summaryrefslogtreecommitdiff
path: root/git-svn.perl
diff options
context:
space:
mode:
authorThomas Rast <trast@student.ethz.ch>2009-05-29 15:09:42 (GMT)
committerEric Wong <normalperson@yhbt.net>2009-06-25 07:38:16 (GMT)
commit5eec27e35f0a6231d2b0c50d94c726a67f14b23e (patch)
treea62a63ba7a38bde8aa3d0a3164f7a36c95a266a1 /git-svn.perl
parent916e1373fb86db9d7019de4e7e74e39c9474a153 (diff)
downloadgit-5eec27e35f0a6231d2b0c50d94c726a67f14b23e.zip
git-5eec27e35f0a6231d2b0c50d94c726a67f14b23e.tar.gz
git-5eec27e35f0a6231d2b0c50d94c726a67f14b23e.tar.bz2
git-svn: let 'dcommit $rev' work on $rev instead of HEAD
'git svn dcommit' takes an optional revision argument, but the meaning of it was rather scary. It completely ignored the current state of the HEAD, only looking at the revisions between SVN and $rev. If HEAD was attached to $branch, the branch lost all commits $rev..$branch in the process. Considering that 'git svn dcommit HEAD^' has the intuitive meaning "dcommit all changes on my branch except the last one", we change the meaning of the revision argument. git-svn temporarily checks out $rev for its work, meaning that * if a branch is specified, that branch (_not_ the HEAD) is rebased as part of the dcommit, * if some other revision is specified, as in the example, all work happens on a detached HEAD and no branch is affected. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Acked-by: Eric Wong <normalperson@yhbt.net>
Diffstat (limited to 'git-svn.perl')
-rwxr-xr-xgit-svn.perl34
1 files changed, 32 insertions, 2 deletions
diff --git a/git-svn.perl b/git-svn.perl
index 3301797..33fe34c 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -454,8 +454,22 @@ sub cmd_dcommit {
'Cannot dcommit with a dirty index. Commit your changes first, '
. "or stash them with `git stash'.\n";
$head ||= 'HEAD';
+
+ my $old_head;
+ if ($head ne 'HEAD') {
+ $old_head = eval {
+ command_oneline([qw/symbolic-ref -q HEAD/])
+ };
+ if ($old_head) {
+ $old_head =~ s{^refs/heads/}{};
+ } else {
+ $old_head = eval { command_oneline(qw/rev-parse HEAD/) };
+ }
+ command(['checkout', $head], STDERR => 0);
+ }
+
my @refs;
- my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs);
+ my ($url, $rev, $uuid, $gs) = working_head_info('HEAD', \@refs);
unless ($gs) {
die "Unable to determine upstream SVN information from ",
"$head history.\nPerhaps the repository is empty.";
@@ -541,7 +555,7 @@ sub cmd_dcommit {
if (@diff) {
@refs = ();
my ($url_, $rev_, $uuid_, $gs_) =
- working_head_info($head, \@refs);
+ working_head_info('HEAD', \@refs);
my ($linear_refs_, $parents_) =
linearize_history($gs_, \@refs);
if (scalar(@$linear_refs) !=
@@ -579,6 +593,22 @@ sub cmd_dcommit {
}
}
}
+
+ if ($old_head) {
+ my $new_head = command_oneline(qw/rev-parse HEAD/);
+ my $new_is_symbolic = eval {
+ command_oneline(qw/symbolic-ref -q HEAD/);
+ };
+ if ($new_is_symbolic) {
+ print "dcommitted the branch ", $head, "\n";
+ } else {
+ print "dcommitted on a detached HEAD because you gave ",
+ "a revision argument.\n",
+ "The rewritten commit is: ", $new_head, "\n";
+ }
+ command(['checkout', $old_head], STDERR => 0);
+ }
+
unlink $gs->{index};
}