git-svn: add support for --first-parent

When git-svn uses git-log to find embedded 'git-svn-id'-lines in commit
messages, it can get confused when local history contains merges with
other git-svn branches. But if --first-parent is supplied to git-log,
working_head_info() will only see 'branch-local' commits and thus the
first commit containing a 'git-svn-id' line should refer to the correct
subversion branch.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Acked-by: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Lars Hjemli
2007-09-05 11:35:29 +02:00
committed by Junio C Hamano
parent ad00a3b8f8
commit 05b4df3153
2 changed files with 23 additions and 4 deletions

View File

@ -317,6 +317,16 @@ This is only used with the 'dcommit' command.
Print out the series of git arguments that would show Print out the series of git arguments that would show
which diffs would be committed to SVN. which diffs would be committed to SVN.
--first-parent::
This is only used with the 'dcommit', 'rebase', 'log', 'find-rev' and
'show-ignore' commands.
These commands tries to detect the upstream subversion branch by means of
the embedded 'git-svn-id' line in commit messages. When --first-parent is
specified, git-svn only follows the first parent of each commit, effectively
ignoring commits brought into the current branch through merge-operations.
-- --
ADVANCED OPTIONS ADVANCED OPTIONS

View File

@ -59,7 +59,7 @@ my ($_stdin, $_help, $_edit,
$_template, $_shared, $_template, $_shared,
$_version, $_fetch_all, $_no_rebase, $_version, $_fetch_all, $_no_rebase,
$_merge, $_strategy, $_dry_run, $_local, $_merge, $_strategy, $_dry_run, $_local,
$_prefix, $_no_checkout, $_verbose); $_prefix, $_no_checkout, $_verbose, $_first_parent);
$Git::SVN::_follow_parent = 1; $Git::SVN::_follow_parent = 1;
my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username, my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
'config-dir=s' => \$Git::SVN::Ra::config_dir, 'config-dir=s' => \$Git::SVN::Ra::config_dir,
@ -119,12 +119,15 @@ my %cmd = (
'dry-run|n' => \$_dry_run, 'dry-run|n' => \$_dry_run,
'fetch-all|all' => \$_fetch_all, 'fetch-all|all' => \$_fetch_all,
'no-rebase' => \$_no_rebase, 'no-rebase' => \$_no_rebase,
'first-parent' => \$_first_parent,
%cmt_opts, %fc_opts } ], %cmt_opts, %fc_opts } ],
'set-tree' => [ \&cmd_set_tree, 'set-tree' => [ \&cmd_set_tree,
"Set an SVN repository to a git tree-ish", "Set an SVN repository to a git tree-ish",
{ 'stdin|' => \$_stdin, %cmt_opts, %fc_opts, } ], { 'stdin|' => \$_stdin, %cmt_opts, %fc_opts, } ],
'show-ignore' => [ \&cmd_show_ignore, "Show svn:ignore listings", 'show-ignore' => [ \&cmd_show_ignore, "Show svn:ignore listings",
{ 'revision|r=i' => \$_revision } ], { 'revision|r=i' => \$_revision,
'first-parent' => \$_first_parent
} ],
'multi-fetch' => [ \&cmd_multi_fetch, 'multi-fetch' => [ \&cmd_multi_fetch,
"Deprecated alias for $0 fetch --all", "Deprecated alias for $0 fetch --all",
{ 'revision|r=s' => \$_revision, %fc_opts } ], { 'revision|r=s' => \$_revision, %fc_opts } ],
@ -145,15 +148,19 @@ my %cmd = (
'authors-file|A=s' => \$_authors, 'authors-file|A=s' => \$_authors,
'color' => \$Git::SVN::Log::color, 'color' => \$Git::SVN::Log::color,
'pager=s' => \$Git::SVN::Log::pager, 'pager=s' => \$Git::SVN::Log::pager,
'first-parent' => \$_first_parent
} ], } ],
'find-rev' => [ \&cmd_find_rev, "Translate between SVN revision numbers and tree-ish", 'find-rev' => [ \&cmd_find_rev, "Translate between SVN revision numbers and tree-ish",
{ } ], {
'first-parent' => \$_first_parent
} ],
'rebase' => [ \&cmd_rebase, "Fetch and rebase your working directory", 'rebase' => [ \&cmd_rebase, "Fetch and rebase your working directory",
{ 'merge|m|M' => \$_merge, { 'merge|m|M' => \$_merge,
'verbose|v' => \$_verbose, 'verbose|v' => \$_verbose,
'strategy|s=s' => \$_strategy, 'strategy|s=s' => \$_strategy,
'local|l' => \$_local, 'local|l' => \$_local,
'fetch-all|all' => \$_fetch_all, 'fetch-all|all' => \$_fetch_all,
'first-parent' => \$_first_parent,
%fc_opts } ], %fc_opts } ],
'commit-diff' => [ \&cmd_commit_diff, 'commit-diff' => [ \&cmd_commit_diff,
'Commit a diff between two trees', 'Commit a diff between two trees',
@ -811,7 +818,9 @@ sub cmt_metadata {
sub working_head_info { sub working_head_info {
my ($head, $refs) = @_; my ($head, $refs) = @_;
my ($fh, $ctx) = command_output_pipe('log', '--no-color', $head); my @args = ('log', '--no-color');
push @args, '--first-parent' if $_first_parent;
my ($fh, $ctx) = command_output_pipe(@args, $head);
my $hash; my $hash;
my %max; my %max;
while (<$fh>) { while (<$fh>) {