From fcfa32b9e10b3c0373a263a732146850bdf67242 Mon Sep 17 00:00:00 2001 From: Yaacov Akiba Slama Date: Wed, 2 Nov 2005 23:51:57 +0200 Subject: [PATCH 01/22] Use svn pools to solve the memory leak problem. Signed-off-by: Yaacov Akiba Slama Signed-off-by: Junio C Hamano --- git-svnimport.perl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/git-svnimport.perl b/git-svnimport.perl index 45b6a1986..5bf9ef21e 100755 --- a/git-svnimport.perl +++ b/git-svnimport.perl @@ -112,7 +112,9 @@ sub file { DIR => File::Spec->tmpdir(), UNLINK => 1); print "... $rev $path ...\n" if $opt_v; - eval { $self->{'svn'}->get_file($path,$rev,$fh); }; + my $pool = SVN::Pool->new(); + eval { $self->{'svn'}->get_file($path,$rev,$fh,$pool); }; + $pool->clear; if($@) { return undef if $@ =~ /Attempted to get checksum/; die $@; @@ -674,7 +676,9 @@ sub commit_all { } while(++$current_rev <= $svn->{'maxrev'}) { - $svn->{'svn'}->get_log("/",$current_rev,$current_rev,$current_rev,1,1,\&_commit_all,""); + my $pool=SVN::Pool->new; + $svn->{'svn'}->get_log("/",$current_rev,$current_rev,1,1,1,\&_commit_all,$pool); + $pool->clear; commit_all(); if($opt_l and not --$opt_l) { print STDERR "Stopping, because there is a memory leak (in the SVN library).\n"; From cbce5d8961f7790a621f7cee6ecb2c25ae372867 Mon Sep 17 00:00:00 2001 From: Yaacov Akiba Slama Date: Wed, 2 Nov 2005 23:51:57 +0200 Subject: [PATCH 02/22] Add node_kind function to differentiate between file and directory Signed-off-by: Yaacov Akiba Slama Signed-off-by: Junio C Hamano --- git-svnimport.perl | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/git-svnimport.perl b/git-svnimport.perl index 5bf9ef21e..83b70f9bb 100755 --- a/git-svnimport.perl +++ b/git-svnimport.perl @@ -260,10 +260,17 @@ ($$) open BRANCHES,">>", "$git_dir/svn2git"; -sub get_file($$$) { - my($rev,$branch,$path) = @_; +sub node_kind($$$) { + my ($branch, $path, $revision) = @_; + my $pool=SVN::Pool->new; + my $kind = $svn->{'svn'}->check_path(revert_split_path($branch,$path),$revision,$pool); + $pool->clear; + return $kind; +} + +sub revert_split_path($$) { + my($branch,$path) = @_; - # revert split_path(), below my $svnpath; $path = "" if $path eq "/"; # this should not happen, but ... if($branch eq "/") { @@ -274,6 +281,14 @@ ($$$) $svnpath = "$branch_name/$branch/$path"; } + return $svnpath +} + +sub get_file($$$) { + my($rev,$branch,$path) = @_; + + my $svnpath = revert_split_path($branch,$path); + # now get it my $name; if($opt_d) { From c2c07a5c2adf2aebc19b04a608592489b156a8bb Mon Sep 17 00:00:00 2001 From: Yaacov Akiba Slama Date: Wed, 2 Nov 2005 23:51:57 +0200 Subject: [PATCH 03/22] Don't output error on changes in the nodes /, /tags or /branches Signed-off-by: Junio C Hamano --- git-svnimport.perl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/git-svnimport.perl b/git-svnimport.perl index 83b70f9bb..ea5bbdb8a 100755 --- a/git-svnimport.perl +++ b/git-svnimport.perl @@ -336,7 +336,12 @@ ($$) } elsif($path =~ s#^/\Q$branch_name\E/([^/]+)/?##) { $branch = $1; } else { - print STDERR "$rev: Unrecognized path: $path\n"; + my %no_error = ( + "/" => 1, + "/$tag_name" => 1, + "/$branch_name" => 1 + ); + print STDERR "$rev: Unrecognized path: $path\n" unless (defined $no_error{$path}); return () } $path = "/" if $path eq ""; From 8168373fe7e6214205fd23e519f72c3f1bbb7080 Mon Sep 17 00:00:00 2001 From: Yaacov Akiba Slama Date: Wed, 2 Nov 2005 23:51:57 +0200 Subject: [PATCH 04/22] copy_dir becomes copy_path and handles both files and directories The A (Add) and R (Replace) actions handling are unified. Signed-off-by: Yaacov Akiba Slama Signed-off-by: Junio C Hamano --- git-svnimport.perl | 90 +++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/git-svnimport.perl b/git-svnimport.perl index ea5bbdb8a..9cee629f1 100755 --- a/git-svnimport.perl +++ b/git-svnimport.perl @@ -348,21 +348,42 @@ ($$) return ($branch,$path); } -sub copy_subdir($$$$$$) { +sub branch_rev($$) { + + my ($srcbranch,$uptorev) = @_; + + my $bbranches = $branches{$srcbranch}; + my @revs = reverse sort { ($a eq 'LAST' ? 0 : $a) <=> ($b eq 'LAST' ? 0 : $b) } keys %$bbranches; + my $therev; + foreach my $arev(@revs) { + next if ($arev eq 'LAST'); + if ($arev <= $uptorev) { + $therev = $arev; + last; + } + } + return $therev; +} + +sub copy_path($$$$$$$) { # Somebody copied a whole subdirectory. # We need to find the index entries from the old version which the # SVN log entry points to, and add them to the new place. - my($newrev,$newbranch,$path,$oldpath,$rev,$new) = @_; - my($branch,$srcpath) = split_path($rev,$oldpath); + my($newrev,$newbranch,$path,$oldpath,$rev,$node_kind,$new) = @_; - my $gitrev = $branches{$branch}{$rev}; + my($srcbranch,$srcpath) = split_path($rev,$oldpath); + my $therev = branch_rev($srcbranch, $rev); + my $gitrev = $branches{$srcbranch}{$therev}; unless($gitrev) { print STDERR "$newrev:$newbranch: could not find $oldpath \@ $rev\n"; return; } - print "$newrev:$newbranch:$path: copying from $branch:$srcpath @ $rev\n" if $opt_v; - $srcpath =~ s#/*$#/#; + print "$newrev:$newbranch:$path: copying from $srcbranch:$srcpath @ $rev\n" if $opt_v; + if ($node_kind eq $SVN::Node::dir) { + $srcpath =~ s#/*$#/#; + } + open my $f,"-|","git-ls-tree","-r","-z",$gitrev,$srcpath; local $/ = "\0"; while(<$f>) { @@ -370,9 +391,12 @@ ($$$$$$) my($m,$p) = split(/\t/,$_,2); my($mode,$type,$sha1) = split(/ /,$m); next if $type ne "blob"; - $p = substr($p,length($srcpath)-1); - print "... found $path$p ...\n" if $opt_v; - push(@$new,[$mode,$sha1,$path.$p]); + if ($node_kind eq $SVN::Node::dir) { + $p = $path . substr($p,length($srcpath)-1); + } else { + $p = $path; + } + push(@$new,[$mode,$sha1,$p]); } close($f) or print STDERR "$newrev:$newbranch: could not list files in $oldpath \@ $rev\n"; @@ -476,39 +500,31 @@ sub commit { foreach my $path(@paths) { my $action = $changed_paths->{$path}; - if ($action->[0] eq "A") { - my $f = get_file($revision,$branch,$path); - if($f) { - push(@new,$f) if $f; - } elsif($action->[1]) { - copy_subdir($revision,$branch,$path,$action->[1],$action->[2],\@new); - } else { - my $opath = $action->[3]; - print STDERR "$revision: $branch: could not fetch '$opath'\n"; + if ($action->[0] eq "R") { + # refer to a file/tree in an earlier commit + push(@old,$path); # remove any old stuff + } + if(($action->[0] eq "A") || ($action->[0] eq "R")) { + my $node_kind = node_kind($branch,$path,$revision); + if($action->[1]) { + copy_path($revision,$branch,$path,$action->[1],$action->[2],$node_kind,\@new); + } elsif ($node_kind eq $SVN::Node::file) { + my $f = get_file($revision,$branch,$path); + if ($f) { + push(@new,$f) if $f; + } else { + my $opath = $action->[3]; + print STDERR "$revision: $branch: could not fetch '$opath'\n"; + } } } elsif ($action->[0] eq "D") { push(@old,$path); } elsif ($action->[0] eq "M") { - my $f = get_file($revision,$branch,$path); - push(@new,$f) if $f; - } elsif ($action->[0] eq "R") { - # refer to a file/tree in an earlier commit - push(@old,$path); # remove any old stuff - - # ... and add any new stuff - my($b,$srcpath) = split_path($revision,$action->[1]); - $srcpath =~ s#/*$#/#; - open my $F,"-|","git-ls-tree","-r","-z", $branches{$b}{$action->[2]}, $srcpath; - local $/ = "\0"; - while(<$F>) { - chomp; - my($m,$p) = split(/\t/,$_,2); - my($mode,$type,$sha1) = split(/ /,$m); - next if $type ne "blob"; - $p = substr($p,length($srcpath)-1); - push(@new,[$mode,$sha1,$path.$p]); + my $node_kind = node_kind($branch,$path,$revision); + if ($node_kind eq $SVN::Node::file) { + my $f = get_file($revision,$branch,$path); + push(@new,$f) if $f; } - close($F); } else { die "$revision: unknown action '".$action->[0]."' for $path\n"; } From 109fc2b97b73090a4a0a6550cdf9b2446fd12389 Mon Sep 17 00:00:00 2001 From: Yaacov Akiba Slama Date: Wed, 2 Nov 2005 23:51:57 +0200 Subject: [PATCH 05/22] Bundle file copies from multiple branches into a merge. When copying files and/or directories from several branches in one single revision, all these branches are used as parents of the commit. Signed-off-by: Yaacov Akiba Slama Signed-off-by: Junio C Hamano --- git-svnimport.perl | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/git-svnimport.perl b/git-svnimport.perl index 9cee629f1..ae82a7c09 100755 --- a/git-svnimport.perl +++ b/git-svnimport.perl @@ -365,12 +365,12 @@ ($$) return $therev; } -sub copy_path($$$$$$$) { +sub copy_path($$$$$$$$) { # Somebody copied a whole subdirectory. # We need to find the index entries from the old version which the # SVN log entry points to, and add them to the new place. - my($newrev,$newbranch,$path,$oldpath,$rev,$node_kind,$new) = @_; + my($newrev,$newbranch,$path,$oldpath,$rev,$node_kind,$new,$parents) = @_; my($srcbranch,$srcpath) = split_path($rev,$oldpath); my $therev = branch_rev($srcbranch, $rev); @@ -379,6 +379,9 @@ ($$$$$$$) print STDERR "$newrev:$newbranch: could not find $oldpath \@ $rev\n"; return; } + if ($srcbranch ne $newbranch) { + push(@$parents, $branches{$srcbranch}{'LAST'}); + } print "$newrev:$newbranch:$path: copying from $srcbranch:$srcpath @ $rev\n" if $opt_v; if ($node_kind eq $SVN::Node::dir) { $srcpath =~ s#/*$#/#; @@ -405,7 +408,7 @@ ($$$$$$$) sub commit { my($branch, $changed_paths, $revision, $author, $date, $message) = @_; my($author_name,$author_email,$dest); - my(@old,@new); + my(@old,@new,@parents); if (not defined $author) { $author_name = $author_email = "unknown"; @@ -492,6 +495,8 @@ sub commit { $last_rev = $rev; } + push (@parents, $rev) if defined $rev; + my $cid; if($tag and not %$changed_paths) { $cid = $rev; @@ -507,7 +512,7 @@ sub commit { if(($action->[0] eq "A") || ($action->[0] eq "R")) { my $node_kind = node_kind($branch,$path,$revision); if($action->[1]) { - copy_path($revision,$branch,$path,$action->[1],$action->[2],$node_kind,\@new); + copy_path($revision,$branch,$path,$action->[1],$action->[2],$node_kind,\@new,\@parents); } elsif ($node_kind eq $SVN::Node::file) { my $f = get_file($revision,$branch,$path); if ($f) { @@ -592,7 +597,6 @@ sub commit { $pw->close(); my @par = (); - @par = ("-p",$rev) if defined $rev; # loose detection of merges # based on the commit msg @@ -602,11 +606,17 @@ sub commit { if ($mparent eq 'HEAD') { $mparent = $opt_o }; if ( -e "$git_dir/refs/heads/$mparent") { $mparent = get_headref($mparent, $git_dir); - push @par, '-p', $mparent; + push (@parents, $mparent); print OUT "Merge parent branch: $mparent\n" if $opt_v; } } } + my %seen_parents = (); + my @unique_parents = grep { ! $seen_parents{$_} ++ } @parents; + foreach my $bparent (@unique_parents) { + push @par, '-p', $bparent; + print OUT "Merge parent branch: $bparent\n" if $opt_v; + } exec("env", "GIT_AUTHOR_NAME=$author_name", From a16db4f472887a9050bf528bc7f0b94d6f7e8319 Mon Sep 17 00:00:00 2001 From: Yaacov Akiba Slama Date: Wed, 2 Nov 2005 23:51:57 +0200 Subject: [PATCH 06/22] Handle a revision that only creates a new tag correctly. Fix an error when a svn revision consists only of the creation of a new tag directory (/tags/this_is_a_tag). Signed-off-by: Yaacov Akiba Slama Signed-off-by: Junio C Hamano --- git-svnimport.perl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/git-svnimport.perl b/git-svnimport.perl index ae82a7c09..e97f47059 100755 --- a/git-svnimport.perl +++ b/git-svnimport.perl @@ -648,6 +648,10 @@ sub commit { die "Error running git-commit-tree: $?\n" if $?; } + if (not defined $cid) { + $cid = $branches{"/"}{"LAST"}; + } + if(not defined $dest) { print "... no known parent\n" if $opt_v; } elsif(not $tag) { @@ -664,6 +668,7 @@ sub commit { # the tag was 'complex', i.e. did not refer to a "real" revision $dest =~ tr/_/\./ if $opt_u; + $branch = $dest; my $pid = open2($in, $out, 'git-mktag'); print $out ("object $cid\n". From 01d4f0e7758f0fa837eec18a901a668f816cfc5f Mon Sep 17 00:00:00 2001 From: Yaacov Akiba Slama Date: Wed, 2 Nov 2005 23:51:58 +0200 Subject: [PATCH 07/22] Lift the default limit of number of revs. Now that the leak is gone, there is by default no limit of revisions to import. No more message about leak when the limit (given by the -l parameter) is reached. Signed-off-by: Yaacov Akiba Slama Signed-off-by: Junio C Hamano --- git-svnimport.perl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/git-svnimport.perl b/git-svnimport.perl index e97f47059..ab690f364 100755 --- a/git-svnimport.perl +++ b/git-svnimport.perl @@ -53,7 +53,6 @@ END $opt_o ||= "origin"; $opt_s ||= 1; -$opt_l = 100 unless defined $opt_l; my $git_tree = $opt_C; $git_tree ||= "."; @@ -727,15 +726,16 @@ sub commit_all { } while(++$current_rev <= $svn->{'maxrev'}) { + if (defined $opt_l) { + $opt_l--; + if ($opt_l < 0) { + last; + } + } my $pool=SVN::Pool->new; $svn->{'svn'}->get_log("/",$current_rev,$current_rev,1,1,1,\&_commit_all,$pool); $pool->clear; commit_all(); - if($opt_l and not --$opt_l) { - print STDERR "Stopping, because there is a memory leak (in the SVN library).\n"; - print STDERR "Please repeat this command; it will continue safely\n"; - last; - } } From f3ad062560bfd4a2983122de93d08f43ea66e7cf Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Nov 2005 23:30:12 -0800 Subject: [PATCH 08/22] Fix a couple of obvious and insignificant typo. Signed-off-by: Junio C Hamano --- git-svnimport.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git-svnimport.perl b/git-svnimport.perl index ab690f364..cb9afb955 100755 --- a/git-svnimport.perl +++ b/git-svnimport.perl @@ -25,7 +25,7 @@ use SVN::Core; use SVN::Ra; -die "Need CVN:Core 1.2.1 or better" if $SVN::Core::VERSION lt "1.2.1"; +die "Need SVN:Core 1.2.1 or better" if $SVN::Core::VERSION lt "1.2.1"; $SIG{'PIPE'}="IGNORE"; $ENV{'TZ'}="UTC"; @@ -34,7 +34,7 @@ sub usage() { print STDERR < Date: Sat, 5 Nov 2005 11:38:02 -0800 Subject: [PATCH 09/22] Separate RPMS for programs with non-standard dependencies. Signed-off-by: Jim Radford Signed-off-by: Junio C Hamano --- git-core.spec.in | 50 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/git-core.spec.in b/git-core.spec.in index 5240dd2c2..26846d005 100644 --- a/git-core.spec.in +++ b/git-core.spec.in @@ -19,32 +19,70 @@ distributed source code management system. This package includes rudimentary tools that can be used as a SCM, but you should look elsewhere for tools for ordinary humans layered on top of this. +%package svn +Summary: Git tools for importing Subversion repositories. +Group: Development/Tools +Requires: subversion +%description svn +Git tools for importing Subversion repositories. + +%package cvs +Summary: Git tools for importing CVS repositories. +Group: Development/Tools +Requires: cvs +%description cvs +Git tools for importing CVS repositories. + +%package email +Summary: Git tools for sending email. +Group: Development/Tools +%description email +Git tools for sending email. + %prep %setup -q %build -make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" WITH_OWN_SUBPROCESS_PY=YesPlease \ +make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" WITH_OWN_SUBPROCESS_PY=YesPlease WITH_SEND_EMAIL=1 \ prefix=%{_prefix} all %{!?_without_docs: doc} %install rm -rf $RPM_BUILD_ROOT -make %{_smp_mflags} DESTDIR=$RPM_BUILD_ROOT WITH_OWN_SUBPROCESS_PY=YesPlease \ +make %{_smp_mflags} DESTDIR=$RPM_BUILD_ROOT WITH_OWN_SUBPROCESS_PY=YesPlease WITH_SEND_EMAIL=1 \ prefix=%{_prefix} mandir=%{_mandir} \ install %{!?_without_docs: install-doc} +(find $RPM_BUILD_ROOT%{_bindir} -type f | grep -vE "svn|cvs|email" | sed -e s@^$RPM_BUILD_ROOT@@) > bin-man-files +%if %{!?_without_docs:1}0 +(find $RPM_BUILD_ROOT%{_mandir} -type f | grep -vE "svn|cvs|email" | sed -e s@^$RPM_BUILD_ROOT@@ -e 's/$/*/' ) >> bin-man-files +%endif + %clean rm -rf $RPM_BUILD_ROOT -%files +%files svn +%{_bindir}/*svn* +%{!?_without_docs: %{_mandir}/man1/*svn*.1*} + +%files cvs +%{_bindir}/*cvs* +%{!?_without_docs: %{_mandir}/man1/*cvs*.1*} + +%files email +%{_bindir}/*email* +%{!?_without_docs: %{_mandir}/man1/*email*.1*} + +%files -f bin-man-files %defattr(-,root,root) -%{_bindir}/* %{_datadir}/git-core/ %doc README COPYING Documentation/*.txt %{!?_without_docs: %doc Documentation/*.html } -%{!?_without_docs: %{_mandir}/man1/*.1*} -%{!?_without_docs: %{_mandir}/man7/*.7*} %changelog +* Tue Sep 27 2005 Jim Radford +- Move programs with non-standard dependencies (svn, cvs, email) + into separate packages + * Tue Sep 27 2005 H. Peter Anvin - parallelize build - COPTS -> CFLAGS From f8d294f0a44c4305a9f3a1c70beb6a1c7583f287 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 8 Nov 2005 08:58:52 -0800 Subject: [PATCH 10/22] Clean build annoyance. As Pasky pointed out, building in templates directory showed list of built template files which was unneeded. This commit also fixes another build annoyance I recently left in by accident. Signed-off-by: Junio C Hamano --- Documentation/build-docdep.perl | 4 ---- templates/Makefile | 1 - 2 files changed, 5 deletions(-) diff --git a/Documentation/build-docdep.perl b/Documentation/build-docdep.perl index 6ff35e02f..489389c32 100755 --- a/Documentation/build-docdep.perl +++ b/Documentation/build-docdep.perl @@ -22,15 +22,11 @@ while ($changed) { $changed = 0; while (my ($text, $included) = each %include) { - print STDERR "Looking at $text...\n"; for my $i (keys %$included) { - print STDERR "$text includes $i.\n"; # $text has include::$i; if $i includes $j # $text indirectly includes $j. if (exists $include{$i}) { - print STDERR "$i includes something.\n"; for my $j (keys %{$include{$i}}) { - print STDERR "$text includes $i include $j\n"; if (!exists $include{$text}{$j}) { $include{$text}{$j} = 1; $included{$j} = 1; diff --git a/templates/Makefile b/templates/Makefile index 07e928e56..8f7f4fec3 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -13,7 +13,6 @@ shq = $(subst ','\'',$(1)) shellquote = '$(call shq,$(1))' all: boilerplates.made custom - find blt # Put templates that can be copied straight from the source # in a file direc--tory--file in the source. They will be From cb34882bd61e00295b6213d8c4c7bf9bb0e10a17 Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Tue, 8 Nov 2005 11:45:15 +0100 Subject: [PATCH 11/22] fix t5000-tar-tree.sh when $TAR isn't set $TAR isn't set everywhere. Provide a default (tar) Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- t/t5000-tar-tree.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh index 4db1bb114..adc5e937d 100755 --- a/t/t5000-tar-tree.sh +++ b/t/t5000-tar-tree.sh @@ -25,6 +25,7 @@ commit id embedding: ' . ./test-lib.sh +TAR=${TAR:-tar} test_expect_success \ 'populate workdir' \ From 23fc63bf8fb7c3627f78ca6743b4f3ae17a5df49 Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Tue, 8 Nov 2005 10:51:10 +0100 Subject: [PATCH 12/22] make tests ignorable with "make -i" Allow failed tests to be ignored using make's "-i". The patch also disables parallel make in t/. This doesn't make the testing any different as before: the tests were run sequentially before. It also allows to run more tests, ignoring the ones usually failing just to figure out if something else broke. (Or to ignore plainly uninteresting situations because of the testing being done on say... cygwin ;) Signed-off-by: Junio C Hamano --- t/Makefile | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/t/Makefile b/t/Makefile index 5c76afff8..5c5a62012 100644 --- a/t/Makefile +++ b/t/Makefile @@ -15,9 +15,14 @@ shellquote = '$(call shq,$(1))' T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh) -all: - @$(foreach t,$T,echo "*** $t ***"; $(call shellquote,$(SHELL_PATH)) $t $(GIT_TEST_OPTS) || exit; ) - @rm -fr trash +all: $(T) clean + +$(T): + @echo "*** $@ ***"; $(call shellquote,$(SHELL_PATH)) $@ $(GIT_TEST_OPTS) clean: rm -fr trash + +.PHONY: $(T) clean +.NOPARALLEL: + From 61f81518a2372dd78fa03da2b3d62173c3268ee7 Mon Sep 17 00:00:00 2001 From: Kai Ruemmler Date: Tue, 8 Nov 2005 11:44:33 +0100 Subject: [PATCH 13/22] git-tag -d : delete tag This adds option '-d' to git-tag.sh and documents it. Signed-off-by: Kai Ruemmler Signed-off-by: Junio C Hamano --- Documentation/git-tag.txt | 4 +++- git-tag.sh | 9 ++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 3984812ce..95de436c1 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -8,7 +8,7 @@ git-tag - Create a tag object signed with GPG SYNOPSIS -------- -'git-tag' [-a | -s | -u ] [-f] [-m ] [] +'git-tag' [-a | -s | -u ] [-f | -d] [-m ] [] DESCRIPTION ----------- @@ -30,6 +30,8 @@ A GnuPG signed tag object will be created when `-s` or `-u committer identity for the current user is used to find the GnuPG key for signing. +`-d ` deletes the tag. + Author ------ diff --git a/git-tag.sh b/git-tag.sh index 6130904a9..137594530 100755 --- a/git-tag.sh +++ b/git-tag.sh @@ -4,7 +4,7 @@ . git-sh-setup || die "Not a git archive" usage () { - echo >&2 "Usage: git-tag [-a | -s | -u ] [-f] [-m ] []" + echo >&2 "Usage: git-tag [-a | -s | -u ] [-f | -d] [-m ] []" exit 1 } @@ -37,6 +37,13 @@ do shift username="$1" ;; + -d) + shift + tag_name="$1" + rm "$GIT_DIR/refs/tags/$tag_name" && \ + echo "Deleted tag $tag_name." + exit $? + ;; -*) usage ;; From f4f440a039587c14ca29a8fe127b4d5273eacafc Mon Sep 17 00:00:00 2001 From: Peter Hagervall Date: Tue, 8 Nov 2005 23:18:31 +0100 Subject: [PATCH 14/22] sparse fixes for http-{fetch,push}.c Make a bunch of needlessly global functions static, and replace two K&R-style declarations. Signed-off-by: Peter Hagervall Signed-off-by: Junio C Hamano --- http-fetch.c | 4 ++-- http-push.c | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/http-fetch.c b/http-fetch.c index ea8af1b2d..88b74b434 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -569,7 +569,7 @@ static void release_request(struct transfer_request *request) } #ifdef USE_CURL_MULTI -void process_curl_messages(void) +static void process_curl_messages(void) { int num_messages; struct active_request_slot *slot; @@ -625,7 +625,7 @@ void process_curl_messages(void) } } -void process_request_queue(void) +static void process_request_queue(void) { struct transfer_request *request = request_queue_head; struct active_request_slot *slot = active_queue_head; diff --git a/http-push.c b/http-push.c index 0b90fb9ae..886618933 100644 --- a/http-push.c +++ b/http-push.c @@ -595,7 +595,7 @@ static void start_move(struct transfer_request *request) } } -int refresh_lock(struct active_lock *lock) +static int refresh_lock(struct active_lock *lock) { struct active_request_slot *slot; char *if_header; @@ -726,7 +726,7 @@ static void release_request(struct transfer_request *request) } #ifdef USE_CURL_MULTI -void process_curl_messages(void) +static void process_curl_messages(void) { int num_messages; struct active_request_slot *slot; @@ -766,7 +766,7 @@ void process_curl_messages(void) } } -void process_request_queue(void) +static void process_request_queue(void) { struct transfer_request *request = request_queue_head; struct active_request_slot *slot = active_queue_head; @@ -799,7 +799,7 @@ void process_request_queue(void) } #endif -void process_waiting_requests(void) +static void process_waiting_requests(void) { struct active_request_slot *slot = active_queue_head; @@ -812,7 +812,7 @@ void process_waiting_requests(void) } } -void add_request(unsigned char *sha1, struct active_lock *lock) +static void add_request(unsigned char *sha1, struct active_lock *lock) { struct transfer_request *request = request_queue_head; struct packed_git *target; @@ -939,7 +939,7 @@ static int setup_index(unsigned char *sha1) return 0; } -static int fetch_indices() +static int fetch_indices(void) { unsigned char sha1[20]; char *url; @@ -1189,7 +1189,7 @@ end_lockprop_element(void *userData, const char *name) } } -struct active_lock *lock_remote(char *file, long timeout) +static struct active_lock *lock_remote(char *file, long timeout) { struct active_request_slot *slot; struct buffer out_buffer; @@ -1318,7 +1318,7 @@ struct active_lock *lock_remote(char *file, long timeout) return new_lock; } -int unlock_remote(struct active_lock *lock) +static int unlock_remote(struct active_lock *lock) { struct active_request_slot *slot; char *lock_token_header; @@ -1359,7 +1359,7 @@ int unlock_remote(struct active_lock *lock) return rc; } -int check_locking() +static int check_locking(void) { struct active_request_slot *slot; struct buffer in_buffer; @@ -1425,7 +1425,7 @@ int check_locking() return 1; } -int is_ancestor(unsigned char *sha1, struct commit *commit) +static int is_ancestor(unsigned char *sha1, struct commit *commit) { struct commit_list *parents; @@ -1446,8 +1446,8 @@ int is_ancestor(unsigned char *sha1, struct commit *commit) return 0; } -void get_delta(unsigned char *sha1, struct object *obj, - struct active_lock *lock) +static void get_delta(unsigned char *sha1, struct object *obj, + struct active_lock *lock) { struct commit *commit; struct commit_list *parents; @@ -1503,7 +1503,7 @@ void get_delta(unsigned char *sha1, struct object *obj, } } -int update_remote(unsigned char *sha1, struct active_lock *lock) +static int update_remote(unsigned char *sha1, struct active_lock *lock) { struct active_request_slot *slot; char *out_data; From f37d0cc3ff6ef565f961a0d3741ba016e1ceb31d Mon Sep 17 00:00:00 2001 From: "Luck, Tony" Date: Tue, 8 Nov 2005 15:52:02 -0800 Subject: [PATCH 15/22] Update howto using-topic-branches "git resolve" is being deprecated in favour of "git merge". Update the documentation to reflect this. Signed-off-by: Tony Luck Signed-off-by: Junio C Hamano --- Documentation/howto/using-topic-branches.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/howto/using-topic-branches.txt b/Documentation/howto/using-topic-branches.txt index c6c635a51..4698abe46 100644 --- a/Documentation/howto/using-topic-branches.txt +++ b/Documentation/howto/using-topic-branches.txt @@ -9,7 +9,7 @@ GIT as a Linux subsystem maintainer. -Tony -Last updated w.r.t. GIT 0.99.5 +Last updated w.r.t. GIT 0.99.9f Linux subsystem maintenance using GIT ------------------------------------- @@ -89,8 +89,8 @@ out at the current tip of the linus branch. These can be easily kept up to date by merging from the "linus" branch: - $ git checkout test && git resolve test linus "Auto-update from upstream" - $ git checkout release && git resolve release linus "Auto-update from upstream" + $ git checkout test && git merge "Auto-update from upstream" test linus + $ git checkout release && git merge "Auto-update from upstream" release linus Set up so that you can push upstream to your public tree (you need to log-in to the remote system and create an empty tree there before the @@ -128,7 +128,7 @@ commit to this branch. When you are happy with the state of this change, you can pull it into the "test" branch in preparation to make it public: - $ git checkout test && git resolve test speed-up-spinlocks "Pull speed-up-spinlock changes" + $ git checkout test && git merge "Pull speed-up-spinlock changes" test speed-up-spinlocks It is unlikely that you would have any conflicts here ... but you might if you spent a while on this step and had also pulled new versions from upstream. @@ -138,7 +138,7 @@ same branch into the "release" tree ready to go upstream. This is where you see the value of keeping each patch (or patch series) in its own branch. It means that the patches can be moved into the "release" tree in any order. - $ git checkout release && git resolve release speed-up-spinlocks "Pull speed-up-spinlock changes" + $ git checkout release && git merge "Pull speed-up-spinlock changes" release speed-up-spinlocks After a while, you will have a number of branches, and despite the well chosen names you picked for each of them, you may forget what @@ -190,7 +190,7 @@ Here are some of the scripts that I use to simplify all this even further. case "$1" in test|release) - git checkout $1 && git resolve $1 linus "Auto-update from upstream" + git checkout $1 && git merge "Auto-update from upstream" $1 linus ;; linus) before=$(cat .git/refs/heads/linus) @@ -231,7 +231,7 @@ test|release) echo $1 already merged into $2 1>&2 exit 1 fi - git checkout $2 && git resolve $2 $1 "Pull $1 into $2 branch" + git checkout $2 && git merge "Pull $1 into $2 branch" $2 $1 ;; *) usage From e09f5d7b07ada67f9e9c25ba7e58d76b8d5f4253 Mon Sep 17 00:00:00 2001 From: Alexander Litvinov Date: Wed, 9 Nov 2005 13:02:58 +0600 Subject: [PATCH 16/22] Fix cvsexportcommit syntax error There is a syntax error in cvsexport script: Signed-off-by: Junio C Hamano --- git-cvsexportcommit.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl index 7074b0c21..50b041c32 100755 --- a/git-cvsexportcommit.perl +++ b/git-cvsexportcommit.perl @@ -64,7 +64,7 @@ last; }; # found it die "Did not find $parent in the parents for this commit!"; -s } + } } else { # we don't have a parent from the cmdline... if (@parents == 1) { # it's safe to get it from the commit $parent = $parents[0]; From c8a4f5e5422677b950e7e74b29fa6631fd8ce243 Mon Sep 17 00:00:00 2001 From: Fredrik Kuivinen Date: Wed, 9 Nov 2005 11:36:55 +0100 Subject: [PATCH 17/22] merge-recursive: Fix limited output of rename messages The previous code did the right thing, but it did it by accident. Signed-off-by: Fredrik Kuivinen Signed-off-by: Junio C Hamano --- git-merge-recursive.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/git-merge-recursive.py b/git-merge-recursive.py index 9983cd9de..36578754c 100755 --- a/git-merge-recursive.py +++ b/git-merge-recursive.py @@ -162,13 +162,10 @@ def mergeTrees(head, merge, common, branch1Name, branch2Name): # Low level file merging, update and removal # ------------------------------------------ -MERGE_NONE = 0 -MERGE_TRIVIAL = 1 -MERGE_3WAY = 2 def mergeFile(oPath, oSha, oMode, aPath, aSha, aMode, bPath, bSha, bMode, branch1Name, branch2Name): - merge = MERGE_NONE + merge = False clean = True if stat.S_IFMT(aMode) != stat.S_IFMT(bMode): @@ -181,7 +178,7 @@ def mergeFile(oPath, oSha, oMode, aPath, aSha, aMode, bPath, bSha, bMode, sha = bSha else: if aSha != oSha and bSha != oSha: - merge = MERGE_TRIVIAL + merge = True if aMode == oMode: mode = bMode @@ -211,7 +208,6 @@ def mergeFile(oPath, oSha, oMode, aPath, aSha, aMode, bPath, bSha, bMode, os.unlink(src1) os.unlink(src2) - merge = MERGE_3WAY clean = (code == 0) else: assert(stat.S_ISLNK(aMode) and stat.S_ISLNK(bMode)) @@ -590,7 +586,7 @@ def processRenames(renamesA, renamesB, branchNameA, branchNameB): if merge or not clean: print 'Renaming', fmtRename(path, ren1.dstName) - if merge == MERGE_3WAY: + if merge: print 'Auto-merging', ren1.dstName if not clean: @@ -668,7 +664,7 @@ def processRenames(renamesA, renamesB, branchNameA, branchNameB): if merge or not clean: print 'Renaming', fmtRename(ren1.srcName, ren1.dstName) - if merge == MERGE_3WAY: + if merge: print 'Auto-merging', ren1.dstName if not clean: From 186f855fc639f2063e5f02abc75ca39464a35500 Mon Sep 17 00:00:00 2001 From: Fredrik Kuivinen Date: Wed, 9 Nov 2005 11:42:57 +0100 Subject: [PATCH 18/22] merge-recursive: Fix support for branch names containing slashes A branch name could have a slash in it. Signed-off-by: Fredrik Kuivinen Signed-off-by: Junio C Hamano --- git-merge-recursive.py | 1 + 1 file changed, 1 insertion(+) diff --git a/git-merge-recursive.py b/git-merge-recursive.py index 36578754c..90e889c30 100755 --- a/git-merge-recursive.py +++ b/git-merge-recursive.py @@ -295,6 +295,7 @@ def fileExists(path): else: raise + branch = branch.replace('/', '_') newPath = path + '_' + branch suffix = 0 while newPath in currentFileSet or \ From c44922a7817398d63bb2b46dc599bd05c710e746 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Nov 2005 12:40:03 -0800 Subject: [PATCH 19/22] Update INSTALL Explicitly mention how to install by hand in build-as-user and install-as-root steps. Signed-off-by: Junio C Hamano --- INSTALL | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/INSTALL b/INSTALL index bbb13f3fd..06b11e104 100644 --- a/INSTALL +++ b/INSTALL @@ -5,10 +5,13 @@ Normally you can just do "make" followed by "make install", and that will install the git programs in your own ~/bin/ directory. If you want to do a global install, you can do - make prefix=/usr install + $ make prefix=/usr ;# as yourself + # make prefix=/usr install ;# as root -(or prefix=/usr/local, of course). Some day somebody may send me a RPM -spec file or something, and you can do "make rpm" or whatever. +(or prefix=/usr/local, of course). Just like any program suite +that uses $prefix, the built results have some paths encoded, +which are derived from $prefix, so "make all; make prefix=/usr +install" would not work. Issues of note: From ff36de0847768873cc793afd6378d3b229591436 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Nov 2005 14:59:23 -0800 Subject: [PATCH 20/22] git-apply: do not fail on binary diff when not applying nor checking. We run git-apply with --stat and --summary at the end of the pull by default, which causes it to barf when the pull brought in changes to binary files. Just mark them as binary patch and proceed when not applying nor checking. [jc: I almost missed --check until I saw Linus did something similar.] Signed-off-by: Junio C Hamano --- apply.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/apply.c b/apply.c index 3e53b3438..cf8aa87a2 100644 --- a/apply.c +++ b/apply.c @@ -53,7 +53,7 @@ struct fragment { struct patch { char *new_name, *old_name, *def_name; unsigned int old_mode, new_mode; - int is_rename, is_copy, is_new, is_delete; + int is_rename, is_copy, is_new, is_delete, is_binary; int lines_added, lines_deleted; int score; struct fragment *fragments; @@ -890,8 +890,18 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch) patchsize = parse_single_patch(buffer + offset + hdrsize, size - offset - hdrsize, patch); - if (!patchsize && !metadata_changes(patch)) - die("patch with only garbage at line %d", linenr); + if (!patchsize && !metadata_changes(patch)) { + static const char binhdr[] = "Binary files "; + + if (sizeof(binhdr) - 1 < size - offset - hdrsize && + !memcmp(binhdr, buffer + hdrsize, sizeof(binhdr)-1)) + patch->is_binary = 1; + + if (patch->is_binary && !apply && !check) + ; + else + die("patch with only garbage at line %d", linenr); + } return offset + hdrsize + patchsize; } @@ -949,9 +959,12 @@ static void show_stats(struct patch *patch) add = (add * max + max_change / 2) / max_change; del = total - add; } - printf(" %s%-*s |%5d %.*s%.*s\n", prefix, - len, name, patch->lines_added + patch->lines_deleted, - add, pluses, del, minuses); + if (patch->is_binary) + printf(" %s%-*s | Bin\n", prefix, len, name); + else + printf(" %s%-*s |%5d %.*s%.*s\n", prefix, + len, name, patch->lines_added + patch->lines_deleted, + add, pluses, del, minuses); if (qname) free(qname); } From 13956670a7baf4b3b794a2cc799bd501753f1746 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Nov 2005 18:54:14 -0800 Subject: [PATCH 21/22] Use 'merge-base --all' where applicable. It may get extra merge base on truly pathological commit histories, but is a lot easier to understand, explain, and prove correctness. Signed-off-by: Junio C Hamano --- git-merge.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/git-merge.sh b/git-merge.sh index b810fceaf..7f481e4ca 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -110,7 +110,14 @@ do die "$remote - not something we can merge" done -common=$(git-show-branch --merge-base $head "$@") +case "$#" in +1) + common=$(git-merge-base --all $head "$@") + ;; +*) + common=$(git-show-branch --merge-base $head "$@") + ;; +esac echo "$head" >"$GIT_DIR/ORIG_HEAD" case "$#,$common,$no_commit" in @@ -162,7 +169,7 @@ case "$#,$common,$no_commit" in up_to_date=t for remote do - common_one=$(git-merge-base $head $remote) + common_one=$(git-merge-base --all $head $remote) if test "$common_one" != "$remote" then up_to_date=f From a1c292958f9968565f4048a17196d99fd16fc7ca Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 8 Nov 2005 02:00:31 -0800 Subject: [PATCH 22/22] Make git-recursive the default strategy for git-pull. This does two things: - It changes the hardcoded default merge strategy for two-head git-pull from resolve to recursive. - .git/config file acquires two configuration items. pull.twohead names the strategy for two-head case, and pull.octopus names the strategy for octopus merge. IOW you are paranoid, you can have the following lines in your .git/config file and keep using git-merge-resolve when pulling one remote: [pull] twohead = resolve OTOH, you can say this: [pull] twohead = resolve twohead = recursive to try quicker resolve first, and when it fails, fall back to recursive. Signed-off-by: Junio C Hamano --- git-pull.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/git-pull.sh b/git-pull.sh index 2358af62d..3b875ad43 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -79,10 +79,22 @@ case "$merge_head" in exit 0 ;; ?*' '?*) - strategy_default_args='-s octopus' + var=`git-var -l | sed -ne 's/^pull\.octopus=/-s /p'` + if test '' = "$var" + then + strategy_default_args='-s octopus' + else + strategy_default_args=$var + fi ;; *) - strategy_default_args='-s resolve' + var=`git-var -l | sed -ne 's/^pull\.twohead=/-s /p'` + if test '' = "$var" + then + strategy_default_args='-s recursive' + else + strategy_default_args=$var + fi ;; esac