Reputation: 782
My git-svn work flow is as follows:
Production code goes in master, off which I do my git svn dcommits/rebase. I work on feature/topic branches, and continue to rebase -i to master and merge until I'm ready to bring those into master and subsequently push to svn trunk using dcommit.
I can usually do git checkout -
to checkout the previous branch I was on.
For some reason though, when I do git svn rebase
, and then try to git checkout to my previous branch, it does not work (it just stays in master). That is, lets say I do:
(master)$ git checkout -b my-feature-branch
I do some work on that branch, then commit
(my-feature-branch)$ git commit -am "Some work"
I then want to bring in the latest changes, and the quickly change back to my branch:
(my-feature-branch)$ git checkout master
(master)$ git svn rebase
This brings in the latest svn trunk changes into master. Now I just want to quickly change back to my topic branch.
(master)$ git checkout -
At this point, the branch checkout stays as master. I'm guessing some sort of operation is popping off the last branch I worked on, but I don't know about the internals to know this for sure.
So my question is, does anyone know why this is?
Upvotes: 2
Views: 144
Reputation: 311635
When you run git checkout -
, git
consults the file .git/logs/HEAD
to find the last branch that you checked out.
When you run git svn rebase
, this triggers the cmd_rebase
function in the git-svn
command, which in turns calls:
command_noisy(rebase_cmd(), $gs->refname);
This calls rebase_cmd
, which looks like this:
sub rebase_cmd {
my @cmd = qw/rebase/;
push @cmd, '-v' if $_verbose;
push @cmd, qw/--merge/ if $_merge;
push @cmd, "--strategy=$_strategy" if $_strategy;
push @cmd, "--preserve-merges" if $_preserve_merges;
@cmd;
}
So the git
command line built by this chain looks something like:
git rebase $gs->refname
(where $gs->refname
would be substitute with a branch name.) And from the git-rebase
man page:
If <branch> is specified, git rebase will perform an automatic git checkout before doing anything else. Otherwise it remains on the current branch.
Since the rebase
command specifies a branch name, rebase
performs a checkout, which appends an entry to .git/logs/HEAD
even if you are already on that branch. This is why the target of git checkout -
is not what you expect after running git svn rebase
.
UPDATE I may be wrong about why rebase is performing the checkout, but if you examine .git/logs/HEAD
you can see clearly that rebase is performing (multiple) checkouts. For example, if I have a branch master
and a branch b1
(descended from master
), and then do:
git checkout master
git rebase b1
I end up with the following in the the log:
6240c11... c4bfd14... Lars Kellogg-Stedman <[email protected]>
1352952244 -0500 checkout: moving from b1 to master
c4bfd14... 6240c11... Lars Kellogg-Stedman <[email protected]>
1352952260 -0500 checkout: moving from master to 6240c1154706c675d19d771ad36aebc2658a5df8^0
6240c11... 6240c11... Lars Kellogg-Stedman <[email protected]>
1352952260 -0500 rebase finished: returning to refs/heads/master
Upvotes: 1
Reputation: 4772
This actually doesn't seem to have anything to do with git-svn, and is just a side-effect of rebasing in git. A git rebase
seems to imply re-checking out the current branch. To prove this to your self, use the following commands:
$ git checkout master
$ git checkout HEAD~1
# A bunch of stuff about being in detached HEAD mode.
$ git checkout -b foo
$ git rebase master
$ git checkout -
Already on 'foo'
This is because git rebase
detaches HEAD using git checkout -q "$onto^0"
. If you check .git/logs/HEAD after running the above commands, you'll see entries that state "moving from foo to 876AF98", followed by "rebase finished: returning to refs/heads/foo".
Upvotes: 1