Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use git rebase to retroactively make commits land on a different branch?

Tags:

git

rebase

I have some commits:

 - 1 - 2 - 3 - 4 - 5 (HEAD, master)

Afterwards I notice Commits 2 & 3 really should have gone on their own branch. They are completely independent of commits 4 and 5 Can I use git rebase to make?

 - 1 - 4 - 5 (HEAD, master)
    \
     2 - 3 (TestBranch)

And most importantly, will the SHA1s for Commit 2 and Commit 3 stay the same as they were before the rebase?

like image 206
AndyL Avatar asked Jan 14 '11 22:01

AndyL


People also ask

Does rebasing create new commits?

The Rebase Option But, instead of using a merge commit, rebasing re-writes the project history by creating brand new commits for each commit in the original branch.

Does git rebase change both branches?

Git's rebase command reapplies your changes onto another branch. As opposed to merging, which pulls the differences from the other branch into yours, rebasing switches your branch's base to the other branch's position and walks through your commits one by one to apply them again.

Does rebase rewrite commit history?

Changing older or multiple commits. To modify older or multiple commits, you can use git rebase to combine a sequence of commits into a new base commit. In standard mode, git rebase allows you to literally rewrite history — automatically applying commits in your current working branch to the passed branch head.


1 Answers

First, note that your desired TestBranch points simply to the current commit 3; you don't have to do anything but git branch TestBranch <commit 3> to accomplish that. Remember, branches are just pointers to commits. This should answer your question about the SHA1s of commits 2 and 3. You haven't changed those commits at all, so their SHA1s are of course the same.

To get your current branch (master) where you want it (commits 1, 4, 5), you will indeed rebase. This is a very simple case for its interactive mode. First, run:

git rebase -i <commit 1> master     # -i is a synonym for --interactive

Git will launch your editor, and show you all of the commits since commit 1 on your master branch (2,3,4,5), along with some hints about what to do. You just need to delete the lines for commits 2 and 3, then save and quit. It will then apply what's left (4 and 5), leaving you with what you want. Of course, if commits 4 and 5 depended on commit 2 or 3, you're going to get merge conflicts when git tries to apply their patches during the rebase.

Note that this will change the SHA1s of commits 4 and 5, since the SHA1 of a commit depends on its parent. This will mess with anyone who's pulled that branch. (You have been warned.) Your actual final result would more accurately be described like this:

- 1 - 4' - 5' (HEAD, master)
   \
    2 - 3 (TestBranch)

Commits 4' and 5' have the same diffs as commits 4 and 5, but have different parents, so they are different commits.

like image 113
Cascabel Avatar answered Oct 04 '22 21:10

Cascabel