From 006ede5e860717ff1ec68125393bcd4e74507e5b Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 8 Dec 2006 01:55:19 -0800 Subject: [PATCH 01/10] git-svn: extra error check to ensure we open a file correctly This may be an issue with repositories imported with commit 27a1a8014b842c0d70fdc91c68dd361ca2dfb34c or later, but before commit dad73c0bb9f33323ec1aacf560a6263f1d85f81a. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/git-svn.perl b/git-svn.perl index 747daf0181..ff61b9201f 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3438,6 +3438,9 @@ sub open_file { my ($self, $path, $pb, $rev) = @_; my ($mode, $blob) = (safe_qx('git-ls-tree',$self->{c},'--',$path) =~ /^(\d{6}) blob ([a-f\d]{40})\t/); + unless (defined $mode && defined $blob) { + die "$path was not found in commit $self->{c} (r$rev)\n"; + } { path => $path, mode_a => $mode, mode_b => $mode, blob => $blob, pool => SVN::Pool->new, action => 'M' }; } From bbee1d971dc07c29f840b439aa2a2c890a12cf9f Mon Sep 17 00:00:00 2001 From: Uwe Zeisberger Date: Fri, 8 Dec 2006 12:44:31 +0100 Subject: [PATCH 02/10] Fix documentation copy&paste typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was introduced in 45a3b12cfd3eaa05bbb0954790d5be5b8240a7b5 Signed-off-by: Uwe Kleine-K,AC6(Bnig Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 61e2ab2900..5ea3fda540 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -120,7 +120,7 @@ our %feature = ( # To disable system wide have in $GITWEB_CONFIG # $feature{'snapshot'}{'default'} = [undef]; # To have project specific config enable override in $GITWEB_CONFIG - # $feature{'blame'}{'override'} = 1; + # $feature{'snapshot'}{'override'} = 1; # and in project config gitweb.snapshot = none|gzip|bzip2; 'snapshot' => { 'sub' => \&feature_snapshot, From a552db3a64464f1b514b074fbc43aaf599106087 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 8 Dec 2006 02:20:17 -0800 Subject: [PATCH 03/10] git-svn: use do_switch for --follow-parent if the SVN library supports it do_switch works with the SVN Perl bindings after r22312 in the Subversion trunk. Since no released version of SVN currently supports it; we'll just autodetect it and enable its usage when a user has a recent-enough version of SVN. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/git-svn.perl b/git-svn.perl index ff61b9201f..1f8a3b0e07 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -72,7 +72,7 @@ my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit, $_username, $_config_dir, $_no_auth_cache, $_xfer_delta, $_pager, $_color); my (@_branch_from, %tree_map, %users, %rusers, %equiv); -my ($_svn_co_url_revs, $_svn_pg_peg_revs); +my ($_svn_co_url_revs, $_svn_pg_peg_revs, $_svn_can_do_switch); my @repo_path_split_cache; my %fc_opts = ( 'no-ignore-externals' => \$_no_ignore_ext, @@ -2877,6 +2877,24 @@ sub libsvn_connect { return $ra; } +sub libsvn_can_do_switch { + unless (defined $_svn_can_do_switch) { + my $pool = SVN::Pool->new; + my $rep = eval { + $SVN->do_switch(1, '', 0, $SVN->{url}, + SVN::Delta::Editor->new, $pool); + }; + if ($@) { + $_svn_can_do_switch = 0; + } else { + $rep->abort_report($pool); + $_svn_can_do_switch = 1; + } + $pool->clear; + } + $_svn_can_do_switch; +} + sub libsvn_dup_ra { my ($ra) = @_; SVN::Ra->new(map { $_ => $ra->{$_} } qw/config url @@ -3198,12 +3216,26 @@ sub libsvn_find_parent_branch { unlink $GIT_SVN_INDEX; print STDERR "Found branch parent: ($GIT_SVN) $parent\n"; sys(qw/git-read-tree/, $parent); - # I can't seem to get do_switch() to work correctly with - # the SWIG interface (TypeError when passing switch_url...), - # so we'll unconditionally bypass the delta interface here - # for now - return libsvn_fetch_full($parent, $paths, $rev, - $author, $date, $msg); + unless (libsvn_can_do_switch()) { + return libsvn_fetch_full($parent, $paths, $rev, + $author, $date, $msg); + } + # do_switch works with svn/trunk >= r22312, but that is not + # included with SVN 1.4.2 (the latest version at the moment), + # so we can't rely on it. + my $ra = libsvn_connect("$url/$branch_from"); + my $ed = SVN::Git::Fetcher->new({c => $parent, q => $_q}); + my $pool = SVN::Pool->new; + my $reporter = $ra->do_switch($rev, '', 1, $SVN->{url}, + $ed, $pool); + my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : (); + $reporter->set_path('', $r0, 0, @lock, $pool); + $reporter->finish_report($pool); + $pool->clear; + unless ($ed->{git_commit_ok}) { + die "SVN connection failed somewhere...\n"; + } + return libsvn_log_entry($rev, $author, $date, $msg, [$parent]); } print STDERR "Nope, branch point not imported or unknown\n"; return undef; From 2cdf87ebd9976d98d544669d94b111fea731d2ba Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 8 Dec 2006 14:07:45 -0800 Subject: [PATCH 04/10] Fix perl/ build. An earlier commit f848718a broke the build in perl/ directory by allowing the Makefile.PL to overwrite the now-tracked Makefile. Fix this by forcing Makefile.PL to produce its output in perl.mak as the broken commit originally intended. Signed-off-by: Junio C Hamano --- perl/Makefile | 2 +- perl/Makefile.PL | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/perl/Makefile b/perl/Makefile index bd483b0997..099beda873 100644 --- a/perl/Makefile +++ b/perl/Makefile @@ -29,7 +29,7 @@ $(makfile): ../GIT-CFLAGS Makefile echo ' echo $(instdir_SQ)' >> $@ else $(makfile): Makefile.PL ../GIT-CFLAGS - '$(PERL_PATH_SQ)' $< FIRST_MAKEFILE='$@' PREFIX='$(prefix_SQ)' + '$(PERL_PATH_SQ)' $< PREFIX='$(prefix_SQ)' endif # this is just added comfort for calling make directly in perl dir diff --git a/perl/Makefile.PL b/perl/Makefile.PL index de73235e4c..41687757a7 100644 --- a/perl/Makefile.PL +++ b/perl/Makefile.PL @@ -24,5 +24,6 @@ WriteMakefile( NAME => 'Git', VERSION_FROM => 'Git.pm', PM => \%pm, + MAKEFILE => 'perl.mak', %extra ); From 62b339a544b1fa5199de7571c460d770cb286e65 Mon Sep 17 00:00:00 2001 From: Josef Weidendorfer Date: Sat, 9 Dec 2006 02:28:26 +0100 Subject: [PATCH 05/10] Add branch.*.merge warning and documentation update This patch clarifies the meaning of the branch.*.merge option. Previously, if branch.*.merge was specified but did not match any ref, the message "No changes." was not really helpful regarding the misconfiguration. This patch adds a warning for this. Signed-off-by: Josef Weidendorfer Signed-off-by: Junio C Hamano --- Documentation/config.txt | 11 +++++++++-- git-parse-remote.sh | 11 +++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 9090762819..21ec55797b 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -125,10 +125,17 @@ apply.whitespace:: branch..remote:: When in branch , it tells `git fetch` which remote to fetch. + If this option is not given, `git fetch` defaults to remote "origin". branch..merge:: - When in branch , it tells `git fetch` the default remote branch - to be merged. + When in branch , it tells `git fetch` the default refspec to + be marked for merging in FETCH_HEAD. The value has exactly to match + a remote part of one of the refspecs which are fetched from the remote + given by "branch..remote". + The merge information is used by `git pull` (which at first calls + `git fetch`) to lookup the default branch for merging. Without + this option, `git pull` defaults to merge the first refspec fetched. + Specify multiple values to get an octopus merge. pager.color:: A boolean to enable/disable colored output when the pager is in diff --git a/git-parse-remote.sh b/git-parse-remote.sh index da064a53f6..6ae534bf89 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -134,6 +134,8 @@ canon_refs_list_for_fetch () { # or the first one otherwise; add prefix . to the rest # to prevent the secondary branches to be merged by default. merge_branches= + found_mergeref= + curr_branch= if test "$1" = "-d" then shift ; remote="$1" ; shift @@ -171,6 +173,10 @@ canon_refs_list_for_fetch () { dot_prefix= && break done fi + if test -z $dot_prefix + then + found_mergeref=true + fi case "$remote" in '') remote=HEAD ;; refs/heads/* | refs/tags/* | refs/remotes/*) ;; @@ -191,6 +197,11 @@ canon_refs_list_for_fetch () { fi echo "${dot_prefix}${force}${remote}:${local}" done + if test -z "$found_mergeref" -a "$curr_branch" + then + echo >&2 "Warning: No merge candidate found because value of config option + \"branch.${curr_branch}.merge\" does not match any remote branch fetched." + fi } # Returns list of src: (no store), or src:dst (store) From 90ffefe564cd849f88b1d1b5817eb25e3d57521b Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 8 Dec 2006 23:04:21 -0500 Subject: [PATCH 06/10] shortlog: fix segfault on empty authorname The old code looked backwards from the email address to parse the name, allowing an arbitrary number of spaces between the two. However, in the case of no name, we looked back too far to the 'author' (or 'Author:') header. Instead, remove at most one space between name and address. The bug was triggered by commit febf7ea4bed from linux-2.6. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builtin-shortlog.c b/builtin-shortlog.c index f1124e261b..7a2ddfe797 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -188,7 +188,7 @@ static void read_from_stdin(struct path_list *list) bob = buffer + strlen(buffer); else { offset = 8; - while (isspace(bob[-1])) + if (isspace(bob[-1])) bob--; } @@ -236,7 +236,7 @@ static void get_from_rev(struct rev_info *rev, struct path_list *list) author = scratch; authorlen = strlen(scratch); } else { - while (bracket[-1] == ' ') + if (bracket[-1] == ' ') bracket--; author = buffer + 7; From 4cfeccc75d6ab1ccc433770bac6bf3b15ab486d6 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 8 Dec 2006 22:58:50 -0500 Subject: [PATCH 07/10] Documentation: simpler shared repository creation Take Johannes Schindelin's suggestions for a further simplification of the shared repository creation using git --bare init-db --shared, and for a simplified cvsimport using an existing CVS working directory. Also insert more man page references. Signed-off-by: J. Bruce Fields cvs-migration.txt | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) Signed-off-by: Junio C Hamano --- Documentation/cvs-migration.txt | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Documentation/cvs-migration.txt b/Documentation/cvs-migration.txt index 47846bdab2..b657f4589f 100644 --- a/Documentation/cvs-migration.txt +++ b/Documentation/cvs-migration.txt @@ -43,8 +43,8 @@ Pull: refs/heads/master:refs/remotes/origin/master ------------ ================================ -You can update the shared repository with your changes by first commiting -your changes, and then using: +You can update the shared repository with your changes by first committing +your changes, and then using the gitlink:git-push[1] command: ------------------------------------------------ $ git push origin master @@ -76,11 +76,15 @@ possibly created from scratch or from a tarball (see the link:tutorial.html[tutorial]), or imported from an already existing CVS repository (see the next section). -If your project's working directory is /home/alice/myproject, you can -create a shared repository at /pub/repo.git with: +Assume your existing repo is at /home/alice/myproject. Create a new "bare" +repository (a repository without a working tree) and fetch your project into +it: ------------------------------------------------ -$ git clone -bare /home/alice/myproject /pub/repo.git +$ mkdir /pub/my-repo.git +$ cd /pub/my-repo.git +$ git --bare init-db --shared +$ git --bare fetch /home/alice/myproject master:master ------------------------------------------------ Next, give every team member read/write access to this repository. One @@ -93,10 +97,7 @@ Put all the committers in the same group, and make the repository writable by that group: ------------------------------------------------ -$ cd /pub -$ chgrp -R $group repo.git -$ find repo.git -mindepth 1 -type d |xargs chmod ug+rwx,g+s -$ GIT_DIR=repo.git git repo-config core.sharedrepository true +$ chgrp -R $group /pub/my-repo.git ------------------------------------------------ Make sure committers have a umask of at most 027, so that the directories @@ -107,15 +108,15 @@ Importing a CVS archive First, install version 2.1 or higher of cvsps from link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make -sure it is in your path. The magic command line is then +sure it is in your path. Then cd to a checked out CVS working directory +of the project you are interested in and run gitlink:git-cvsimport[1]: ------------------------------------------- -$ git cvsimport -v -d -C +$ git cvsimport -C ------------------------------------------- This puts a git archive of the named CVS module in the directory -, which will be created if necessary. The -v option makes -the conversion script very chatty. +, which will be created if necessary. The import checks out from CVS every revision of every file. Reportedly cvsimport can average some twenty revisions per second, so for a From d9671b75ad3bbf2f95f11a8571e9beaa12ccf6dd Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 8 Dec 2006 13:29:55 -0800 Subject: [PATCH 08/10] rerere: add clear, diff, and status commands git-am and git-rebase will be updated to use 'clear', and diff/status can be used to aid the user in tracking progress in the resolution process. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- Documentation/git-rerere.txt | 27 +++++++++++++++++++++++++-- git-rerere.perl | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt index 8b6b651237..22494b2b2e 100644 --- a/Documentation/git-rerere.txt +++ b/Documentation/git-rerere.txt @@ -7,8 +7,7 @@ git-rerere - Reuse recorded resolve SYNOPSIS -------- -'git-rerere' - +'git-rerere' [clear|diff|status] DESCRIPTION ----------- @@ -167,6 +166,30 @@ would conflict the same way the test merge you resolved earlier. `git-rerere` is run by `git rebase` to help you resolve this conflict. +COMMANDS +-------- + +Normally, git-rerere is run without arguments or user-intervention. +However, it has several commands that allow it to interact with +its working state. + +'clear':: + +This resets the metadata used by rerere if a merge resolution is to be +is aborted. Calling gitlink:git-am[1] --skip or gitlink:git-rebase[1] +[--skip|--abort] will automatcally invoke this command. + +'diff':: + +This displays diffs for the current state of the resolution. It is +useful for tracking what has changed while the user is resolving +conflicts. Additional arguments are passed directly to the system +diff(1) command installed in PATH. + +'status':: + +Like diff, but this only prints the filenames that will be tracked +for resolutions. Author ------ diff --git a/git-rerere.perl b/git-rerere.perl index d3664ff491..b2550bb2ef 100755 --- a/git-rerere.perl +++ b/git-rerere.perl @@ -172,6 +172,38 @@ sub merge { -d "$rr_dir" || exit(0); read_rr(); + +if (@ARGV) { + my $arg = shift @ARGV; + if ($arg eq 'clear') { + for my $path (keys %merge_rr) { + my $name = $merge_rr{$path}; + if (-d "$rr_dir/$name" && + ! -f "$rr_dir/$name/postimage") { + rmtree(["$rr_dir/$name"]); + } + } + unlink $merge_rr; + } + elsif ($arg eq 'status') { + for my $path (keys %merge_rr) { + print $path, "\n"; + } + } + elsif ($arg eq 'diff') { + for my $path (keys %merge_rr) { + my $name = $merge_rr{$path}; + system('diff', ((@ARGV == 0) ? ('-u') : @ARGV), + '-L', "a/$path", '-L', "b/$path", + "$rr_dir/$name/preimage", $path); + } + } + else { + die "$0 unknown command: $arg\n"; + } + exit 0; +} + my %conflict = map { $_ => 1 } find_conflict(); # MERGE_RR records paths with conflicts immediately after merge From cda2d3c112a03079af9019c7d6617e65ab88ae7e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 8 Dec 2006 13:03:12 -0800 Subject: [PATCH 09/10] git-rerere: add 'gc' command. Over time, unresolved rr-cache entries are accumulated and they tend to get less and less likely to be useful as the tips of branches advance. Reorder documentation page to show the subcommand section earlier than the discussion section. Signed-off-by: Junio C Hamano --- Documentation/git-rerere.txt | 56 ++++++++++++++++++++---------------- git-rerere.perl | 25 ++++++++++++++++ 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt index 22494b2b2e..116dca4c06 100644 --- a/Documentation/git-rerere.txt +++ b/Documentation/git-rerere.txt @@ -26,6 +26,38 @@ results and applying the previously recorded hand resolution. You need to create `$GIT_DIR/rr-cache` directory to enable this command. + +COMMANDS +-------- + +Normally, git-rerere is run without arguments or user-intervention. +However, it has several commands that allow it to interact with +its working state. + +'clear':: + +This resets the metadata used by rerere if a merge resolution is to be +is aborted. Calling gitlink:git-am[1] --skip or gitlink:git-rebase[1] +[--skip|--abort] will automatcally invoke this command. + +'diff':: + +This displays diffs for the current state of the resolution. It is +useful for tracking what has changed while the user is resolving +conflicts. Additional arguments are passed directly to the system +diff(1) command installed in PATH. + +'status':: + +Like diff, but this only prints the filenames that will be tracked +for resolutions. + +'gc':: + +This command is used to prune records of conflicted merge that +occurred long time ago. + + DISCUSSION ---------- @@ -166,30 +198,6 @@ would conflict the same way the test merge you resolved earlier. `git-rerere` is run by `git rebase` to help you resolve this conflict. -COMMANDS --------- - -Normally, git-rerere is run without arguments or user-intervention. -However, it has several commands that allow it to interact with -its working state. - -'clear':: - -This resets the metadata used by rerere if a merge resolution is to be -is aborted. Calling gitlink:git-am[1] --skip or gitlink:git-rebase[1] -[--skip|--abort] will automatcally invoke this command. - -'diff':: - -This displays diffs for the current state of the resolution. It is -useful for tracking what has changed while the user is resolving -conflicts. Additional arguments are passed directly to the system -diff(1) command installed in PATH. - -'status':: - -Like diff, but this only prints the filenames that will be tracked -for resolutions. Author ------ diff --git a/git-rerere.perl b/git-rerere.perl index b2550bb2ef..61eef575da 100755 --- a/git-rerere.perl +++ b/git-rerere.perl @@ -169,6 +169,28 @@ sub merge { return 0; } +sub garbage_collect_rerere { + # We should allow specifying these from the command line and + # that is why the caller gives @ARGV to us, but I am lazy. + + my $cutoff_noresolve = 15; # two weeks + my $cutoff_resolve = 60; # two months + my @to_remove; + while (<$rr_dir/*/preimage>) { + my ($dir) = /^(.*)\/preimage$/; + my $cutoff = ((-f "$dir/postimage") + ? $cutoff_resolve + : $cutoff_noresolve); + my $age = -M "$_"; + if ($cutoff <= $age) { + push @to_remove, $dir; + } + } + if (@to_remove) { + rmtree(\@to_remove); + } +} + -d "$rr_dir" || exit(0); read_rr(); @@ -198,6 +220,9 @@ if (@ARGV) { "$rr_dir/$name/preimage", $path); } } + elsif ($arg eq 'gc') { + garbage_collect_rerere(@ARGV); + } else { die "$0 unknown command: $arg\n"; } From f131dd492f098f9f565df93df13e35c734284590 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 8 Dec 2006 13:29:56 -0800 Subject: [PATCH 10/10] rerere: record (or avoid misrecording) resolved, skipped or aborted rebase/am Data in rr-cache isn't valid after a patch application is skipped or and aborted, so our next commit could be misrecorded as a resolution of that skipped/failed commit, which is wrong. git-am --skip, git-rebase --skip/--abort will automatically invoke git-rerere clear to avoid this. Also, since git-am --resolved indicates a resolution was succesful, remember to run git-rerere to record the resolution (and not surprise the user when the next commit is made). Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-am.sh | 8 ++++++++ git-rebase.sh | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/git-am.sh b/git-am.sh index afe322b20f..5df6787a3f 100755 --- a/git-am.sh +++ b/git-am.sh @@ -246,6 +246,10 @@ last=`cat "$dotest/last"` this=`cat "$dotest/next"` if test "$skip" = t then + if test -d "$GIT_DIR/rr-cache" + then + git-rerere clear + fi this=`expr "$this" + 1` resume= fi @@ -408,6 +412,10 @@ do stop_here_user_resolve $this fi apply_status=0 + if test -d "$GIT_DIR/rr-cache" + then + git rerere + fi ;; esac diff --git a/git-rebase.sh b/git-rebase.sh index 25530dfdc5..2b4f3477fa 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -139,6 +139,10 @@ do --skip) if test -d "$dotest" then + if test -d "$GIT_DIR/rr-cache" + then + git-rerere clear + fi prev_head="`cat $dotest/prev_head`" end="`cat $dotest/end`" msgnum="`cat $dotest/msgnum`" @@ -157,6 +161,10 @@ do exit ;; --abort) + if test -d "$GIT_DIR/rr-cache" + then + git-rerere clear + fi if test -d "$dotest" then rm -r "$dotest"