47

I have two git branches, "A" and "B", and commits numbered 1 thru 8. My history looks like this

1 -> 2 -> 3 -> 4[A] -> 5 -> 6 -> 7 -> 8[B]

I want to change it so my history looks like this:

1 -> 2 -> 3 -> 4 -> 5 -> 6[A] -> 7 -> 8[B]

That is, I want to move the head of branch A from commit 4 to commit 6.

What commands do I use to do this?

3 Answers 3

58

You can run:

git branch -f A 6
6
  • 1
    This works in this situation because A actually contains nothing; it just points to the branchpoint and so we move the pointer elsewhere without losing anything. Suppose A had some commits? Then you have to do a git rebase to carry over the commits. That is more general and should handle this "empty branch" trivial case too.
    – Kaz
    Commented Mar 19, 2012 at 5:35
  • 9
    @Kaz, git has lightweight branches, so they never "contain" anything. They are just a moving sticky note attached to a commit. My answer is for this scenario, a linear branch history. If it wasn't linear, I would look at what the OP actually wanted and come up with a solution. Commented Mar 19, 2012 at 5:41
  • You could say that about CVS too then. A branch doesn't contain anything. It's just a branch tag ("sticky note") denoting a branch number like 1.2.0.2. Does CVS have light-weight branching? :)
    – Kaz
    Commented Mar 19, 2012 at 6:02
  • i couldn't do this while on branch A, so i went with @ralphtheninja's answer.
    – Jayen
    Commented Aug 7, 2013 at 5:59
  • @Jayen You can still use Matthew's solution, you just have to checkout any other branch first. If A is your only branch, just do git checkout -b temp; git branch -f A 6; git checkout A.
    – Matthew
    Commented Jun 23, 2015 at 22:47
17
git checkout A
git reset --hard 6
1
  • 7
    This works, but is the "hard way". The reason it works is that if you are "on a branch" (in git terms), git reset --hard <rev> moves the branch for you. But git branch -f <name> <rev> re-points the branch in one step. There is one limitation: git branch -f won't let you move your current branch. So if you're already "on branch A" (as shown by git branch output) you need to use this git reset --hard method. (Or get off branch A, but that's getting silly. :-) )
    – torek
    Commented Mar 19, 2012 at 3:00
10

This is a special case of rebase, just that the branch is empty:

git checkout A
git rebase B

rebase is more general; it handles this case also:

Before:

                  A1 -> A2 -> [A]
                /
1 -> 2 -> 3 -> 4  -> 5 -> 6 -> 7 -> 8[B]

After:

                                      A1' -> A2' -> [A]
                                     /
1 -> 2 -> 3 -> 4  -> 5 -> 6 -> 7 -> 8[B]

A1' and A2' are merged to account for the delta between 4 and 8 on the parent branch.

Git rebase handles this trivial case without a hassle. I created a repo with two commits on master and a branch br pointing to the first commit.

$ git checkout br
Switched to branch 'br'
$ git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded br to master.

Poof, done. The log now shows the branch pointing to the second commit.

We can also achieve this "After": [thanks to M. Flaschen for pointing out this was missing]:

                            A1'' -> A2'' -> [A]
                           /
1 -> 2 -> 3 -> 4  -> 5 -> 6 -> 7 -> 8[B]

Instead of rebasing to the branch B, we would name the specific commit 6, e.g.

git checkout A
git rebase 6   # rather than rebase B

When there are no A1 and A2 commits, this reduces to the original question: moving the [A] pointer from 4 to 6.

4
  • The before case does not match the question. In the question, no commits are only on A. Commented Mar 19, 2012 at 5:52
  • The before case is a generalization of the question. A1 and A2 don't exist. An empty list is a list.
    – Kaz
    Commented Mar 19, 2012 at 6:05
  • 1
    Your after case also doesn't match. [A] is pointing to 8, rather than 6. Also, I'm not sure this generalization helps answer the original question. Commented Mar 19, 2012 at 6:14
  • git rebase <commit> works just fine, and by doing that you can move the branch from [4] to [6]`. I will update my response. Whoever modded this down, go stuff yourself. This is the right way to do it using the high level user interface for branch hopping.
    – Kaz
    Commented Mar 19, 2012 at 6:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.