DEV Community

loading...

What is git rebase?

borrrden profile image Jim Borden ・1 min read

You can think of git commits like a long chain. Each time you make a commit, you add one more link in the chain. The problem is that sometimes that chain can split into two chains like this:

D
|
C   C2
|   |
B --
|
A
Enter fullscreen mode Exit fullscreen mode

What most people do when they want to move C2 back into the original chain is what is called a merge and it looks like this:

E
|  \
D   |
|   |
C   C2
|   |
B --
|
A
Enter fullscreen mode Exit fullscreen mode

In which E is a commit which combines the changes of C, D, and C2 into a new commit . However, with branches and then branches off of branches this can quickly lead to a spaghetti looking history. Instead, let's see what happens when you switch to the branch with commit C2 (let's call it 'dev') and run rebase on the main line (let's call it 'master'). So

git checkout dev
git rebase master
Enter fullscreen mode Exit fullscreen mode
C2
|
D
|
C
|
B
|
A
Enter fullscreen mode Exit fullscreen mode

This history is much cleaner now, as C2 was simply moved to the end of the line. This is what rebase does. Note that master is still pointing to 'D', and dev is pointing to the new 'C2' location.

Discussion (8)

pic
Editor guide
Collapse
mxdanielon profile image
Daniel Gallegos

Great post to exemplify rebase! Just remember that for pushing changes to remote it could be better to git push --force-with-lease instead of the typical git push --force. The former would watch for any changes you don't have in your local branch.

Collapse
borrrden profile image
Jim Borden Author

As the other Daniel pointed out never force push to the master branch and always let relevant people know when you do for another. What do do with your rebased changes (in terms of pushing) probably deserves a separate post all together but the main goal here is to not have to force push at all. In the example I've given no force push is needed for the main branch (only the dev branch if it is going to continue)

Collapse
dhiller profile image
Daniel Hiller

If you force push to a main branch everyone will hate you. I don't think you should give this advice in a posting for git beginners. Just because you can do that doesn't mean it's the right thing to do....

Collapse
jastbytes profile image
Jan Steffen • Edited

May the --force be with you! Seriously, never force push to the master. It's not like you have to with rebase. Don't understand the advice though.

forcepush

Collapse
dhiller profile image
Daniel Hiller • Edited

You should point out that when doing rebase you're in fact changing commit history for the commit c2. While the changes in c2 still apply, the commit id will change. That is not obvious to any git beginner. So to be more clear you should rename the c2 to c2'.

Collapse
borrrden profile image
Jim Borden Author

This is true but I wonder if a beginner will understand the significance of this...

Collapse
midblue profile image
Jasper Stephenson

Thanks for the guide, I've never been clear on this! In the last diagram, does C2 overwrite the changes from D? Or does it functionally do the same thing a regular merge?

Collapse
borrrden profile image
Jim Borden Author

C2 will apply the changes on top of D as if it were a regular merge. As such, you can get merge conflicts at this stage but after you merge them your history will still be cleaner.