* [PATCH 1/2] gitweb: add '/' to the end of filename in page title for trees
From: Jakub Narebski @ 2006-06-20 6:17 UTC (permalink / raw)
To: git; +Cc: Jakub Narebski
In-Reply-To: <11507842053885-git-send-email-jnareb@gmail.com>
---
gitweb/gitweb.cgi | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
d17c119d32ae4c5dd50976ea6a255d2bcbe480ed
diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index 1e1a044..42f3296 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -263,6 +263,9 @@ sub git_header_html {
$title .= "/$action";
if (defined $file_name) {
$title .= " - $file_name";
+ if ($action eq "tree" && $file_name !~ m|/$|) {
+ $title .= "/";
+ }
}
}
}
--
1.3.0
^ permalink raw reply related
* [PATCH 0/2] gitweb: Enhance page title
From: Jakub Narebski @ 2006-06-20 6:17 UTC (permalink / raw)
To: git
This series of patches adds filename (with '/' at the end added for
trees, i.e. directories) to the page title, for easier bookmarking and
viewing browser history.
On top of 'next', but should apply cleanly for 'master' too.
^ permalink raw reply
* [PATCH 1/2] gitweb: Add filename to page title if set
From: Jakub Narebski @ 2006-06-20 6:17 UTC (permalink / raw)
To: git; +Cc: Jakub Narebski
In-Reply-To: <11507842053885-git-send-email-jnareb@gmail.com>
---
gitweb/gitweb.cgi | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
a54751bb328072baed5446bdc4076f1e00002737
diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index 12d5271..1e1a044 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -260,7 +260,10 @@ sub git_header_html {
if (defined $project) {
$title .= " - $project";
if (defined $action) {
+ if (defined $file_name) {
+ $title .= " - $file_name";
+ }
}
}
print $cgi->header(-type=>'text/html', -charset => 'utf-8', -status=> $status, -expires => $expires);
--
1.3.0
^ permalink raw reply related
* Re: packs and trees
From: Martin Langhoff @ 2006-06-20 6:13 UTC (permalink / raw)
To: Jon Smirl; +Cc: git
In-Reply-To: <9e4733910606192257y1516e966t848a3b1e29e5667f@mail.gmail.com>
On 6/20/06, Jon Smirl <jonsmirl@gmail.com> wrote:
> The plan is to modify rcs2git from parsecvs to create all of the git
> objects for the tree.
Sounds like a good plan. Have you seen recent discussions about it
being impossible to repack usefully when you don't have trees (and
resulting performance problems on ext3).
> cvs2svn seems to do a good job at generating the trees.
No doubt. Gut the last stage, and use all the data in the intermediate
DBs to run a git import. It's a great plan, and if you can understand
that Python code... all yours ;-)
> exactly sure how the changeset detection algorithms in the three apps
> compare, but cvs2svn is not having any trouble building changesets for
> Mozilla. The other two apps have some issues, cvsps throws away some
> of the branches and parsecvs can't complete the analysis.
Have you tried a recent parsecvs from Keith's tree? There's been quite
a bit of activity there too. And Keith's interested in sorting out
incremental imports too, which you need for a reasonable Moz
transition plan as well.
cheers,
martin
^ permalink raw reply
* packs and trees
From: Jon Smirl @ 2006-06-20 5:57 UTC (permalink / raw)
To: git
Converting from CVS would be a lot more efficient if all of revisions
contained in a CVS file were written into git at the same time. So, if
I extract complete revisions from 100 source files into git objects
and then ask git to incremental pack, will git find all of the deltas
and do a good job packing? Some of these files have thousands (50MB)
of deltas. Also, note that I have not written any tree info into git
yet.
After all of the revisions are into git, I will follow up with the
tree info and then repack all. How will the pack end up grouped,
chronologically or will it still be sorted by file? It is not clear to
me how the tree info interacts with the magic packing sauce.
The plan is to modify rcs2git from parsecvs to create all of the git
objects for the tree. It would be called by the cvs2svn code which
would track the object IDs through the changeset generation process.
At the end it will write all of the trees connecting the objects
together.
cvs2svn seems to do a good job at generating the trees. I am not
exactly sure how the changeset detection algorithms in the three apps
compare, but cvs2svn is not having any trouble building changesets for
Mozilla. The other two apps have some issues, cvsps throws away some
of the branches and parsecvs can't complete the analysis.
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* Re: [PATCH (fixed)] git-svn: fix --rmdir when using SVN:: libraries
From: Eric Wong @ 2006-06-20 5:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vbqso7him.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> wrote:
> Eric Wong <normalperson@yhbt.net> writes:
>
> > Makefile: automatically run new tests as they appear in t/
> >
> > Signed-off-by: Eric Wong <normalperson@yhbt.net>
> > ---
> >
> > Oops, I left out the Makefile change in the other patch,...
>
> Yeah, I was wondering about that.
>
> > ... had the new
> > test file as +x
>
> Shouldn't they be executable? It is not a big deal, because you
> run them via $(SHELL), though...
Yes, I prefer to use $(SHELL) instead. Makes it easier to test with
different shells without mucking /bin/sh
--
Eric Wong
^ permalink raw reply
* [PATCH] gitweb: add type="text/css" to stylesheet link
From: Jakub Narebski @ 2006-06-20 4:11 UTC (permalink / raw)
To: git; +Cc: Jakub Narebski
---
gitweb/gitweb.cgi | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
75b6977d185f946fcab8b86011f37869948c1dac
diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index fa90c51..c582424 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -39,7 +39,7 @@ # html text to include at home page
my $home_text = "indextext.html";
# URI of default stylesheet
-my $stylesheet = "gitweb.css";
+my $stylesheet = "gitweb.css";
# source of projects list
#my $projects_list = $projectroot;
@@ -272,7 +272,7 @@ sub git_header_html {
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<meta name="robots" content="index, nofollow"/>
-<link rel="stylesheet" href="$stylesheet"/>
+<link rel="stylesheet" type="text/css" href="$stylesheet"/>
<title>$title</title>
$rss_link
</head>
--
1.3.0
^ permalink raw reply related
* [PATCH] Make CSS file gitweb/gitweb.css more readable
From: Jakub Narebski @ 2006-06-20 3:48 UTC (permalink / raw)
To: git; +Cc: Jakub Narebski
In-Reply-To: <7vwtbc9a45.fsf@assigned-by-dhcp.cox.net>
---
gitweb/gitweb.css | 273 +++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 223 insertions(+), 50 deletions(-)
72888c0a080d95117d54dc9578dc2a0de7b19abd
diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 5900916..9d91426 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -1,58 +1,231 @@
body {
- font-family: sans-serif; font-size: 12px; border:solid #d9d8d1; border-width:1px;
- margin:10px; background-color:#ffffff; color:#000000;
-}
-a { color:#0000cc; }
-a:hover, a:visited, a:active { color:#880000; }
-div.page_header { height:25px; padding:8px; font-size:18px; font-weight:bold; background-color:#d9d8d1; }
-div.page_header a:visited, a.header { color:#0000cc; }
-div.page_header a:hover { color:#880000; }
-div.page_nav { padding:8px; }
-div.page_nav a:visited { color:#0000cc; }
-div.page_path { padding:8px; border:solid #d9d8d1; border-width:0px 0px 1px}
-div.page_footer { height:17px; padding:4px 8px; background-color: #d9d8d1; }
-div.page_footer_text { float:left; color:#555555; font-style:italic; }
-div.page_body { padding:8px; }
+ font-family: sans-serif;
+ font-size: 12px;
+ border:solid #d9d8d1;
+ border-width: 1px;
+ margin: 10px;
+ background-color: #ffffff;
+ color: #000000;
+}
+
+a {
+ color: #0000cc;
+}
+
+a:hover, a:visited, a:active {
+ color: #880000;
+}
+
+div.page_header {
+ height: 25px;
+ padding: 8px;
+ font-size: 18px;
+ font-weight: bold;
+ background-color: #d9d8d1;
+}
+
+div.page_header a:visited, a.header {
+ color: #0000cc;
+}
+
+div.page_header a:hover {
+ color: #880000;
+}
+
+div.page_nav {
+ padding:8px;
+}
+
+div.page_nav a:visited {
+ color: #0000cc;
+}
+
+div.page_path {
+ padding: 8px;
+ border: solid #d9d8d1;
+ border-width: 0px 0px 1px;
+}
+
+div.page_footer {
+ height: 17px;
+ padding: 4px 8px;
+ background-color: #d9d8d1;
+}
+
+div.page_footer_text {
+ float: left;
+ color: #555555;
+ font-style: italic;
+}
+
+div.page_body {
+ padding: 8px;
+}
+
div.title, a.title {
- display:block; padding:6px 8px;
- font-weight:bold; background-color:#edece6; text-decoration:none; color:#000000;
+ display: block;
+ padding: 6px 8px;
+ font-weight: bold;
+ background-color: #edece6;
+ text-decoration: none;
+ color: #000000;
+}
+
+a.title:hover {
+ background-color: #d9d8d1;
+}
+
+div.title_text {
+ padding: 6px 0px;
+ border: solid #d9d8d1;
+ border-width: 0px 0px 1px;
}
-a.title:hover { background-color: #d9d8d1; }
-div.title_text { padding:6px 0px; border: solid #d9d8d1; border-width:0px 0px 1px; }
-div.log_body { padding:8px 8px 8px 150px; }
-span.age { position:relative; float:left; width:142px; font-style:italic; }
+
+div.log_body {
+ padding: 8px 8px 8px 150px;
+}
+
+span.age {
+ position: relative;
+ float: left;
+ width: 142px;
+ font-style:italic;
+}
+
div.log_link {
- padding:0px 8px;
- font-size:10px; font-family:sans-serif; font-style:normal;
- position:relative; float:left; width:136px;
-}
-div.list_head { padding:6px 8px 4px; border:solid #d9d8d1; border-width:1px 0px 0px; font-style:italic; }
-a.list { text-decoration:none; color:#000000; }
-a.list:hover { text-decoration:underline; color:#880000; }
-a.text { text-decoration:none; color:#0000cc; }
-a.text:visited { text-decoration:none; color:#880000; }
-a.text:hover { text-decoration:underline; color:#880000; }
-table { padding:8px 4px; }
-th { padding:2px 5px; font-size:12px; text-align:left; }
-tr.light:hover { background-color:#edece6; }
-tr.dark { background-color:#f6f6f0; }
-tr.dark:hover { background-color:#edece6; }
-td { padding:2px 5px; font-size:12px; vertical-align:top; }
-td.link { padding:2px 5px; font-family:sans-serif; font-size:10px; }
-div.pre { font-family:monospace; font-size:12px; white-space:pre; }
-div.diff_info { font-family:monospace; color:#000099; background-color:#edece6; font-style:italic; }
-div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; padding:12px 8px; }
-div.search { margin:4px 8px; position:absolute; top:56px; right:12px }
-a.linenr { color:#999999; text-decoration:none }
+ padding: 0px 8px;
+ font-size: 10px;
+ font-family: sans-serif;
+ font-style:normal;
+ position: relative;
+ float: left;
+ width: 136px;
+}
+
+div.list_head {
+ padding: 6px 8px 4px;
+ border: solid #d9d8d1;
+ border-width: 1px 0px 0px;
+ font-style: italic;
+}
+
+a.list {
+ text-decoration: none;
+ color: #000000;
+}
+
+a.list:hover {
+ text-decoration: underline;
+ color: #880000;
+}
+
+a.text {
+ text-decoration: none;
+ color: #0000cc;
+}
+
+a.text:visited {
+ text-decoration: none;
+ color: #880000;
+}
+
+a.text:hover {
+ text-decoration: underline;
+ color: #880000;
+}
+
+table {
+ padding: 8px 4px;
+}
+
+th {
+ padding: 2px 5px;
+ font-size: 12px;
+ text-align: left;
+}
+
+tr.light:hover {
+ background-color: #edece6;
+}
+
+tr.dark {
+ background-color: #f6f6f0;
+}
+
+tr.dark:hover {
+ background-color: #edece6;
+}
+
+
+td {
+ padding: 2px 5px;
+ font-size: 12px;
+ vertical-align:top;
+}
+
+td.link {
+ padding: 2px 5px;
+ font-family: sans-serif;
+ font-size: 10px;
+}
+
+div.pre {
+ font-family: monospace;
+ font-size: 12px;
+ white-space: pre;
+ /* padding-left: 5px; */
+}
+
+div.diff_info {
+ font-family: monospace;
+ color: #000099;
+ background-color: #edece6;
+ font-style: italic;
+}
+
+div.index_include {
+ border: solid #d9d8d1;
+ border-width: 0px 0px 1px;
+ padding: 12px 8px;
+}
+
+div.search {
+ margin: 4px 8px;
+ position: absolute;
+ top: 56px;
+ right: 12px
+}
+
+a.linenr {
+ color: #999999;
+ text-decoration: none
+}
+
a.rss_logo {
- float:right; padding:3px 0px; width:35px; line-height:10px;
- border:1px solid; border-color:#fcc7a5 #7d3302 #3e1a01 #ff954e;
- color:#ffffff; background-color:#ff6600;
- font-weight:bold; font-family:sans-serif; font-size:10px;
- text-align:center; text-decoration:none;
+ float: right;
+ padding: 3px 0px;
+ width: 35px;
+ line-height: 10px;
+ border: 1px solid;
+ border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e;
+ color: #ffffff;
+ background-color: #ff6600;
+ font-weight: bold;
+ font-family: sans-serif;
+ font-size: 10px;
+ text-align: center;
+ text-decoration: none;
+}
+
+a.rss_logo:hover {
+ background-color: #ee5500;
}
-a.rss_logo:hover { background-color:#ee5500; }
+
span.tag {
- padding:0px 4px; font-size:10px; font-weight:normal;
- background-color:#ffffaa; border:1px solid; border-color:#ffffcc #ffee00 #ffee00 #ffffcc;
+ padding: 0px 4px;
+ font-size: 10px;
+ font-weight: normal;
+ background-color: #ffffaa;
+ border: 1px solid;
+ border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
}
--
1.3.0
^ permalink raw reply related
* Re: [PATCH] Make CSS file gitweb/gitweb.css more readable
From: Jakub Narebski @ 2006-06-20 3:32 UTC (permalink / raw)
To: git
In-Reply-To: <e77prc$v40$1@sea.gmane.org>
Jakub Narebski wrote:
> Junio C Hamano wrote:
>
>> Jakub, I've been applying your patches after hand-fixing but it
>> appears that there is serious whitespace breakage on the mail
>> path somewhere between you and the mailing list. Please check
>> your MUA.
>
> Checking:
It looks like KNode/0.7.7 (from KDE 3.2.2) converts tabs to spaces
even for inserted files.
I'll use email client (KMail or git-send-email) in the future.
I'll be resending the patch as part of larger series in near future.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: [PATCH] Make CSS file gitweb/gitweb.css more readable
From: Jakub Narebski @ 2006-06-20 3:25 UTC (permalink / raw)
To: git
In-Reply-To: <7vwtbc9a45.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano wrote:
> Jakub, I've been applying your patches after hand-fixing but it
> appears that there is serious whitespace breakage on the mail
> path somewhere between you and the mailing list. Please check
> your MUA.
Checking:
--inserted file--
test
tab test
tab+space test
space test
empty line below
line with tab only below
--
Signature
--end of inserted file--
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: 2.6.17-rc6-mm2
From: Linus Torvalds @ 2006-06-20 3:22 UTC (permalink / raw)
To: Michal Ludvig; +Cc: Goo GGooo, git, Junio C Hamano
In-Reply-To: <44976506.8040205@logix.cz>
On Tue, 20 Jun 2006, Michal Ludvig wrote:
>
> OpenBSD has CVS access to their repos over SSH even for anonymous users.
> Could something similar be set up on git.kernel.org as well?
I suspect the kernel.org people would prefer not to. And I'm almost
certain that others don't want to. It would really be much better if the
git protocol itself just had a sideband channel. Oh, well.
Linus
^ permalink raw reply
* [PATCH] Restore SIGCHLD to SIG_DFL where we care about waitpid().
From: Junio C Hamano @ 2006-06-20 3:11 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0606191742470.5498@g5.osdl.org>
It was reported that under one implementation of socks client,
"git clone" fails with "error: waitpid failed (No child
processes)", because "git" is spawned after setting SIGCHLD to
SIG_IGN.
Arguably it may be a broken setting, but we should protect
ourselves so that we can get reliable results from waitpid() for
the children we care about.
This patch resets SIGCHLD to SIG_DFL in three places:
- connect.c::git_connect() - initiators of git native
protocol transfer are covered with this.
- daemon.c::main() - obviously.
- merge-index.c::main() - obviously.
There are other programs that do fork() but do not waitpid():
http-push, imap-send. upload-pack does not either, but in the
case of that program, each of the forked halves runs exec()
another program, so this change would not have much effect
there.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Linus Torvalds <torvalds@osdl.org> writes:
> On Mon, 19 Jun 2006, Junio C Hamano wrote:
>
>> I do not offhand think of a place where we do fork() but not
>> waitpid(), and it is very tempting to cheat and do that in the
>> main(), since I do not see a downside to it.
>
> Yeah, it probably does make sense. That said, there are several "main()"
> functions, so you'd still end up having to verify that we catch all the
> paths.. Are all users of fork() built-in by now?
Not really. But git native protocol initiators all use
git_connect() so they are easy, and there are only few
remaining ones that matter.
connect.c | 5 +++++
daemon.c | 5 +++++
merge-index.c | 5 +++++
3 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/connect.c b/connect.c
index 52d709e..db7342e 100644
--- a/connect.c
+++ b/connect.c
@@ -581,6 +581,11 @@ int git_connect(int fd[2], char *url, co
enum protocol protocol = PROTO_LOCAL;
int free_path = 0;
+ /* Without this we cannot rely on waitpid() to tell
+ * what happened to our children.
+ */
+ signal(SIGCHLD, SIG_DFL);
+
host = strstr(url, "://");
if(host) {
*host = '\0';
diff --git a/daemon.c b/daemon.c
index 2f03f99..1067004 100644
--- a/daemon.c
+++ b/daemon.c
@@ -671,6 +671,11 @@ int main(int argc, char **argv)
int inetd_mode = 0;
int i;
+ /* Without this we cannot rely on waitpid() to tell
+ * what happened to our children.
+ */
+ signal(SIGCHLD, SIG_DFL);
+
for (i = 1; i < argc; i++) {
char *arg = argv[i];
diff --git a/merge-index.c b/merge-index.c
index 024196e..190e12f 100644
--- a/merge-index.c
+++ b/merge-index.c
@@ -99,6 +99,11 @@ int main(int argc, char **argv)
{
int i, force_file = 0;
+ /* Without this we cannot rely on waitpid() to tell
+ * what happened to our children.
+ */
+ signal(SIGCHLD, SIG_DFL);
+
if (argc < 3)
usage("git-merge-index [-o] [-q] <merge-program> (-a | <filename>*)");
--
1.4.0.g275f
^ permalink raw reply related
* Re: 2.6.17-rc6-mm2
From: Michal Ludvig @ 2006-06-20 3:01 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Goo GGooo, git, Junio C Hamano
In-Reply-To: <Pine.LNX.4.64.0606152335130.5498@g5.osdl.org>
[-- Attachment #1: Type: text/plain, Size: 1008 bytes --]
Linus Torvalds wrote:
>
> On Fri, 16 Jun 2006, Goo GGooo wrote:
>
>> I suggest adding SO_KEEPALIVE option on the git socket.
>
> Actually, the really irritating thing is that we actually generate all
> these nice status updates, which just makes pulling and cloning a lot more
> comfortable, because you actually see what is going on, and what to
> expect.
>
> Except they only work over ssh, where we have a separate channel (for
> stderr), and with the native git protocol all that nice status work just
> gets flushed to /dev/null :(
OpenBSD has CVS access to their repos over SSH even for anonymous users.
Could something similar be set up on git.kernel.org as well?
> And in your case, the usability downside actually turned into a real
> accessibility bug.
Same issue here. Thanks for the hint. Attached is a patch against git
1.4.0 that solves it perfectly in my case.
Sysctl settings (for keepalive every 10 sec):
net.ipv4.tcp_keepalive_intvl=10
net.ipv4.tcp_keepalive_time=10
Michal
[-- Attachment #2: keepalive.diff --]
[-- Type: text/x-patch, Size: 1375 bytes --]
Set SO_KEEPALIVE option on native git:// sockets.
Signed-off-by: Michal Ludvig <michal@logix.cz>
Index: git-1.4.0/connect.c
===================================================================
--- git-1.4.0.orig/connect.c
+++ git-1.4.0/connect.c
@@ -331,7 +331,7 @@ static int git_tcp_connect_sock(char *ho
char *colon, *end;
char *port = STR(DEFAULT_GIT_PORT);
struct addrinfo hints, *ai0, *ai;
- int gai;
+ int gai, option;
if (host[0] == '[') {
end = strchr(host + 1, ']');
@@ -363,6 +363,10 @@ static int git_tcp_connect_sock(char *ho
ai->ai_socktype, ai->ai_protocol);
if (sockfd < 0)
continue;
+
+ option = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof(option));
+
if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
close(sockfd);
sockfd = -1;
@@ -392,7 +396,7 @@ static int git_tcp_connect_sock(char *ho
struct hostent *he;
struct sockaddr_in sa;
char **ap;
- unsigned int nport;
+ unsigned int nport, option;
if (host[0] == '[') {
end = strchr(host + 1, ']');
@@ -433,6 +437,9 @@ static int git_tcp_connect_sock(char *ho
sa.sin_port = htons(nport);
memcpy(&sa.sin_addr, *ap, he->h_length);
+ option = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof(option));
+
if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
close(sockfd);
sockfd = -1;
^ permalink raw reply
* Re: [PATCH] Fix git to be (more) ANSI C99 compliant.
From: Junio C Hamano @ 2006-06-20 1:59 UTC (permalink / raw)
To: Florian Forster; +Cc: git, Linus Torvalds, Rene Scharfe
In-Reply-To: <20060619212116.GL1331@verplant.org>
Florian Forster <octo@verplant.org> writes:
> I didn't start writing the patch because I like C99 so much. In fact, in
> my opinion it introduces some possibilities I'd rather not have in C
> because people might actually use them. But by default the Sun cc
> complains about void-pointer arithmetic...
I am reasonably sympathetic to that, and judging from the number
of lines the patch touches, I am not as strongly opposed to it
as Linus seems to be.
> Maybe Rene Scharfe's method (as used in the patch to git-tar-tree) is a
> good way around it? There are no explicit casts involved and standard-
> compliant compilers like it, too. The downside is that you have two
> variables for the same thing/memory.
I think Rene's patch makes sense primarily because the functions
affected are small and we can easily see that the aliased input
variable ("data") is not used -- IOW, there is no confusion.
If it were a big function and the code used one variable for
some purpose and the other one for another purpose, it would be
far worse than having to cast the same variable occasionally.
BTW, I think we would probably want to have this patch on top of
Rene's patch. In all instances, the variable "buf" is of type
"const char *" and the existing casts do not make sense to me.
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index 5c8a5f0..39a61b6 100644
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
@@ -36,7 +36,7 @@ static void reliable_write(const void *d
die("git-tar-tree: disk full?");
}
size -= ret;
- buf = (char *) buf + ret;
+ buf += ret;
}
}
@@ -65,13 +65,13 @@ static void write_blocked(const void *da
memcpy(block + offset, buf, chunk);
size -= chunk;
offset += chunk;
- buf = (char *) buf + chunk;
+ buf += chunk;
write_if_needed();
}
while (size >= BLOCKSIZE) {
reliable_write(buf, BLOCKSIZE);
size -= BLOCKSIZE;
- buf = (char *) buf + BLOCKSIZE;
+ buf += BLOCKSIZE;
}
if (size) {
memcpy(block + offset, buf, size);
^ permalink raw reply related
* Re: [PATCH (fixed)] git-svn: fix --rmdir when using SVN:: libraries
From: Junio C Hamano @ 2006-06-20 1:17 UTC (permalink / raw)
To: Eric Wong; +Cc: git
In-Reply-To: <11507651751452-git-send-email-normalperson@yhbt.net>
Eric Wong <normalperson@yhbt.net> writes:
> Makefile: automatically run new tests as they appear in t/
>
> Signed-off-by: Eric Wong <normalperson@yhbt.net>
> ---
>
> Oops, I left out the Makefile change in the other patch,...
Yeah, I was wondering about that.
> ... had the new
> test file as +x
Shouldn't they be executable? It is not a big deal, because you
run them via $(SHELL), though...
^ permalink raw reply
* [PATCH (fixed)] git-svn: fix --rmdir when using SVN:: libraries
From: Eric Wong @ 2006-06-20 0:59 UTC (permalink / raw)
To: git, Junio C Hamano; +Cc: Eric Wong
In-Reply-To: <11507645052855-git-send-email-normalperson@yhbt.net>
When tracking directories with nearly all of its files at
the most nested levels, --rmdir would accidentally go too
far when deleting.
Of course, we'll add a test for this condition, too.
Makefile: automatically run new tests as they appear in t/
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
Oops, I left out the Makefile change in the other patch, had the new
test file as +x
contrib/git-svn/Makefile | 3 +--
contrib/git-svn/git-svn.perl | 15 +++++++++++----
contrib/git-svn/t/t0002-deep-rmdir.sh | 29 +++++++++++++++++++++++++++++
3 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/contrib/git-svn/Makefile b/contrib/git-svn/Makefile
index 6aedb10..7c20946 100644
--- a/contrib/git-svn/Makefile
+++ b/contrib/git-svn/Makefile
@@ -29,8 +29,7 @@ git-svn.html : git-svn.txt
asciidoc -b xhtml11 -d manpage \
-f ../../Documentation/asciidoc.conf $<
test: git-svn
- cd t && $(SHELL) ./t0000-contrib-git-svn.sh $(TEST_FLAGS)
- cd t && $(SHELL) ./t0001-contrib-git-svn-props.sh $(TEST_FLAGS)
+ cd t && for i in t????-*.sh; do $(SHELL) ./$$i $(TEST_FLAGS); done
# we can test NO_OPTIMIZE_COMMITS independently of LC_ALL
full-test:
diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index da0ff9a..7e7f2f0 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -2841,13 +2841,20 @@ sub rmdirs {
exec qw/git-ls-tree --name-only -r -z/, $self->{c} or croak $!;
}
local $/ = "\0";
+ my @svn_path = split m#/#, $self->{svn_path};
while (<$fh>) {
chomp;
- $_ = $self->{svn_path} . '/' . $_;
- my ($dn) = ($_ =~ m#^(.*?)/?(?:[^/]+)$#);
- delete $rm->{$dn};
- last unless %$rm;
+ my @dn = (@svn_path, (split m#/#, $_));
+ while (pop @dn) {
+ delete $rm->{join '/', @dn};
+ }
+ unless (%$rm) {
+ close $fh;
+ return;
+ }
}
+ close $fh;
+
my ($r, $p, $bat) = ($self->{r}, $self->{pool}, $self->{bat});
foreach my $d (sort { $b =~ tr#/#/# <=> $a =~ tr#/#/# } keys %$rm) {
$self->close_directory($bat->{$d}, $p);
diff --git a/contrib/git-svn/t/t0002-deep-rmdir.sh b/contrib/git-svn/t/t0002-deep-rmdir.sh
new file mode 100644
index 0000000..d693d18
--- /dev/null
+++ b/contrib/git-svn/t/t0002-deep-rmdir.sh
@@ -0,0 +1,29 @@
+test_description='git-svn rmdir'
+. ./lib-git-svn.sh
+
+test_expect_success 'initialize repo' "
+ mkdir import &&
+ cd import &&
+ mkdir -p deeply/nested/directory/number/1 &&
+ mkdir -p deeply/nested/directory/number/2 &&
+ echo foo > deeply/nested/directory/number/1/file &&
+ echo foo > deeply/nested/directory/number/2/another &&
+ svn import -m 'import for git-svn' . $svnrepo &&
+ cd ..
+ "
+
+test_expect_success 'mirror via git-svn' "
+ git-svn init $svnrepo &&
+ git-svn fetch &&
+ git checkout -f -b test-rmdir remotes/git-svn
+ "
+
+test_expect_success 'Try a commit on rmdir' "
+ git rm -f deeply/nested/directory/number/2/another &&
+ git commit -a -m 'remove another' &&
+ git-svn commit --rmdir HEAD &&
+ svn ls -R $svnrepo | grep ^deeply/nested/directory/number/1
+ "
+
+
+test_done
--
1.4.GIT
^ permalink raw reply related
* [PATCH] git-svn: fix --rmdir when using SVN:: libraries
From: Eric Wong @ 2006-06-20 0:48 UTC (permalink / raw)
To: git, Junio C Hamano; +Cc: Eric Wong
In-Reply-To: <11507645052855-git-send-email-normalperson@yhbt.net>
When tracking directories with nearly all of its files at
the most nested levels, --rmdir would accidentally go too
far when deleting.
Of course, we'll add a test for this condition, too.
Makefile: automatically run new tests as they appear in t/
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
contrib/git-svn/git-svn.perl | 15 +++++++++++----
contrib/git-svn/t/t0002-deep-rmdir.sh | 29 +++++++++++++++++++++++++++++
2 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index da0ff9a..7e7f2f0 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -2841,13 +2841,20 @@ sub rmdirs {
exec qw/git-ls-tree --name-only -r -z/, $self->{c} or croak $!;
}
local $/ = "\0";
+ my @svn_path = split m#/#, $self->{svn_path};
while (<$fh>) {
chomp;
- $_ = $self->{svn_path} . '/' . $_;
- my ($dn) = ($_ =~ m#^(.*?)/?(?:[^/]+)$#);
- delete $rm->{$dn};
- last unless %$rm;
+ my @dn = (@svn_path, (split m#/#, $_));
+ while (pop @dn) {
+ delete $rm->{join '/', @dn};
+ }
+ unless (%$rm) {
+ close $fh;
+ return;
+ }
}
+ close $fh;
+
my ($r, $p, $bat) = ($self->{r}, $self->{pool}, $self->{bat});
foreach my $d (sort { $b =~ tr#/#/# <=> $a =~ tr#/#/# } keys %$rm) {
$self->close_directory($bat->{$d}, $p);
diff --git a/contrib/git-svn/t/t0002-deep-rmdir.sh b/contrib/git-svn/t/t0002-deep-rmdir.sh
new file mode 100755
index 0000000..d693d18
--- /dev/null
+++ b/contrib/git-svn/t/t0002-deep-rmdir.sh
@@ -0,0 +1,29 @@
+test_description='git-svn rmdir'
+. ./lib-git-svn.sh
+
+test_expect_success 'initialize repo' "
+ mkdir import &&
+ cd import &&
+ mkdir -p deeply/nested/directory/number/1 &&
+ mkdir -p deeply/nested/directory/number/2 &&
+ echo foo > deeply/nested/directory/number/1/file &&
+ echo foo > deeply/nested/directory/number/2/another &&
+ svn import -m 'import for git-svn' . $svnrepo &&
+ cd ..
+ "
+
+test_expect_success 'mirror via git-svn' "
+ git-svn init $svnrepo &&
+ git-svn fetch &&
+ git checkout -f -b test-rmdir remotes/git-svn
+ "
+
+test_expect_success 'Try a commit on rmdir' "
+ git rm -f deeply/nested/directory/number/2/another &&
+ git commit -a -m 'remove another' &&
+ git-svn commit --rmdir HEAD &&
+ svn ls -R $svnrepo | grep ^deeply/nested/directory/number/1
+ "
+
+
+test_done
--
1.4.GIT
^ permalink raw reply related
* Re: git-svn: don't use the --rmdir feature with SVN libs
From: Eric Wong @ 2006-06-20 0:48 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <20060619233424.GD3929@localdomain>
Fortunately, the fix is pretty simple. But yes, this is the
scariest bug in git-svn that's ever happened :x
^ permalink raw reply
* Re: [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)?
From: Linus Torvalds @ 2006-06-20 0:44 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vfyi07jf2.fsf@assigned-by-dhcp.cox.net>
On Mon, 19 Jun 2006, Junio C Hamano wrote:
>
> Linus Torvalds <torvalds@osdl.org> writes:
>
> > Whether we want to do that in the main() routine or when we actually do
> > the fork() or whatever is a different issue.
>
> I do not offhand think of a place where we do fork() but not
> waitpid(), and it is very tempting to cheat and do that in the
> main(), since I do not see a downside to it.
Yeah, it probably does make sense. That said, there are several "main()"
functions, so you'd still end up having to verify that we catch all the
paths.. Are all users of fork() built-in by now?
Linus
^ permalink raw reply
* Add "named object array" concept
From: Linus Torvalds @ 2006-06-20 0:42 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
We've had this notion of a "object_list" for a long time, which eventually
grew a "name" member because some users (notably git-rev-list) wanted to
name each object as it is generated.
That object_list is great for some things, but it isn't all that wonderful
for others, and the "name" member is generally not used by everybody.
This patch splits the users of the object_list array up into two: the
traditional list users, who want the list-like format, and who don't
actually use or want the name. And another class of users that really used
the list as an extensible array, and generally wanted to name the objects.
The patch is fairly straightforward, but it's also biggish. Most of it
really just cleans things up: switching the revision parsing and listing
over to the array makes things like the builtin-diff usage much simpler
(we now see exactly how many members the array has, and we don't get the
objects reversed from the order they were on the command line).
One of the main reasons for doing this at all is that the malloc overhead
of the simple object list was actually pretty high, and the array is just
a lot denser. So this patch brings down memory usage by git-rev-list by
just under 3% (on top of all the other memory use optimizations) on the
mozilla archive.
It does add more lines than it removes, and more importantly, it adds a
whole new infrastructure for maintaining lists of objects, but on the
other hand, the new dynamic array code is pretty obvious. The change to
builtin-diff-tree.c shows a fairly good example of why an array interface
is sometimes more natural, and just much simpler for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
Btw, somebody should really check my http-push conversion.
It actually used to set up the whole "name" thing, and it still has the
code for it, but there really is no point to it, and as far as I can tell,
it never _used_ it. It just had it because the code was copied from
git-rev-list, I suspect.
So there's room for further simplification there, but I wanted to leave
that part as a minimal patch, just because I don't use it, and while I'm
pretty damn sure that the "name" part was never actually used (the fact
that it compiles fine without any "name" in the object list at all is a
big hint ;), it should get somebody else looking over my diff. And
simplifying the code later.
builtin-diff-files.c | 2 +-
builtin-diff-index.c | 2 +-
builtin-diff-tree.c | 42 +++++++++------------------------
builtin-diff.c | 26 +++++++++++---------
builtin-grep.c | 16 +++++--------
builtin-log.c | 4 ++-
builtin-rev-list.c | 64 ++++++++++++++++++++++++++------------------------
diff-lib.c | 4 ++-
http-push.c | 28 +++++++++++++++-------
name-rev.c | 17 +++++++------
object.c | 17 +++++++++++++
object.h | 13 +++++++++-
revision.c | 33 ++++++++++++--------------
revision.h | 12 +++++----
14 files changed, 150 insertions(+), 130 deletions(-)
diff --git a/builtin-diff-files.c b/builtin-diff-files.c
index cebda82..5afc1d7 100644
--- a/builtin-diff-files.c
+++ b/builtin-diff-files.c
@@ -41,7 +41,7 @@ int cmd_diff_files(int argc, const char
* rev.max_count is reasonable (0 <= n <= 3),
* there is no other revision filtering parameters.
*/
- if (rev.pending_objects ||
+ if (rev.pending.nr ||
rev.min_age != -1 || rev.max_age != -1)
usage(diff_files_usage);
/*
diff --git a/builtin-diff-index.c b/builtin-diff-index.c
index 1958580..c42ef9a 100644
--- a/builtin-diff-index.c
+++ b/builtin-diff-index.c
@@ -32,7 +32,7 @@ int cmd_diff_index(int argc, const char
* Make sure there is one revision (i.e. pending object),
* and there is no revision filtering parameters.
*/
- if (!rev.pending_objects || rev.pending_objects->next ||
+ if (rev.pending.nr != 1 ||
rev.max_count != -1 || rev.min_age != -1 || rev.max_age != -1)
usage(diff_cache_usage);
return run_diff_index(&rev, cached);
diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c
index 58cf658..3409a39 100644
--- a/builtin-diff-tree.c
+++ b/builtin-diff-tree.c
@@ -65,7 +65,6 @@ int cmd_diff_tree(int argc, const char *
char line[1000];
struct object *tree1, *tree2;
static struct rev_info *opt = &log_tree_opt;
- struct object_list *list;
int read_stdin = 0;
git_config(git_diff_config);
@@ -86,45 +85,28 @@ int cmd_diff_tree(int argc, const char *
}
/*
- * NOTE! "setup_revisions()" will have inserted the revisions
- * it parsed in reverse order. So if you do
- *
- * git-diff-tree a b
- *
- * the commit list will be "b" -> "a" -> NULL, so we reverse
- * the order of the objects if the first one is not marked
- * UNINTERESTING.
+ * NOTE! We expect "a ^b" to be equal to "a..b", so we
+ * reverse the order of the objects if the second one
+ * is marked UNINTERESTING.
*/
- nr_sha1 = 0;
- list = opt->pending_objects;
- if (list) {
- nr_sha1++;
- tree1 = list->item;
- list = list->next;
- if (list) {
- nr_sha1++;
- tree2 = tree1;
- tree1 = list->item;
- if (list->next)
- usage(diff_tree_usage);
- /* Switch them around if the second one was uninteresting.. */
- if (tree2->flags & UNINTERESTING) {
- struct object *tmp = tree2;
- tree2 = tree1;
- tree1 = tmp;
- }
- }
- }
-
+ nr_sha1 = opt->pending.nr;
switch (nr_sha1) {
case 0:
if (!read_stdin)
usage(diff_tree_usage);
break;
case 1:
+ tree1 = opt->pending.objects[0].item;
diff_tree_commit_sha1(tree1->sha1);
break;
case 2:
+ tree1 = opt->pending.objects[0].item;
+ tree2 = opt->pending.objects[1].item;
+ if (tree2->flags & UNINTERESTING) {
+ struct object *tmp = tree2;
+ tree2 = tree1;
+ tree1 = tmp;
+ }
diff_tree_sha1(tree1->sha1,
tree2->sha1,
"", &opt->diffopt);
diff --git a/builtin-diff.c b/builtin-diff.c
index 6ac3d4b..99a2f76 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -50,7 +50,7 @@ static int builtin_diff_files(struct rev
* specified rev.max_count is reasonable (0 <= n <= 3), and
* there is no other revision filtering parameter.
*/
- if (revs->pending_objects ||
+ if (revs->pending.nr ||
revs->min_age != -1 ||
revs->max_age != -1 ||
3 < revs->max_count)
@@ -172,7 +172,7 @@ static int builtin_diff_index(struct rev
* Make sure there is one revision (i.e. pending object),
* and there is no revision filtering parameters.
*/
- if (!revs->pending_objects || revs->pending_objects->next ||
+ if (revs->pending.nr != 1 ||
revs->max_count != -1 || revs->min_age != -1 ||
revs->max_age != -1)
usage(builtin_diff_usage);
@@ -181,10 +181,10 @@ static int builtin_diff_index(struct rev
static int builtin_diff_tree(struct rev_info *revs,
int argc, const char **argv,
- struct object_list *ent)
+ struct object_array_entry *ent)
{
const unsigned char *(sha1[2]);
- int swap = 1;
+ int swap = 0;
while (1 < argc) {
const char *arg = argv[1];
if (!strcmp(arg, "--raw"))
@@ -195,10 +195,10 @@ static int builtin_diff_tree(struct rev_
}
/* We saw two trees, ent[0] and ent[1].
- * unless ent[0] is unintesting, they are swapped
+ * if ent[1] is unintesting, they are swapped
*/
- if (ent[0].item->flags & UNINTERESTING)
- swap = 0;
+ if (ent[1].item->flags & UNINTERESTING)
+ swap = 1;
sha1[swap] = ent[0].item->sha1;
sha1[1-swap] = ent[1].item->sha1;
diff_tree_sha1(sha1[0], sha1[1], "", &revs->diffopt);
@@ -208,7 +208,7 @@ static int builtin_diff_tree(struct rev_
static int builtin_diff_combined(struct rev_info *revs,
int argc, const char **argv,
- struct object_list *ent,
+ struct object_array_entry *ent,
int ents)
{
const unsigned char (*parent)[20];
@@ -242,13 +242,14 @@ void add_head(struct rev_info *revs)
obj = parse_object(sha1);
if (!obj)
return;
- add_object(obj, &revs->pending_objects, NULL, "HEAD");
+ add_pending_object(revs, obj, "HEAD");
}
int cmd_diff(int argc, const char **argv, char **envp)
{
+ int i;
struct rev_info rev;
- struct object_list *list, ent[100];
+ struct object_array_entry ent[100];
int ents = 0, blobs = 0, paths = 0;
const char *path = NULL;
struct blobinfo blob[2];
@@ -281,7 +282,7 @@ int cmd_diff(int argc, const char **argv
/* Do we have --cached and not have a pending object, then
* default to HEAD by hand. Eek.
*/
- if (!rev.pending_objects) {
+ if (!rev.pending.nr) {
int i;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
@@ -294,7 +295,8 @@ int cmd_diff(int argc, const char **argv
}
}
- for (list = rev.pending_objects; list; list = list->next) {
+ for (i = 0; i < rev.pending.nr; i++) {
+ struct object_array_entry *list = rev.pending.objects+i;
struct object *obj = list->item;
const char *name = list->name;
int flags = (obj->flags & UNINTERESTING);
diff --git a/builtin-grep.c b/builtin-grep.c
index 9806499..6a240fb 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -657,7 +657,7 @@ int cmd_grep(int argc, const char **argv
int cached = 0;
int seen_dashdash = 0;
struct grep_opt opt;
- struct object_list *list, **tail, *object_list = NULL;
+ struct object_array list = { 0, 0, NULL };
const char *prefix = setup_git_directory();
const char **paths = NULL;
int i;
@@ -677,7 +677,6 @@ int cmd_grep(int argc, const char **argv
* that continues up to the -- (if exists), and then paths.
*/
- tail = &object_list;
while (1 < argc) {
const char *arg = argv[1];
argc--; argv++;
@@ -851,12 +850,9 @@ int cmd_grep(int argc, const char **argv
/* Is it a rev? */
if (!get_sha1(arg, sha1)) {
struct object *object = parse_object(sha1);
- struct object_list *elem;
if (!object)
die("bad object %s", arg);
- elem = object_list_insert(object, tail);
- elem->name = arg;
- tail = &elem->next;
+ add_object_array(object, arg, &list);
continue;
}
if (!strcmp(arg, "--")) {
@@ -881,16 +877,16 @@ int cmd_grep(int argc, const char **argv
paths[1] = NULL;
}
- if (!object_list)
+ if (!list.nr)
return !grep_cache(&opt, paths, cached);
if (cached)
die("both --cached and trees are given.");
- for (list = object_list; list; list = list->next) {
+ for (i = 0; i < list.nr; i++) {
struct object *real_obj;
- real_obj = deref_tag(list->item, NULL, 0);
- if (grep_object(&opt, paths, real_obj, list->name))
+ real_obj = deref_tag(list.objects[i].item, NULL, 0);
+ if (grep_object(&opt, paths, real_obj, list.objects[i].name))
hit = 1;
}
return !hit;
diff --git a/builtin-log.c b/builtin-log.c
index 9187fd3..5a8a50b 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -257,8 +257,8 @@ int cmd_format_patch(int argc, const cha
output_directory);
}
- if (rev.pending_objects && rev.pending_objects->next == NULL) {
- rev.pending_objects->item->flags |= UNINTERESTING;
+ if (rev.pending.nr == 1) {
+ rev.pending.objects[0].item->flags |= UNINTERESTING;
add_head(&rev);
}
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 71353eb..63bad0e 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -99,26 +99,26 @@ static void show_commit(struct commit *c
}
}
-static struct object_list **process_blob(struct blob *blob,
- struct object_list **p,
- struct name_path *path,
- const char *name)
+static void process_blob(struct blob *blob,
+ struct object_array *p,
+ struct name_path *path,
+ const char *name)
{
struct object *obj = &blob->object;
if (!revs.blob_objects)
- return p;
+ return;
if (obj->flags & (UNINTERESTING | SEEN))
- return p;
+ return;
obj->flags |= SEEN;
name = strdup(name);
- return add_object(obj, p, path, name);
+ add_object(obj, p, path, name);
}
-static struct object_list **process_tree(struct tree *tree,
- struct object_list **p,
- struct name_path *path,
- const char *name)
+static void process_tree(struct tree *tree,
+ struct object_array *p,
+ struct name_path *path,
+ const char *name)
{
struct object *obj = &tree->object;
struct tree_desc desc;
@@ -126,14 +126,14 @@ static struct object_list **process_tree
struct name_path me;
if (!revs.tree_objects)
- return p;
+ return;
if (obj->flags & (UNINTERESTING | SEEN))
- return p;
+ return;
if (parse_tree(tree) < 0)
die("bad tree object %s", sha1_to_hex(obj->sha1));
obj->flags |= SEEN;
name = strdup(name);
- p = add_object(obj, p, path, name);
+ add_object(obj, p, path, name);
me.up = path;
me.elem = name;
me.elem_len = strlen(name);
@@ -143,57 +143,59 @@ static struct object_list **process_tree
while (tree_entry(&desc, &entry)) {
if (S_ISDIR(entry.mode))
- p = process_tree(lookup_tree(entry.sha1), p, &me, entry.path);
+ process_tree(lookup_tree(entry.sha1), p, &me, entry.path);
else
- p = process_blob(lookup_blob(entry.sha1), p, &me, entry.path);
+ process_blob(lookup_blob(entry.sha1), p, &me, entry.path);
}
free(tree->buffer);
tree->buffer = NULL;
- return p;
}
static void show_commit_list(struct rev_info *revs)
{
+ int i;
struct commit *commit;
- struct object_list *objects = NULL, **p = &objects, *pending;
+ struct object_array objects = { 0, 0, NULL };
while ((commit = get_revision(revs)) != NULL) {
- p = process_tree(commit->tree, p, NULL, "");
+ process_tree(commit->tree, &objects, NULL, "");
show_commit(commit);
}
- for (pending = revs->pending_objects; pending; pending = pending->next) {
+ for (i = 0; i < revs->pending.nr; i++) {
+ struct object_array_entry *pending = revs->pending.objects + i;
struct object *obj = pending->item;
const char *name = pending->name;
if (obj->flags & (UNINTERESTING | SEEN))
continue;
if (obj->type == TYPE_TAG) {
obj->flags |= SEEN;
- p = add_object(obj, p, NULL, name);
+ add_object_array(obj, name, &objects);
continue;
}
if (obj->type == TYPE_TREE) {
- p = process_tree((struct tree *)obj, p, NULL, name);
+ process_tree((struct tree *)obj, &objects, NULL, name);
continue;
}
if (obj->type == TYPE_BLOB) {
- p = process_blob((struct blob *)obj, p, NULL, name);
+ process_blob((struct blob *)obj, &objects, NULL, name);
continue;
}
die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
}
- while (objects) {
+ for (i = 0; i < objects.nr; i++) {
+ struct object_array_entry *p = objects.objects + i;
+
/* An object with name "foo\n0000000..." can be used to
* confuse downstream git-pack-objects very badly.
*/
- const char *ep = strchr(objects->name, '\n');
+ const char *ep = strchr(p->name, '\n');
if (ep) {
- printf("%s %.*s\n", sha1_to_hex(objects->item->sha1),
- (int) (ep - objects->name),
- objects->name);
+ printf("%s %.*s\n", sha1_to_hex(p->item->sha1),
+ (int) (ep - p->name),
+ p->name);
}
else
- printf("%s %s\n", sha1_to_hex(objects->item->sha1), objects->name);
- objects = objects->next;
+ printf("%s %s\n", sha1_to_hex(p->item->sha1), p->name);
}
}
@@ -348,7 +350,7 @@ int cmd_rev_list(int argc, const char **
if ((!list &&
(!(revs.tag_objects||revs.tree_objects||revs.blob_objects) &&
- !revs.pending_objects)) ||
+ !revs.pending.nr)) ||
revs.diff)
usage(rev_list_usage);
diff --git a/diff-lib.c b/diff-lib.c
index 2183b41..d93cd55 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -329,8 +329,8 @@ int run_diff_index(struct rev_info *revs
}
mark_merge_entries();
- ent = revs->pending_objects->item;
- tree_name = revs->pending_objects->name;
+ ent = revs->pending.objects[0].item;
+ tree_name = revs->pending.objects[0].name;
tree = parse_tree_indirect(ent->sha1);
if (!tree)
return error("bad tree object %s", tree_name);
diff --git a/http-push.c b/http-push.c
index ba64f8f..0f02a55 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1171,7 +1171,7 @@ static void one_remote_object(const char
obj->flags |= REMOTE;
if (!object_list_contains(objects, obj))
- add_object(obj, &objects, NULL, "");
+ object_list_insert(obj, &objects);
}
static void handle_lockprop_ctx(struct xml_ctx *ctx, int tag_closed)
@@ -1699,6 +1699,15 @@ static int locking_available(void)
return lock_flags;
}
+struct object_list **add_one_object(struct object *obj, struct object_list **p)
+{
+ struct object_list *entry = xmalloc(sizeof(struct object_list));
+ entry->item = obj;
+ entry->next = *p;
+ *p = entry;
+ return &entry->next;
+}
+
static struct object_list **process_blob(struct blob *blob,
struct object_list **p,
struct name_path *path,
@@ -1712,8 +1721,7 @@ static struct object_list **process_blob
return p;
obj->flags |= SEEN;
- name = strdup(name);
- return add_object(obj, p, path, name);
+ return add_one_object(obj, p);
}
static struct object_list **process_tree(struct tree *tree,
@@ -1735,7 +1743,7 @@ static struct object_list **process_tree
obj->flags |= SEEN;
name = strdup(name);
- p = add_object(obj, p, NULL, name);
+ p = add_one_object(obj, p);
me.up = path;
me.elem = name;
me.elem_len = strlen(name);
@@ -1756,8 +1764,9 @@ static struct object_list **process_tree
static int get_delta(struct rev_info *revs, struct remote_lock *lock)
{
+ int i;
struct commit *commit;
- struct object_list **p = &objects, *pending;
+ struct object_list **p = &objects;
int count = 0;
while ((commit = get_revision(revs)) != NULL) {
@@ -1767,15 +1776,16 @@ static int get_delta(struct rev_info *re
count += add_send_request(&commit->object, lock);
}
- for (pending = revs->pending_objects; pending; pending = pending->next) {
- struct object *obj = pending->item;
- const char *name = pending->name;
+ for (i = 0; i < revs->pending.nr; i++) {
+ struct object_array_entry *entry = revs->pending.objects + i;
+ struct object *obj = entry->item;
+ const char *name = entry->name;
if (obj->flags & (UNINTERESTING | SEEN))
continue;
if (obj->type == TYPE_TAG) {
obj->flags |= SEEN;
- p = add_object(obj, p, NULL, name);
+ p = add_one_object(obj, p);
continue;
}
if (obj->type == TYPE_TREE) {
diff --git a/name-rev.c b/name-rev.c
index c29b93e..586d842 100644
--- a/name-rev.c
+++ b/name-rev.c
@@ -128,8 +128,7 @@ static const char* get_rev_name(struct o
int main(int argc, char **argv)
{
- struct object_list *revs = NULL;
- struct object_list **walker = &revs;
+ struct object_array revs = { 0, 0, NULL };
int as_is = 0, all = 0, transform_stdin = 0;
setup_git_directory();
@@ -184,9 +183,7 @@ int main(int argc, char **argv)
if (cutoff > commit->date)
cutoff = commit->date;
- object_list_append((struct object *)commit, walker);
- (*walker)->name = *argv;
- walker = &((*walker)->next);
+ add_object_array((struct object *)commit, *argv, &revs);
}
for_each_ref(name_ref);
@@ -243,9 +240,13 @@ #define ishex(x) (isdigit((x)) || ((x) >
if (objs[i])
printf("%s %s\n", sha1_to_hex(objs[i]->sha1),
get_rev_name(objs[i]));
- } else
- for ( ; revs; revs = revs->next)
- printf("%s %s\n", revs->name, get_rev_name(revs->item));
+ } else {
+ int i;
+ for (i = 0; i < revs.nr; i++)
+ printf("%s %s\n",
+ revs.objects[i].name,
+ get_rev_name(revs.objects[i].item));
+ }
return 0;
}
diff --git a/object.c b/object.c
index e26e319..37784ce 100644
--- a/object.c
+++ b/object.c
@@ -200,3 +200,20 @@ int object_list_contains(struct object_l
}
return 0;
}
+
+void add_object_array(struct object *obj, const char *name, struct object_array *array)
+{
+ unsigned nr = array->nr;
+ unsigned alloc = array->alloc;
+ struct object_array_entry *objects = array->objects;
+
+ if (nr >= alloc) {
+ alloc = (alloc + 32) * 2;
+ objects = xrealloc(objects, alloc * sizeof(*objects));
+ array->alloc = alloc;
+ array->objects = objects;
+ }
+ objects[nr].item = obj;
+ objects[nr].name = name;
+ array->nr = ++nr;
+}
diff --git a/object.h b/object.h
index c537b4b..6f23a9a 100644
--- a/object.h
+++ b/object.h
@@ -4,7 +4,6 @@ #define OBJECT_H
struct object_list {
struct object *item;
struct object_list *next;
- const char *name;
};
struct object_refs {
@@ -13,6 +12,15 @@ struct object_refs {
struct object *ref[FLEX_ARRAY]; /* more */
};
+struct object_array {
+ unsigned int nr;
+ unsigned int alloc;
+ struct object_array_entry {
+ struct object *item;
+ const char *name;
+ } *objects;
+};
+
#define TYPE_BITS 3
#define FLAG_BITS 27
@@ -72,4 +80,7 @@ unsigned object_list_length(struct objec
int object_list_contains(struct object_list *list, struct object *obj);
+/* Object array handling .. */
+void add_object_array(struct object *obj, const char *name, struct object_array *array);
+
#endif /* OBJECT_H */
diff --git a/revision.c b/revision.c
index 7bff2a1..b963f2a 100644
--- a/revision.c
+++ b/revision.c
@@ -31,17 +31,12 @@ static char *path_name(struct name_path
return n;
}
-struct object_list **add_object(struct object *obj,
- struct object_list **p,
- struct name_path *path,
- const char *name)
+void add_object(struct object *obj,
+ struct object_array *p,
+ struct name_path *path,
+ const char *name)
{
- struct object_list *entry = xmalloc(sizeof(*entry));
- entry->item = obj;
- entry->next = *p;
- entry->name = path_name(path, name);
- *p = entry;
- return &entry->next;
+ add_object_array(obj, path_name(path, name), p);
}
static void mark_blob_uninteresting(struct blob *blob)
@@ -117,9 +112,9 @@ void mark_parents_uninteresting(struct c
}
}
-static void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
+void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
{
- add_object(obj, &revs->pending_objects, NULL, name);
+ add_object_array(obj, name, &revs->pending);
}
static struct object *get_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags)
@@ -836,7 +831,7 @@ int setup_revisions(int argc, const char
object = get_reference(revs, arg, sha1, flags ^ local_flags);
add_pending_object(revs, object, arg);
}
- if (def && !revs->pending_objects) {
+ if (def && !revs->pending.nr) {
unsigned char sha1[20];
struct object *object;
if (get_sha1(def, sha1))
@@ -868,11 +863,13 @@ int setup_revisions(int argc, const char
void prepare_revision_walk(struct rev_info *revs)
{
- struct object_list *list;
+ int nr = revs->pending.nr;
+ struct object_array_entry *list = revs->pending.objects;
- list = revs->pending_objects;
- revs->pending_objects = NULL;
- while (list) {
+ revs->pending.nr = 0;
+ revs->pending.alloc = 0;
+ revs->pending.objects = NULL;
+ while (--nr >= 0) {
struct commit *commit = handle_commit(revs, list->item, list->name);
if (commit) {
if (!(commit->object.flags & SEEN)) {
@@ -880,7 +877,7 @@ void prepare_revision_walk(struct rev_in
insert_by_date(commit, &revs->commits);
}
}
- list = list->next;
+ list++;
}
if (revs->no_walk)
diff --git a/revision.h b/revision.h
index 4020e25..c010a08 100644
--- a/revision.h
+++ b/revision.h
@@ -18,7 +18,7 @@ typedef void (prune_fn_t)(struct rev_inf
struct rev_info {
/* Starting list */
struct commit_list *commits;
- struct object_list *pending_objects;
+ struct object_array pending;
/* Basic information */
const char *prefix;
@@ -99,9 +99,11 @@ struct name_path {
const char *elem;
};
-extern struct object_list **add_object(struct object *obj,
- struct object_list **p,
- struct name_path *path,
- const char *name);
+extern void add_object(struct object *obj,
+ struct object_array *p,
+ struct name_path *path,
+ const char *name);
+
+extern void add_pending_object(struct rev_info *revs, struct object *obj, const char *name);
#endif
^ permalink raw reply related
* Re: [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)?
From: Junio C Hamano @ 2006-06-20 0:36 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0606191654590.5498@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> Whether we want to do that in the main() routine or when we actually do
> the fork() or whatever is a different issue.
I do not offhand think of a place where we do fork() but not
waitpid(), and it is very tempting to cheat and do that in the
main(), since I do not see a downside to it.
^ permalink raw reply
* Packing empty subtrees: good/bad/indifferent?
From: Shawn Pearce @ 2006-06-20 0:09 UTC (permalink / raw)
To: git
So in my Eclipse plugin/Java GIT implementation I'm trying to figure
out what to do if the API caller feeds me a subtree which is empty.
Core GIT won't store an empty subtree simply because the subtree
can't exist in the index without at least one file in the tree.
But my Java implementation doesn't suffer from that limitation and
will happily store an empty subtree (and checkout an empty directory)
if that is what the caller gave it. :-)
In the plugin's UI level I'm trying relatively hard to refuse putting
an empty directory into the repository as an empty subtree but I'm
now wondering if I should enforce that even lower (like down in
the actual tree writer) just to be on the safe side.
Anyone have two cents they could share on the matter?
--
Shawn.
^ permalink raw reply
* Re: [PATCH] Initialize lock_file struct to all zero.
From: Junio C Hamano @ 2006-06-20 0:04 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0606200054290.26329@wbgn013.biozentrum.uni-wuerzburg.de>
Good catch. Thanks.
^ permalink raw reply
* Re: [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)?
From: Linus Torvalds @ 2006-06-19 23:57 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vwtbc7ll6.fsf@assigned-by-dhcp.cox.net>
On Mon, 19 Jun 2006, Junio C Hamano wrote:
>
> Somebody I met last week in Japan reported that the socks client
> he uses to cross the firewall to connect to git:// port from his
> company environment seems to do signal(SIGCHLD, SIG_IGN) before
> spawning git.
Ok, that sounds pretty broken of it.
> We could work this around by having signal(SIGCHLD, SIG_DFL)
> upfront in git.c::main(), but I am wondering what the standard
> practice for programs that use waitpid() call.
We need the status return, so failing on getting ECHILD is absolutely the
right thing to do, because it implies that we don't know what the status
could have been.
So we need to reset SIGCHLD back to SIG_DFL (or catch it explicitly).
Whether we want to do that in the main() routine or when we actually do
the fork() or whatever is a different issue.
Linus
^ permalink raw reply
* [Q] what to do when waitpid() returns ECHILD under signal(SIGCHLD, SIG_IGN)?
From: Junio C Hamano @ 2006-06-19 23:49 UTC (permalink / raw)
To: git; +Cc: Linus Torvalds
Somebody I met last week in Japan reported that the socks client
he uses to cross the firewall to connect to git:// port from his
company environment seems to do signal(SIGCHLD, SIG_IGN) before
spawning git. When "git clone" is invoked this way, we get a
mysterious failure.
I can reproduce the problem without using funny socks client
like this:
: gitster; trap '' SIGCHLD
: gitster; git clone git://git.kernel.org/pub/scm/git/git.git/ foo.git
error: waitpid failed (No child processes)
fetch-pack from 'git://git.kernel.org/pub/scm/git/git.git/' failed.
: gitster; ls foo.git
ls: foo.git: No such file or directory
We could work this around by having signal(SIGCHLD, SIG_DFL)
upfront in git.c::main(), but I am wondering what the standard
practice for programs that use waitpid() call. Do they protect
themselves from this in order to reliably obtain child exit
status? Or do they simply consider it is a user error to run a
program that use waitpid() with SIGCHLD ignored?
http://www.opengroup.org/onlinepubs/009695399/functions/waitpid.html
explicitly says this is an expected behaviour, so barfing upon
ECHILD sounds like a bug on our part.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox