432

I have two (private) feature branches that I'm working on.

a -- b -- c                  <-- Master
     \     \
      \     d -- e           <-- Branch1
       \
        f -- g               <-- Branch2

After working on these branches a little while I've discovered that I need the changes from Branch2 in Branch1. I'd like to rebase the changes in Branch2 onto Branch1. I'd like to end up with the following:

a -- b -- c                  <-- Master
           \
            d -- e -- f -- g <-- Branch1

I'm pretty sure I need to rebase the second branch onto the first, but I'm not entirely sure about the correct syntax and which branch I should have checked out.

Will this command produce the desired result?

(Branch1)$ git rebase --onto Branch1 Branch2
Nir O.
  • 1,563
  • 1
  • 17
  • 26
Arjen
  • 5,043
  • 4
  • 18
  • 20
  • 17
    To answer your question, I would create a test repository, create the commit structure you showed and try the command you showed. But I think you can do that yourself, so I am not going to do it :) – Daniel Hilgarth Feb 15 '13 at 11:19
  • 6
    Thanks. I was so bent on getting this right the first time that it didn't occur to me that I could easily test this myself :-) – Arjen Feb 15 '13 at 11:27
  • 6
    I thought so, that's why I posted that comment :) Everytime I do something I am not sure it will do what I think it does, I create a test repository and perform my tests there. Or, I create a copy of my real repository and perform the tests on the copy. – Daniel Hilgarth Feb 15 '13 at 11:29
  • 2
    Note: Git 2.0 will introduce a shortcut for this kind of rebase: `git rebase -`. see [my answer below](http://stackoverflow.com/a/22830458/6309) – VonC Apr 03 '14 at 07:17
  • 8
    Minor note: The answers here give branch2 as the result. The OP wanted branch1. Or I missed something? – Josef.B Apr 30 '17 at 22:12
  • Edit needed: If you need "changes from Branch2 in Branch1" then you would end up with "a -- b -- c // f -- g -- d -- e" ... you need changes from Branch1 in Branch2? – CLS Dec 07 '22 at 10:57

5 Answers5

482
  1. Switch to Branch2

    git checkout Branch2
    
  2. Apply the current (Branch2) changes on top of the Branch1 changes, staying in Branch2:

    git rebase Branch1
    

Which would leave you with the desired result in Branch2:

a -- b -- c                      <-- Master
           \
            d -- e               <-- Branch1
           \
            d -- e -- f' -- g'   <-- Branch2

You can delete Branch1.

Rafael
  • 7,605
  • 13
  • 31
  • 46
sasikt
  • 5,324
  • 1
  • 17
  • 16
  • Thanks! When deleting the branch after rebasing I get a message that the branch is not fully merged. I assume I can safely ignore this message and force the delete? – Arjen Feb 15 '13 at 11:28
  • It should not show any error if you have rebased properly. Make sure that all your commits in the branch1 which is to be deleted is present in branch2 and delete branch1 – sasikt Feb 15 '13 at 11:38
  • In case Branch1 changes, you will get into conflicts. Before merging them by hand try "git rebase --skip". If you merge those changes by hand by fully accepting all changes made in the Branch1, you would encounter on "git rebase --continue" the message "No changes - did you forget to use 'git add'?". In such case, also issue "git rebase --skip" – Maksymilian Wojakowski Oct 21 '14 at 11:46
  • 32
    didn't he want to have all changes in Branch1? – tomasz_kusmierczyk Mar 23 '18 at 13:45
  • 13
    This seems like the opposite of what he wanted, no? – 1252748 Jul 11 '18 at 19:49
  • 4
    Indeed, @tomasz_kusmierczyk and @1252748, and I got confused myself, too. But then I realized that performing `git rebase` while staying in Branch1 will rewrite Branch1 history to have Branch1's changes on top of those copied from Branch2. That will result in the following commit order, `a - b - f - g - c' - d' - e'`. – eel ghEEz Oct 22 '18 at 19:35
  • 9
    @tomasz_kusmierczyk and 1252748, this is not the opposite of what he want, this is EXACTLY what he wanted. Branch names don't matter, you can always change them. – a3y3 Feb 18 '20 at 22:59
  • 1
    @a3y3 Branch names DO matter. What if you want to rebase a branch that has an open PR? You can't do it using this method, can you? – Nadav Jul 09 '21 at 06:23
71

Note: if you were on Branch1, you will with Git 2.0 (Q2 2014) be able to type:

git checkout Branch2
git rebase -

The - as rebase parameter in this case means 'the branch we were previously on'. See commit 4f40740 by Brian Gesiak modocache:

rebase: allow "-" short-hand for the previous branch

Teach rebase the same shorthand as checkout and merge to name the branch to rebase the current branch on; that is, that "-" means "the branch we were previously on".

Use this feature with caution, as it is less explicit and a small mistake could lead to a messed up state.

mit
  • 11,083
  • 11
  • 50
  • 74
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 58
    nice, but also a bit dangerous. sometimes verbosity wins. but then again, I also like Java... (-: – sthzg Jul 27 '17 at 09:37
23

This solution should do exactly what was asked for (add Branch2's commits on top of Branch1 while staying on Branch1):

git checkout Branch1
git cherry-pick master..Branch2

You'll end up with this.

a -- b -- c                      <-- Master
           \
            d -- e -- f' -- g'   <-- Branch1 (current)
           \
            f -- g               <-- Branch2

This will cherry-pick each of the commits on Branch2 in order onto Branch1. Then you can delete Branch2.

mit
  • 11,083
  • 11
  • 50
  • 74
Asfand Qazi
  • 6,586
  • 4
  • 32
  • 34
  • This is very useful. I had some commits on top of another (local) branch, not yet pushed to git. I used `git cherry-pick mybranch...origin/mybranch` to pick those commits to current branch. – Smar Dec 07 '21 at 14:04
  • This won't work if you're pulling one feature branch into another feature branch. For that, use: `git cherry-pick ..` – Chris Perry Apr 01 '22 at 22:41
11

I know you asked to Rebase, but I'd Cherry-Pick the commits I wanted to move from Branch2 to Branch1 instead. That way, I wouldn't need to care about when which branch was created from master, and I'd have more control over the merging.

a -- b -- c                  <-- Master
     \     \
      \     d -- e -- f -- g <-- Branch1 (Cherry-Pick f & g)
       \
        f -- g               <-- Branch2
Craigo
  • 3,384
  • 30
  • 22
4

Am I misunderstanding this question? My instinct was to use rebase's --onto flag like so:

git rebase --onto branch1 master branch2

Before rebase:

* 6263580 (HEAD -> branch2) add g
* c802c88 add f
| * c80cfb0 (branch1) add e
| * aea5708 add d
| * 2e522fe (master) add c
|/  
* 0613527 add b
* e2a0c4d add a

After rebase:

* 7f6a363 (HEAD -> branch2) add g
* 4cbab60 add f
* c80cfb0 (branch1) add e
* aea5708 add d
* 2e522fe (master) add c
* 0613527 add b
* e2a0c4d add a

This makes it explicit and its clear what set of commits are getting rebased onto what

pkini
  • 41
  • 3