From fd8fc4ade5c8973b3dca264cc0c26b091982870b Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 2 Mar 2006 12:23:17 -0800 Subject: [PATCH 01/20] git-branch: add -r switch to list refs/remotes/* If we decide to use refs/remotes/, having a convenient way to list them would be nice. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-branch.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/git-branch.sh b/git-branch.sh index 6ac961e6d1..663a3a370c 100755 --- a/git-branch.sh +++ b/git-branch.sh @@ -48,6 +48,12 @@ If you are sure you want to delete it, run 'git branch -D $branch_name'." exit 0 } +ls_remote_branches () { + git-rev-parse --symbolic --all | + sed -ne 's|^refs/\(remotes/\)|\1|p' | + sort +} + force= while case "$#,$1" in 0,*) break ;; *,-*) ;; *) break ;; esac do @@ -56,6 +62,10 @@ do delete_branch "$@" exit ;; + -r) + ls_remote_branches + exit + ;; -f) force="$1" ;; From d5dddccaa0c61c67340efca36237dfa06eccef1c Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Thu, 2 Mar 2006 12:43:51 +0100 Subject: [PATCH 02/20] Fix test case for some sed Some versions of sed lack the "-i" option. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- t/t8001-annotate.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/t/t8001-annotate.sh b/t/t8001-annotate.sh index cae179436c..172908a5b0 100755 --- a/t/t8001-annotate.sh +++ b/t/t8001-annotate.sh @@ -50,7 +50,8 @@ test_expect_success \ test_expect_success \ 'merge-setup part 2' \ 'git checkout -b branch2 master && - sed -i -e "s/2A quick brown/4A quick brown lazy dog/" file && + sed -e "s/2A quick brown/4A quick brown lazy dog/" < file > file.new && + mv file.new file && GIT_AUTHOR_NAME="B2" git commit -a -m "Branch2-1"' test_expect_success \ From 9645da330f10c539a7e8ade6d787c72870812846 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Thu, 2 Mar 2006 17:17:39 +0530 Subject: [PATCH 03/20] gitview: pass the missing argument _show_clicked_cb. In our last update to use the encoding while showing the commit diff we added a new argument to this function. But we missed updating all the callers. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Junio C Hamano --- contrib/gitview/gitview | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview index de9f3f3c72..781badbc5b 100755 --- a/contrib/gitview/gitview +++ b/contrib/gitview/gitview @@ -798,7 +798,7 @@ class GitView: button.set_relief(gtk.RELIEF_NONE) button.set_sensitive(True) button.connect("clicked", self._show_clicked_cb, - child_id, commit.commit_sha1) + child_id, commit.commit_sha1, self.encoding) hbox.pack_start(button, expand=False, fill=True) button.show() From c7569b1e0009e0187ce9f87f23699eaa8576b6ee Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Thu, 2 Mar 2006 17:10:49 +0100 Subject: [PATCH 04/20] manpages: insert two missing [verse] markers for multi-line SYNOPSIS Found with: for i in *.txt; do grep -A 2 "SYNOPSIS" "$i" | grep -q "^\[verse\]$" && continue multiline=$(grep -A 3 "SYNOPSIS" "$i" | tail -n 1) test -n "$multiline" && echo "$i: $multiline" done Signed-off-by: Jonas Fonseca Signed-off-by: Junio C Hamano --- Documentation/git-repo-config.txt | 1 + Documentation/git-svnimport.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/Documentation/git-repo-config.txt b/Documentation/git-repo-config.txt index 33fcde452a..00efde5f0f 100644 --- a/Documentation/git-repo-config.txt +++ b/Documentation/git-repo-config.txt @@ -8,6 +8,7 @@ git-repo-config - Get and set options in .git/config. SYNOPSIS -------- +[verse] 'git-repo-config' [type] name [value [value_regex]] 'git-repo-config' [type] --replace-all name [value [value_regex]] 'git-repo-config' [type] --get name [value_regex] diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt index a1588138ea..9d3865719c 100644 --- a/Documentation/git-svnimport.txt +++ b/Documentation/git-svnimport.txt @@ -9,6 +9,7 @@ git-svnimport - Import a SVN repository into git SYNOPSIS -------- +[verse] 'git-svnimport' [ -o ] [ -h ] [ -v ] [ -d | -D ] [ -C ] [ -i ] [ -u ] [-l limit_rev] [ -b branch_subdir ] [ -T trunk_subdir ] [ -t tag_subdir ] From a41c175d6f3e903844131b6dc39da986248c7585 Mon Sep 17 00:00:00 2001 From: Shawn Pearce Date: Thu, 2 Mar 2006 12:21:33 -0500 Subject: [PATCH 05/20] Prevent --index-info from ignoring -z. If git-update-index --index-info -z is used only the first record given to the process will actually be updated as the -z option is ignored until after all index records have been read and processed. This meant that multiple null terminated records were seen as a single record which was lacking a trailing LF, however since the first record ended in a null the C string handling functions ignored the trailing garbage. So --index-info should be required to be the last command line option, much as --stdin is required to be the last command line option. Because --index-info implies --stdin this isn't an issue as the user shouldn't be passing --stdin when also passing --index-info. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- update-index.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/update-index.c b/update-index.c index ce1db38d16..797245ab27 100644 --- a/update-index.c +++ b/update-index.c @@ -577,9 +577,11 @@ int main(int argc, const char **argv) break; } if (!strcmp(path, "--index-info")) { + if (i != argc - 1) + die("--index-info must be at the end"); allow_add = allow_replace = allow_remove = 1; read_index_info(line_termination); - continue; + break; } if (!strcmp(path, "--ignore-missing")) { not_new = 1; From 69f0d91e49dbf3c3942bae125c07ad17f6027f83 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 3 Mar 2006 01:20:07 -0800 Subject: [PATCH 06/20] contrib/git-svn: add -b/--branch switch for branch detection I've said I don't like branches in Subversion, and I still don't. This is a bit more flexible, though, as the argument for -b is any arbitrary git head/tag reference. This makes some things easier: * Importing git history into a brand new SVN branch. * Tracking multiple SVN branches via GIT_SVN_ID, even from multiple repositories. * Adding tags from SVN (still need to use GIT_SVN_ID, though). * Even merge tracking is supported, if and only the heads end up with 100% equivalent tree objects. This is more stricter but more robust and foolproof than parsing commit messages, imho. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- contrib/git-svn/git-svn.perl | 38 ++++++++++++++++++++++++++++++++++++ contrib/git-svn/git-svn.txt | 17 +++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index 0e092c5d3f..1f9a470f0c 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -35,6 +35,7 @@ my $sha1_short = qr/[a-f\d]{6,40}/; my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit, $_find_copies_harder, $_l, $_version, $_upgrade); +my (@_branch_from, %tree_map); GetOptions( 'revision|r=s' => \$_revision, 'no-ignore-externals' => \$_no_ignore_ext, @@ -43,6 +44,7 @@ 'rmdir' => \$_rmdir, 'upgrade' => \$_upgrade, 'help|H|h' => \$_help, + 'branch|b=s' => \@_branch_from, 'find-copies-harder' => \$_find_copies_harder, 'l=i' => \$_l, 'version|V' => \$_version, @@ -831,6 +833,8 @@ sub git_commit { my $uuid = $info->{'Repository UUID'}; defined $uuid or croak "Unable to get Repository UUID\n"; + map_tree_joins() if (@_branch_from && !%tree_map); + # commit parents can be conditionally bound to a particular # svn revision via: "svn_revno=commit_sha1", filter them out here: my @exec_parents; @@ -852,6 +856,17 @@ sub git_commit { git_addremove(); chomp(my $tree = `git-write-tree`); croak if $?; + if (exists $tree_map{$tree}) { + my %seen_parent = map { $_ => 1 } @exec_parents; + foreach (@{$tree_map{$tree}}) { + # MAXPARENT is defined to 16 in commit-tree.c: + if ($seen_parent{$_} || @exec_parents > 16) { + next; + } + push @exec_parents, $_; + $seen_parent{$_} = 1; + } + } my $msg_fh = IO::File->new_tmpfile or croak $!; print $msg_fh $log_msg->{msg}, "\ngit-svn-id: ", "$SVN_URL\@$log_msg->{revision}", @@ -975,6 +990,29 @@ sub check_upgrade_needed { } } +# fills %tree_map with a reverse mapping of trees to commits. Useful +# for finding parents to commit on. +sub map_tree_joins { + foreach my $br (@_branch_from) { + my $pid = open my $pipe, '-|'; + defined $pid or croak $!; + if ($pid == 0) { + exec(qw(git-rev-list --pretty=raw), $br) or croak $?; + } + while (<$pipe>) { + if (/^commit ($sha1)$/o) { + my $commit = $1; + my ($tree) = (<$pipe> =~ /^tree ($sha1)$/o); + unless (defined $tree) { + die "Failed to parse commit $commit\n"; + } + push @{$tree_map{$tree}}, $commit; + } + } + close $pipe or croak $?; + } +} + __END__ Data structures: diff --git a/contrib/git-svn/git-svn.txt b/contrib/git-svn/git-svn.txt index 4102deb381..7306048bff 100644 --- a/contrib/git-svn/git-svn.txt +++ b/contrib/git-svn/git-svn.txt @@ -27,7 +27,7 @@ For importing svn, git-svnimport is potentially more powerful when operating on repositories organized under the recommended trunk/branch/tags structure, and should be faster, too. -git-svn completely ignores the very limited view of branching that +git-svn mostly ignores the very limited view of branching that Subversion has. This allows git-svn to be much easier to use, especially on repositories that are not organized in a manner that git-svnimport is designed for. @@ -116,6 +116,21 @@ OPTIONS They are both passed directly to git-diff-tree see git-diff-tree(1) for more information. +-b:: +--branch :: + Used with 'fetch' or 'commit'. + + This can be used to join arbitrary git branches to remotes/git-svn + on new commits where the tree object is equivalent. + + When used with different GIT_SVN_ID values, tags and branches in + SVN can be tracked this way, as can some merges where the heads + end up having completely equivalent content. This can even be + used to track branches across multiple SVN _repositories_. + + This option may be specified multiple times, once for each + branch. + COMPATIBILITY OPTIONS --------------------- --no-ignore-externals:: From ac8e0b910c722249b4d21dcf99eea2335f48dfe7 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 3 Mar 2006 01:20:07 -0800 Subject: [PATCH 07/20] contrib/git-svn: several small bug fixes and changes * Fixed manually-edited commit messages not going to remotes/git-svn on sequential commits after the sequential commit optimization. * format help correctly after adding 'show-ignore' * sha1_short regexp matches down to 4 hex characters (from git-rev-parse --short documentation) * Print the first line of the commit message when we commit to SVN next to the sha1. * Document 'T' (type change) in the comments Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- contrib/git-svn/git-svn.perl | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index 1f9a470f0c..67368a502b 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -32,7 +32,7 @@ use File::Spec qw//; use POSIX qw/strftime/; my $sha1 = qr/[a-f\d]{40}/; -my $sha1_short = qr/[a-f\d]{6,40}/; +my $sha1_short = qr/[a-f\d]{4,40}/; my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit, $_find_copies_harder, $_l, $_version, $_upgrade); my (@_branch_from, %tree_map); @@ -90,12 +90,12 @@ sub usage { Available commands: foreach (sort keys %cmd) { - print $fd ' ',pack('A10',$_),$cmd{$_}->[1],"\n"; + print $fd ' ',pack('A13',$_),$cmd{$_}->[1],"\n"; } print $fd <<""; \nGIT_SVN_ID may be set in the environment to an arbitrary identifier if you're tracking multiple SVN branches/repositories in one git repository -and want to keep them separate. +and want to keep them separate. See git-svn(1) for more information. exit $exit; } @@ -245,7 +245,7 @@ sub commit { print "Reading from stdin...\n"; @commits = (); while () { - if (/\b([a-f\d]{6,40})\b/) { + if (/\b($sha1_short)\b/) { unshift @commits, $1; } } @@ -267,7 +267,6 @@ sub commit { chdir $SVN_WC or croak $!; my $svn_current_rev = svn_info('.')->{'Last Changed Rev'}; foreach my $c (@revs) { - print "Committing $c\n"; my $mods = svn_checkout_tree($svn_current_rev, $c); if (scalar @$mods == 0) { print "Skipping, no changes detected\n"; @@ -514,7 +513,7 @@ sub svn_checkout_tree { my ($svn_rev, $treeish) = @_; my $from = file_to_s("$REV_DIR/$svn_rev"); assert_svn_wc_clean($svn_rev,$from); - print "diff-tree '$from' '$treeish'\n"; + print "diff-tree $from $treeish\n"; my $pid = open my $diff_fh, '-|'; defined $pid or croak $!; if ($pid == 0) { @@ -525,7 +524,7 @@ sub svn_checkout_tree { } my $mods = parse_diff_tree($diff_fh); unless (@$mods) { - # git can do empty commits, SVN doesn't allow it... + # git can do empty commits, but SVN doesn't allow it... return $mods; } my ($rm, $add) = precommit_check($mods); @@ -612,7 +611,7 @@ sub svn_commit_tree { my ($svn_rev, $commit) = @_; my $commit_msg = "$GIT_DIR/$GIT_SVN/.svn-commit.tmp.$$"; my %log_msg = ( msg => '' ); - open my $msg, '>', $commit_msg or croak $!; + open my $msg, '>', $commit_msg or croak $!; chomp(my $type = `git-cat-file -t $commit`); if ($type eq 'commit') { @@ -627,7 +626,6 @@ sub svn_commit_tree { if (!$in_msg) { $in_msg = 1 if (/^\s*$/); } else { - $log_msg{msg} .= $_; print $msg $_ or croak $!; } } @@ -639,6 +637,15 @@ sub svn_commit_tree { my $editor = $ENV{VISUAL} || $ENV{EDITOR} || 'vi'; system($editor, $commit_msg); } + + # file_to_s removes all trailing newlines, so just use chomp() here: + open $msg, '<', $commit_msg or croak $!; + { local $/; chomp($log_msg{msg} = <$msg>); } + close $msg or croak $!; + + my ($oneline) = ($log_msg{msg} =~ /([^\n\r]+)/); + print "Committing $commit: $oneline\n"; + my @ci_output = safe_qx(qw(svn commit -F),$commit_msg); my ($committed) = grep(/^Committed revision \d+\./,@ci_output); unlink $commit_msg; @@ -1037,7 +1044,7 @@ sub map_tree_joins { mode_a => first column of diff-index output, no leading ':', mode_b => second column of diff-index output, sha1_b => sha1sum of the final blob, - chg => change type [MCRAD], + chg => change type [MCRADT], file_a => original file name of a file (iff chg is 'C' or 'R') file_b => new/current file name of a file (any chg) } From df746c5a81ebe7d7292fe4d1f672d02a5fa6efeb Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 3 Mar 2006 01:20:08 -0800 Subject: [PATCH 08/20] contrib/git-svn: strip 'git-svn-id:' when commiting to SVN We regenerate and use git-svn-id: whenever we fetch or otherwise commit to remotes/git-svn. We don't actually know what revision number we'll commit to SVN at commit time, so this is useless. It won't throw off things like 'rebuild', though, which knows to only use the last instance of git-svn-id: in a log message Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- contrib/git-svn/git-svn.perl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index 67368a502b..edae9d4dae 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -625,6 +625,9 @@ sub svn_commit_tree { while (<$msg_fh>) { if (!$in_msg) { $in_msg = 1 if (/^\s*$/); + } elsif (/^git-svn-id: /) { + # skip this, we regenerate the correct one + # on re-fetch anyways } else { print $msg $_ or croak $!; } From a9612be245dbb642240e8f20c7215186f1d58b6a Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 3 Mar 2006 01:20:08 -0800 Subject: [PATCH 09/20] contrib/git-svn: allow --authors-file to be specified Syntax is compatible with git-svnimport and git-cvsimport: normalperson = Eric Wong If this option is specified and git-svn encounters an SVN committer name that it cannot parse, it git-svn will abort. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- contrib/git-svn/git-svn.perl | 40 ++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index edae9d4dae..c2b4ee9504 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -34,8 +34,8 @@ my $sha1 = qr/[a-f\d]{40}/; my $sha1_short = qr/[a-f\d]{4,40}/; my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit, - $_find_copies_harder, $_l, $_version, $_upgrade); -my (@_branch_from, %tree_map); + $_find_copies_harder, $_l, $_version, $_upgrade, $_authors); +my (@_branch_from, %tree_map, %users); GetOptions( 'revision|r=s' => \$_revision, 'no-ignore-externals' => \$_no_ignore_ext, @@ -46,6 +46,7 @@ 'help|H|h' => \$_help, 'branch|b=s' => \@_branch_from, 'find-copies-harder' => \$_find_copies_harder, + 'authors-file|authors|A=s' => \$_authors, 'l=i' => \$_l, 'version|V' => \$_version, 'no-stop-on-copy' => \$_no_stop_copy ); @@ -73,6 +74,19 @@ last; } } + +# ' = real-name ' mapping based on git-svnimport: +if ($_authors) { + open my $authors, '<', $_authors or die "Can't open $_authors $!\n"; + while (<$authors>) { + chomp; + next unless /^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$/; + my ($user, $name, $email) = ($1, $2, $3); + $users{$user} = [$name, $email]; + } + close $authors or croak $!; +} + usage(0) if $_help; version() if $_version; usage(1) unless (defined $cmd); @@ -740,6 +754,10 @@ sub svn_log_raw { author => $author, lines => $lines, msg => '' ); + if (defined $_authors && ! defined $users{$author}) { + die "Author: $author not defined in ", + "$_authors file\n"; + } push @svn_log, \%log_msg; $state = 'msg_start'; next; @@ -884,12 +902,8 @@ sub git_commit { $msg_fh->flush == 0 or croak $!; seek $msg_fh, 0, 0 or croak $!; - $ENV{GIT_AUTHOR_NAME} = $ENV{GIT_COMMITTER_NAME} = - $log_msg->{author}; - $ENV{GIT_AUTHOR_EMAIL} = $ENV{GIT_COMMITTER_EMAIL} = - $log_msg->{author}."\@$uuid"; - $ENV{GIT_AUTHOR_DATE} = $ENV{GIT_COMMITTER_DATE} = - $log_msg->{date}; + set_commit_env($log_msg, $uuid); + my @exec = ('git-commit-tree',$tree); push @exec, '-p', $_ foreach @exec_parents; open STDIN, '<&', $msg_fh or croak $!; @@ -915,6 +929,16 @@ sub git_commit { return $commit; } +sub set_commit_env { + my ($log_msg, $uuid) = @_; + my $author = $log_msg->{author}; + my ($name,$email) = defined $users{$author} ? @{$users{$author}} + : ($author,"$author\@$uuid"); + $ENV{GIT_AUTHOR_NAME} = $ENV{GIT_COMMITTER_NAME} = $name; + $ENV{GIT_AUTHOR_EMAIL} = $ENV{GIT_COMMITTER_EMAIL} = $email; + $ENV{GIT_AUTHOR_DATE} = $ENV{GIT_COMMITTER_DATE} = $log_msg->{date}; +} + sub apply_mod_line_blob { my $m = shift; if ($m->{mode_b} =~ /^120/) { From eeb0abe0477dd638f52ef82795338edcb49efa2f Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 3 Mar 2006 01:20:08 -0800 Subject: [PATCH 10/20] contrib/git-svn: cleanup option parsing Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- contrib/git-svn/git-svn.perl | 65 +++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index c2b4ee9504..5d547e8c4c 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -24,6 +24,7 @@ # If SVN:: library support is added, please make the dependencies # optional and preserve the capability to use the command-line client. # use eval { require SVN::... } to make it lazy load +# We don't use any modules not in the standard Perl distribution: use Carp qw/croak/; use IO::File qw//; use File::Basename qw/dirname basename/; @@ -37,26 +38,25 @@ $_find_copies_harder, $_l, $_version, $_upgrade, $_authors); my (@_branch_from, %tree_map, %users); -GetOptions( 'revision|r=s' => \$_revision, - 'no-ignore-externals' => \$_no_ignore_ext, - 'stdin|' => \$_stdin, - 'edit|e' => \$_edit, - 'rmdir' => \$_rmdir, - 'upgrade' => \$_upgrade, - 'help|H|h' => \$_help, +my %fc_opts = ( 'no-ignore-externals' => \$_no_ignore_ext, 'branch|b=s' => \@_branch_from, - 'find-copies-harder' => \$_find_copies_harder, - 'authors-file|authors|A=s' => \$_authors, - 'l=i' => \$_l, - 'version|V' => \$_version, - 'no-stop-on-copy' => \$_no_stop_copy ); + 'authors-file|A=s' => \$_authors ); my %cmd = ( - fetch => [ \&fetch, "Download new revisions from SVN" ], - init => [ \&init, "Initialize and fetch (import)"], - commit => [ \&commit, "Commit git revisions to SVN" ], - 'show-ignore' => [ \&show_ignore, "Show svn:ignore listings" ], - rebuild => [ \&rebuild, "Rebuild git-svn metadata (after git clone)" ], - help => [ \&usage, "Show help" ], + fetch => [ \&fetch, "Download new revisions from SVN", + { 'revision|r=s' => \$_revision, %fc_opts } ], + init => [ \&init, "Initialize and fetch (import)", { } ], + commit => [ \&commit, "Commit git revisions to SVN", + { 'stdin|' => \$_stdin, + 'edit|e' => \$_edit, + 'rmdir' => \$_rmdir, + 'find-copies-harder' => \$_find_copies_harder, + 'l=i' => \$_l, + %fc_opts, + } ], + 'show-ignore' => [ \&show_ignore, "Show svn:ignore listings", { } ], + rebuild => [ \&rebuild, "Rebuild git-svn metadata (after git clone)", + { 'no-ignore-externals' => \$_no_ignore_ext, + 'upgrade' => \$_upgrade } ], ); my $cmd; for (my $i = 0; $i < @ARGV; $i++) { @@ -75,21 +75,14 @@ } } -# ' = real-name ' mapping based on git-svnimport: -if ($_authors) { - open my $authors, '<', $_authors or die "Can't open $_authors $!\n"; - while (<$authors>) { - chomp; - next unless /^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$/; - my ($user, $name, $email) = ($1, $2, $3); - $users{$user} = [$name, $email]; - } - close $authors or croak $!; -} +my %opts; +%opts = %{$cmd{$cmd}->[2]} if (defined $cmd); +GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version ) or exit 1; usage(0) if $_help; version() if $_version; -usage(1) unless (defined $cmd); +usage(1) unless defined $cmd; +load_authors() if $_authors; svn_check_ignore_externals(); $cmd{$cmd}->[0]->(@ARGV); exit 0; @@ -1047,6 +1040,18 @@ sub map_tree_joins { } } +# ' = real-name ' mapping based on git-svnimport: +sub load_authors { + open my $authors, '<', $_authors or die "Can't open $_authors $!\n"; + while (<$authors>) { + chomp; + next unless /^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$/; + my ($user, $name, $email) = ($1, $2, $3); + $users{$user} = [$name, $email]; + } + close $authors or croak $!; +} + __END__ Data structures: From 7f60b228601becaa0bca2017521e1f27d5af70b1 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 3 Mar 2006 01:20:09 -0800 Subject: [PATCH 11/20] contrib/git-svn: create a more recent master if one does not exist In a new repository, the initial fetch creates a master branch if one does not exist so HEAD has something to point to. It now creates a master at the end of the initial fetch run, pointing to the latest revision. Previously it pointed to the first revision imported, which is generally less useful. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- contrib/git-svn/git-svn.perl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index 5d547e8c4c..69b6be33e7 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -224,9 +224,6 @@ sub fetch { sys(@svn_co, $SVN_URL, $SVN_WC); chdir $SVN_WC or croak $!; $last_commit = git_commit($base, @parents); - unless (-f "$GIT_DIR/refs/heads/master") { - sys(qw(git-update-ref refs/heads/master),$last_commit); - } assert_svn_wc_clean($base->{revision}, $last_commit); } else { chdir $SVN_WC or croak $!; @@ -242,6 +239,9 @@ sub fetch { $last_commit = git_commit($log_msg, $last_commit, @parents); } assert_svn_wc_clean($last_rev, $last_commit); + unless (-e "$GIT_DIR/refs/heads/master") { + sys(qw(git-update-ref refs/heads/master),$last_commit); + } return pop @$svn_log; } From 1ca72aef45191016e2108855607c9e03b8c93528 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 3 Mar 2006 01:20:09 -0800 Subject: [PATCH 12/20] contrib/git-svn: avoid re-reading the repository uuid, it never changes If it does change, we're screwed anyways as SVN will refuse to commit or update. We also never access more than one SVN repository per-invocation, so we can store it as a global, too. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- contrib/git-svn/git-svn.perl | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index 69b6be33e7..041791b3ce 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -4,7 +4,7 @@ use warnings; use strict; use vars qw/ $AUTHOR $VERSION - $SVN_URL $SVN_INFO $SVN_WC + $SVN_URL $SVN_INFO $SVN_WC $SVN_UUID $GIT_SVN_INDEX $GIT_SVN $GIT_DIR $REV_DIR/; $AUTHOR = 'Eric Wong '; @@ -114,7 +114,6 @@ sub version { sub rebuild { $SVN_URL = shift or undef; - my $repo_uuid; my $newest_rev = 0; if ($_upgrade) { sys('git-update-ref',"refs/remotes/$GIT_SVN","$GIT_SVN-HEAD"); @@ -150,7 +149,7 @@ sub rebuild { # if we merged or otherwise started elsewhere, this is # how we break out of it - next if (defined $repo_uuid && ($uuid ne $repo_uuid)); + next if (defined $SVN_UUID && ($uuid ne $SVN_UUID)); next if (defined $SVN_URL && ($url ne $SVN_URL)); print "r$rev = $c\n"; @@ -159,7 +158,7 @@ sub rebuild { croak "SVN repository location required: $url\n"; } $SVN_URL ||= $url; - $repo_uuid ||= setup_git_svn(); + $SVN_UUID ||= setup_git_svn(); $latest = $rev; } assert_revision_eq_or_unknown($rev, $c); @@ -252,7 +251,7 @@ sub commit { print "Reading from stdin...\n"; @commits = (); while () { - if (/\b($sha1_short)\b/) { + if (/\b($sha1_short)\b/o) { unshift @commits, $1; } } @@ -320,14 +319,14 @@ sub setup_git_svn { mkpath(["$GIT_DIR/$GIT_SVN/info"]); mkpath([$REV_DIR]); s_to_file($SVN_URL,"$GIT_DIR/$GIT_SVN/info/url"); - my $uuid = svn_info($SVN_URL)->{'Repository UUID'} or + $SVN_UUID = svn_info($SVN_URL)->{'Repository UUID'} or croak "Repository UUID unreadable\n"; - s_to_file($uuid,"$GIT_DIR/$GIT_SVN/info/uuid"); + s_to_file($SVN_UUID,"$GIT_DIR/$GIT_SVN/info/uuid"); open my $fd, '>>', "$GIT_DIR/$GIT_SVN/info/exclude" or croak $!; print $fd '.svn',"\n"; close $fd or croak $!; - return $uuid; + return $SVN_UUID; } sub assert_svn_wc_clean { @@ -850,9 +849,7 @@ sub git_commit { my ($log_msg, @parents) = @_; assert_revision_unknown($log_msg->{revision}); my $out_fh = IO::File->new_tmpfile or croak $!; - my $info = svn_info('.'); - my $uuid = $info->{'Repository UUID'}; - defined $uuid or croak "Unable to get Repository UUID\n"; + $SVN_UUID ||= svn_info('.')->{'Repository UUID'}; map_tree_joins() if (@_branch_from && !%tree_map); @@ -891,11 +888,11 @@ sub git_commit { my $msg_fh = IO::File->new_tmpfile or croak $!; print $msg_fh $log_msg->{msg}, "\ngit-svn-id: ", "$SVN_URL\@$log_msg->{revision}", - " $uuid\n" or croak $!; + " $SVN_UUID\n" or croak $!; $msg_fh->flush == 0 or croak $!; seek $msg_fh, 0, 0 or croak $!; - set_commit_env($log_msg, $uuid); + set_commit_env($log_msg); my @exec = ('git-commit-tree',$tree); push @exec, '-p', $_ foreach @exec_parents; @@ -923,10 +920,10 @@ sub git_commit { } sub set_commit_env { - my ($log_msg, $uuid) = @_; + my ($log_msg) = @_; my $author = $log_msg->{author}; my ($name,$email) = defined $users{$author} ? @{$users{$author}} - : ($author,"$author\@$uuid"); + : ($author,"$author\@$SVN_UUID"); $ENV{GIT_AUTHOR_NAME} = $ENV{GIT_COMMITTER_NAME} = $name; $ENV{GIT_AUTHOR_EMAIL} = $ENV{GIT_COMMITTER_EMAIL} = $email; $ENV{GIT_AUTHOR_DATE} = $ENV{GIT_COMMITTER_DATE} = $log_msg->{date}; From 6f0783cf9473feaaadf2ebc59167f84f0b1172bd Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 3 Mar 2006 01:20:09 -0800 Subject: [PATCH 13/20] contrib/git-svn: add --id/-i=$GIT_SVN_ID command-line switch I ended up using GIT_SVN_ID far more than I ever thought I would. Typing less is good. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- contrib/git-svn/git-svn.perl | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index 041791b3ce..db199a3648 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -10,13 +10,6 @@ $AUTHOR = 'Eric Wong '; $VERSION = '0.10.0'; $GIT_DIR = $ENV{GIT_DIR} || "$ENV{PWD}/.git"; -$GIT_SVN = $ENV{GIT_SVN_ID} || 'git-svn'; -$GIT_SVN_INDEX = "$GIT_DIR/$GIT_SVN/index"; -$ENV{GIT_DIR} ||= $GIT_DIR; -$SVN_URL = undef; -$REV_DIR = "$GIT_DIR/$GIT_SVN/revs"; -$SVN_WC = "$GIT_DIR/$GIT_SVN/tree"; - # make sure the svn binary gives consistent output between locales and TZs: $ENV{TZ} = 'UTC'; $ENV{LC_ALL} = 'C'; @@ -78,7 +71,17 @@ my %opts; %opts = %{$cmd{$cmd}->[2]} if (defined $cmd); -GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version ) or exit 1; +GetOptions(%opts, 'help|H|h' => \$_help, + 'version|V' => \$_version, + 'id|i=s' => \$GIT_SVN) or exit 1; + +$GIT_SVN ||= $ENV{GIT_SVN_ID} || 'git-svn'; +$GIT_SVN_INDEX = "$GIT_DIR/$GIT_SVN/index"; +$ENV{GIT_DIR} ||= $GIT_DIR; +$SVN_URL = undef; +$REV_DIR = "$GIT_DIR/$GIT_SVN/revs"; +$SVN_WC = "$GIT_DIR/$GIT_SVN/tree"; + usage(0) if $_help; version() if $_version; usage(1) unless defined $cmd; From 448c81b495a8867297ad491a186371d9dda80515 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 3 Mar 2006 01:20:09 -0800 Subject: [PATCH 14/20] contrib/git-svn: better documenting of CLI switches Also, fix a asciidoc formatting error Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- contrib/git-svn/git-svn.perl | 29 +++++++++++++++-------------- contrib/git-svn/git-svn.txt | 17 ++++++++++++++++- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index db199a3648..808b933993 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -60,16 +60,7 @@ } }; -# we may be called as git-svn-(command), or git-svn(command). -foreach (keys %cmd) { - if (/git\-svn\-?($_)(?:\.\w+)?$/) { - $cmd = $1; - last; - } -} - -my %opts; -%opts = %{$cmd{$cmd}->[2]} if (defined $cmd); +my %opts = %{$cmd{$cmd}->[2]} if (defined $cmd); GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version, @@ -97,15 +88,25 @@ sub usage { print $fd <<""; git-svn - bidirectional operations between a single Subversion tree and git Usage: $0 [options] [arguments]\n -Available commands: + + print $fd "Available commands:\n" unless $cmd; foreach (sort keys %cmd) { + next if $cmd && $cmd ne $_; print $fd ' ',pack('A13',$_),$cmd{$_}->[1],"\n"; + foreach (keys %{$cmd{$_}->[2]}) { + # prints out arguments as they should be passed: + my $x = s#=s$## ? '' : s#=i$## ? '' : ''; + print $fd ' ' x 17, join(', ', map { length $_ > 1 ? + "--$_" : "-$_" } + split /\|/,$_)," $x\n"; + } } print $fd <<""; -\nGIT_SVN_ID may be set in the environment to an arbitrary identifier if -you're tracking multiple SVN branches/repositories in one git repository -and want to keep them separate. See git-svn(1) for more information. +\nGIT_SVN_ID may be set in the environment or via the --id/-i switch to an +arbitrary identifier if you're tracking multiple SVN branches/repositories in +one git repository and want to keep them separate. See git-svn(1) for more +information. exit $exit; } diff --git a/contrib/git-svn/git-svn.txt b/contrib/git-svn/git-svn.txt index 7306048bff..8e9a971a85 100644 --- a/contrib/git-svn/git-svn.txt +++ b/contrib/git-svn/git-svn.txt @@ -116,6 +116,8 @@ OPTIONS They are both passed directly to git-diff-tree see git-diff-tree(1) for more information. +ADVANCED OPTIONS +---------------- -b:: --branch :: Used with 'fetch' or 'commit'. @@ -131,8 +133,21 @@ OPTIONS This option may be specified multiple times, once for each branch. +-i:: +--id :: + This sets GIT_SVN_ID (instead of using the environment). See + the section on "Tracking Multiple Repositories or Branches" for + more information on using GIT_SVN_ID. + COMPATIBILITY OPTIONS --------------------- +--upgrade:: + Only used with the 'rebuild' command. + + Run this if you used an old version of git-svn that used + 'git-svn-HEAD' instead of 'remotes/git-svn' as the branch + for tracking the remote. + --no-ignore-externals:: Only used with the 'fetch' and 'rebuild' command. @@ -177,7 +192,7 @@ Tracking and contributing to an Subversion managed-project: git-svn commit remotes/git-svn..my-branch # Something is committed to SVN, pull the latest into your branch:: git-svn fetch && git pull . remotes/git-svn -# Append svn:ignore settings to the default git exclude file: +# Append svn:ignore settings to the default git exclude file:: git-svn show-ignore >> .git/info/exclude DESIGN PHILOSOPHY From 8e69b31e0da6e5a540a3ca2ca16d59f3411385bc Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 3 Mar 2006 01:28:48 -0800 Subject: [PATCH 15/20] send-email: accept --no-signed-off-by-cc as the documentation states --no-signed-off-cc is still supported, for backwards compatibility Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-send-email.perl b/git-send-email.perl index b0d095b4e9..7c8d51223f 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -54,7 +54,7 @@ "compose" => \$compose, "quiet" => \$quiet, "suppress-from" => \$suppress_from, - "no-signed-off-cc" => \$no_signed_off_cc, + "no-signed-off-cc|no-signed-off-by-cc" => \$no_signed_off_cc, ); # Now, let's fill any that aren't set in with defaults: From 90924d55c5fc4205b2d41821a3288d478aa661a0 Mon Sep 17 00:00:00 2001 From: Josef Weidendorfer Date: Fri, 3 Mar 2006 17:23:32 +0100 Subject: [PATCH 16/20] git-mv: fix moves into a subdir from outside git-mv needs to be run from the base directory so that the check if a file is under revision also covers files outside of a subdirectory. Previously, e.g. in the git repo, cd Documentation; git-mv ../README . produced the error Error: '../README' not under version control The test is extended for this case; it previously only tested one direction. Signed-off-by: Josef Weidendorfer Signed-off-by: Junio C Hamano --- git-mv.perl | 8 ++++++++ t/t7001-mv.sh | 18 ++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/git-mv.perl b/git-mv.perl index fe9c40e1b9..75aa8feeb6 100755 --- a/git-mv.perl +++ b/git-mv.perl @@ -62,9 +62,17 @@ () $dstDir = ""; } +my $subdir_prefix = `git rev-parse --show-prefix`; +chomp($subdir_prefix); + +# run in git base directory, so that git-ls-files lists all revisioned files +chdir "$GIT_DIR/.."; + # normalize paths, needed to compare against versioned files and update-index # also, this is nicer to end-users by doing ".//a/./b/.//./c" ==> "a/b/c" for (@srcArgs, @dstArgs) { + # prepend git prefix as we run from base directory + $_ = $subdir_prefix.$_; s|^\./||; s|/\./|/| while (m|/\./|); s|//+|/|g; diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 43d74c502e..811a4797a5 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -11,17 +11,31 @@ test_expect_success \ git-commit -m add -a' test_expect_success \ - 'moving the file' \ + 'moving the file out of subdirectory' \ 'cd path0 && git-mv COPYING ../path1/COPYING' # in path0 currently test_expect_success \ 'commiting the change' \ - 'cd .. && git-commit -m move -a' + 'cd .. && git-commit -m move-out -a' test_expect_success \ 'checking the commit' \ 'git-diff-tree -r -M --name-status HEAD^ HEAD | \ grep -E "^R100.+path0/COPYING.+path1/COPYING"' +test_expect_success \ + 'moving the file back into subdirectory' \ + 'cd path0 && git-mv ../path1/COPYING COPYING' + +# in path0 currently +test_expect_success \ + 'commiting the change' \ + 'cd .. && git-commit -m move-in -a' + +test_expect_success \ + 'checking the commit' \ + 'git-diff-tree -r -M --name-status HEAD^ HEAD | \ + grep -E "^R100.+path1/COPYING.+path0/COPYING"' + test_done From d51fac53108b1822ba6b3ff8dd2cd242b40eaac5 Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Fri, 3 Mar 2006 11:20:18 +0100 Subject: [PATCH 17/20] workaround fat/ntfs deficiencies for t3600-rm.sh (git-rm) Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- t/t3600-rm.sh | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index cabfadd56d..d1947e11c1 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -8,11 +8,20 @@ test_description='Test of the various options to git-rm.' . ./test-lib.sh # Setup some files to be removed, some with funny characters -touch -- foo bar baz 'space embedded' 'tab embedded' 'newline -embedded' -q -git-add -- foo bar baz 'space embedded' 'tab embedded' 'newline -embedded' -q -git-commit -m "add files" +touch -- foo bar baz 'space embedded' -q +git-add -- foo bar baz 'space embedded' -q +git-commit -m "add normal files" +test_tabs=y +if touch -- 'tab embedded' 'newline +embedded' +then +git-add -- 'tab embedded' 'newline +embedded' +git-commit -m "add files with tabs and newlines" +else + say 'Your filesystem does not allow tabs in filenames.' + test_tabs=n +fi test_expect_success \ 'Pre-check that foo exists and is in index before git-rm foo' \ @@ -42,16 +51,18 @@ test_expect_success \ 'Test that "git-rm -- -q" succeeds (remove a file that looks like an option)' \ 'git-rm -- -q' -test_expect_success \ +test "$test_tabs" = y && test_expect_success \ "Test that \"git-rm -f\" succeeds with embedded space, tab, or newline characters." \ "git-rm -f 'space embedded' 'tab embedded' 'newline embedded'" +if test "$test_tabs" = y; then chmod u-w . test_expect_failure \ 'Test that "git-rm -f" fails if its rm fails' \ 'git-rm -f baz' chmod u+w . +fi test_expect_success \ 'When the rm in "git-rm -f" fails, it should not remove the file from the index' \ From f794c23466c2230b15ebf7ec30e06a390d1832a4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 3 Mar 2006 14:34:40 -0800 Subject: [PATCH 18/20] show-branch --topics: omit more uninteresting commits. When inspecting contents of topic branches for yet-to-be-merged commits, a commit that is in the release/master branch is uninteresting. Previous round still showed them, especially, the ones before a topic branch that was forked from the release/master later than other topic branches. Signed-off-by: Junio C Hamano --- show-branch.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/show-branch.c b/show-branch.c index 452e63f786..24efb65e62 100644 --- a/show-branch.c +++ b/show-branch.c @@ -727,24 +727,16 @@ int main(int ac, char **av) while (seen) { struct commit *commit = pop_one_commit(&seen); int this_flag = commit->object.flags; + int is_merge_point = ((this_flag & all_revs) == all_revs); - shown_merge_point |= ((this_flag & all_revs) == all_revs); + shown_merge_point |= is_merge_point; if (1 < num_rev) { int is_merge = !!(commit->parents && commit->parents->next); - if (topics) { - int interesting = 0; - for (i = 1; i < num_rev; i++) { - if ((this_flag & - (1u << (i + REV_SHIFT)))) { - interesting = 1; - break; - } - } - if (!interesting) - continue; - } - + if (topics && + !is_merge_point && + (this_flag & (1u << REV_SHIFT))) + continue; for (i = 0; i < num_rev; i++) { int mark; From ce4c8b24a1efcf155c076d54a7e239251504f669 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 3 Mar 2006 13:35:48 -0800 Subject: [PATCH 19/20] contrib/git-svn: fix a copied-tree bug in an overzealous assertion I thought passing --stop-on-copy to svn would save us from all the trouble svn-arch-mirror had with directory (project) copies. I was wrong, there was one thing I overlooked. If a tree was moved from /foo/trunk to /bar/foo/trunk with no other changes in r10, but the last change was done in r5, the Last Changed Rev (from svn info) in /bar/foo/trunk will still be r5, even though the copy in the repository didn't exist until r10. Now, if we ever detect that the Last Changed Rev isn't what we're expecting, we'll run svn diff and only croak if there are differences between them. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- contrib/git-svn/git-svn.perl | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index 808b933993..3c860e458c 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -337,10 +337,17 @@ sub assert_svn_wc_clean { my ($svn_rev, $treeish) = @_; croak "$svn_rev is not an integer!\n" unless ($svn_rev =~ /^\d+$/); croak "$treeish is not a sha1!\n" unless ($treeish =~ /^$sha1$/o); - my $svn_info = svn_info('.'); - if ($svn_rev != $svn_info->{'Last Changed Rev'}) { - croak "Expected r$svn_rev, got r", - $svn_info->{'Last Changed Rev'},"\n"; + my $lcr = svn_info('.')->{'Last Changed Rev'}; + if ($svn_rev != $lcr) { + print STDERR "Checking for copy-tree ... "; + # use + my @diff = grep(/^Index: /,(safe_qx(qw(svn diff), + "-r$lcr:$svn_rev"))); + if (@diff) { + croak "Nope! Expected r$svn_rev, got r$lcr\n"; + } else { + print STDERR "OK!\n"; + } } my @status = grep(!/^Performing status on external/,(`svn status`)); @status = grep(!/^\s*$/,@status); From c6d4217ebc15aea283050d816f3c616eebb9f477 Mon Sep 17 00:00:00 2001 From: "Luck, Tony" Date: Thu, 2 Mar 2006 15:27:31 -0800 Subject: [PATCH 20/20] annotate should number lines starting with 1 C programmers are well used to counting from zero, but every other text file tool starts counting from 1. Signed-off-by: Tony Luck Signed-off-by: Junio C Hamano --- git-annotate.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-annotate.perl b/git-annotate.perl index 08d479f4b9..d93ee19c7e 100755 --- a/git-annotate.perl +++ b/git-annotate.perl @@ -128,7 +128,7 @@ () } printf("%s\t(%10s\t%10s\t%d)%s\n", $rev, $committer, - format_date($date), $i++, $output); + format_date($date), ++$i, $output); } sub init_claim {