Code

GIT 0.99.9g v0.99.9g
authorJunio C Hamano <junkio@cox.net>
Thu, 10 Nov 2005 05:09:43 +0000 (21:09 -0800)
committerJunio C Hamano <junkio@cox.net>
Thu, 10 Nov 2005 05:09:43 +0000 (21:09 -0800)
Another snapshot, as slow and steady marth towards 1.0 continues.
Major changes include:

 - Jim Radford's RPM split.
 - Fredrik's recursive merge strategy is now default for two heads merge.
 - Yaacov's SVN importer updates.

Signed-off-by: Junio C Hamano <junkio@cox.net>
19 files changed:
Documentation/build-docdep.perl
Documentation/git-tag.txt
Documentation/howto/using-topic-branches.txt
INSTALL
Makefile
apply.c
debian/changelog
git-core.spec.in
git-cvsexportcommit.perl
git-merge-recursive.py
git-merge.sh
git-pull.sh
git-svnimport.perl
git-tag.sh
http-fetch.c
http-push.c
t/Makefile
t/t5000-tar-tree.sh
templates/Makefile

index 6ff35e02faf386f103fd691d8ccca346e181614c..489389c32af57d39bb843e2b0621144b38006fa3 100755 (executable)
@@ -22,15 +22,11 @@ my $changed = 1;
 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;
index 3984812cecc4453b4f3fb84f017f3cd4c50751cb..95de436c10d3b43b5c5eac719938005b11ead739 100644 (file)
@@ -8,7 +8,7 @@ git-tag -  Create a tag object signed with GPG
 
 SYNOPSIS
 --------
-'git-tag' [-a | -s | -u <key-id>] [-f] [-m <msg>] <name> [<head>]
+'git-tag' [-a | -s | -u <key-id>] [-f | -d] [-m <msg>] <name> [<head>]
 
 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 <tag>` deletes the tag.
+
 
 Author
 ------
index c6c635a51ee813a9c09b342e2c06a2644b0ac413..4698abe46bff0b878dcfcd05771f5760483b4278 100644 (file)
@@ -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
diff --git a/INSTALL b/INSTALL
index bbb13f3fd98f96af5521226a8cdaf74f8c6732a2..06b11e104c930202be4002f0b98a421c73beedff 100644 (file)
--- 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:
 
index bfdaf762a05adfb020856e27dddce9a4025d5c49..5bd3dedf44bc90277cb9dbf365bc933d9aa8bac0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -50,7 +50,7 @@
 # Define USE_STDEV below if you want git to care about the underlying device
 # change being considered an inode change from the update-cache perspective.
 
-GIT_VERSION = 0.99.9f
+GIT_VERSION = 0.99.9g
 
 # CFLAGS is for the users to override from the command line.
 
diff --git a/apply.c b/apply.c
index 3e53b3438169bcaaf4db97669b062ebe14335fe6..cf8aa87a289bfa534405c461323eae5452c96d1e 100644 (file)
--- 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);
 }
index 03a0f796e4c9d45ac84e0b79dd4dd1e28cace296..e556beb40283b69a0bcc8459a7575872080b80b5 100644 (file)
@@ -1,3 +1,9 @@
+git-core (0.99.9g-0) unstable; urgency=low
+
+  * GIT 0.99.9g
+
+ -- Junio C Hamano <junkio@cox.net>  Wed,  9 Nov 2005 21:01:55 -0800
+
 git-core (0.99.9f-0) unstable; urgency=low
 
   * GIT 0.99.9f
index 5240dd2c296482a7ae5486e7688ef8ca944197e0..26846d0050224fc409ef6f54625a5e37d7e834e9 100644 (file)
@@ -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 <radford@blackbean.org>
+- Move programs with non-standard dependencies (svn, cvs, email)
+  into separate packages
+
 * Tue Sep 27 2005 H. Peter Anvin <hpa@zytor.com>
 - parallelize build
 - COPTS -> CFLAGS
index 7074b0c21b14b0ff358b7ddc9f2b0076fb7ffca4..50b041c3247238f7b399c0648cc7c3bc2a58dba7 100755 (executable)
@@ -64,7 +64,7 @@ if ($parent) {
            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];
index 9983cd9deec120ed376403a3830ad7ad48683516..90e889c300ab16681040c27ab70c43cd741ff8a0 100755 (executable)
@@ -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))
@@ -299,6 +295,7 @@ def uniquePath(path, branch):
             else:
                 raise
 
+    branch = branch.replace('/', '_')
     newPath = path + '_' + branch
     suffix = 0
     while newPath in currentFileSet or \
@@ -590,7 +587,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 +665,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:
index b810fceaf8787f6c450abc628d0a329fe298b13f..7f481e4caacf295635f1fb69c9b4f1c364355234 100755 (executable)
@@ -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
index 2358af62d5eb008ef3d04de67cea7a56aab16526..3b875ad438c21df50c0b1f26bc8fac5ab1bc9740 100755 (executable)
@@ -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
 
index 45b6a1986d1989d372077c5f388010ea988220e6..cb9afb955ccac5dec1494ab5a63c0cb0f868374a 100755 (executable)
@@ -25,7 +25,7 @@ use IPC::Open2;
 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 @@ our($opt_h,$opt_o,$opt_v,$opt_u,$opt_C,$opt_i,$opt_m,$opt_M,$opt_t,$opt_T,$opt_b
 
 sub usage() {
        print STDERR <<END;
-Usage: ${\basename $0}     # fetch/update GIT from CVS
+Usage: ${\basename $0}     # fetch/update GIT from SVN
        [-o branch-for-HEAD] [-h] [-v] [-l max_num_changes]
        [-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]
        [-d|-D] [-i] [-u] [-s start_chg] [-m] [-M regex] [SVN_URL]
@@ -53,7 +53,6 @@ my $branch_name = $opt_b || "branches";
 
 $opt_o ||= "origin";
 $opt_s ||= 1;
-$opt_l = 100 unless defined $opt_l;
 my $git_tree = $opt_C;
 $git_tree ||= ".";
 
@@ -112,7 +111,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 $@;
@@ -258,10 +259,17 @@ EOM
 
 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 "/") {
@@ -272,6 +280,14 @@ sub get_file($$$) {
                $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) {
@@ -319,28 +335,57 @@ sub split_path($$) {
        } 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 "";
        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,$parents) = @_;
 
-       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#/*$#/#;
+       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#/*$#/#;
+       }
+       
        open my $f,"-|","git-ls-tree","-r","-z",$gitrev,$srcpath;
        local $/ = "\0";
        while(<$f>) {
@@ -348,9 +393,12 @@ sub copy_subdir($$$$$$) {
                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";
@@ -359,7 +407,7 @@ sub copy_subdir($$$$$$) {
 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";
@@ -446,6 +494,8 @@ sub commit {
                $last_rev = $rev;
        }
 
+       push (@parents, $rev) if defined $rev;
+
        my $cid;
        if($tag and not %$changed_paths) {
                $cid = $rev;
@@ -454,39 +504,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,\@parents);
+                               } 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";
                        }
@@ -554,7 +596,6 @@ sub commit {
                        $pw->close();
 
                        my @par = ();
-                       @par = ("-p",$rev) if defined $rev;
 
                        # loose detection of merges
                        # based on the commit msg
@@ -564,11 +605,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",
@@ -600,6 +647,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) {
@@ -616,6 +667,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".
@@ -674,13 +726,16 @@ sub commit_all {
 }
 
 while(++$current_rev <= $svn->{'maxrev'}) {
-       $svn->{'svn'}->get_log("/",$current_rev,$current_rev,$current_rev,1,1,\&_commit_all,"");
-       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;
+       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();
 }
 
 
index 6130904a94ddeffb15b1b10ded8336c67112c12e..13759453077b025d7815354c61269c2a9847e68f 100755 (executable)
@@ -4,7 +4,7 @@
 . git-sh-setup || die "Not a git archive"
 
 usage () {
-    echo >&2 "Usage: git-tag [-a | -s | -u <key-id>] [-f] [-m <msg>] <tagname> [<head>]"
+    echo >&2 "Usage: git-tag [-a | -s | -u <key-id>] [-f | -d] [-m <msg>] <tagname> [<head>]"
     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
        ;;
index ea8af1b2defaf7e11dff0a09952234f3c7626376..88b74b434194b0648c21225bac9ecfbe05491a93 100644 (file)
@@ -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;
index 0b90fb9ae3396d0f2b0a9ebf9acad8374f3db317..8866189332568a317183f6f895014519515f67e7 100644 (file)
@@ -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;
index 5c76afff83087ee4d6324699f7ba376c18201716..5c5a62012673eaa7eec76da0068606bc78311fbd 100644 (file)
@@ -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:
+
index 4db1bb11425797b5b105fcb7b92f443616d58355..adc5e937de1a4b28b9556ca00fdfbc95dead70d7 100755 (executable)
@@ -25,6 +25,7 @@ commit id embedding:
 '
 
 . ./test-lib.sh
+TAR=${TAR:-tar}
 
 test_expect_success \
     'populate workdir' \
index 07e928e56dd00678fdbe092b65bd16f7b7edfcc7..8f7f4fec34ad76b85d61f20821f18a1d3ca9a3b2 100644 (file)
@@ -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