Notes from Code School's Git Real Course - Level 6
Merge Commits Are (mostly) Bad
In previous Codeschool levels, they talked about how to do merge commits, but also how they can pollute your history, see LEVEL 3. The alternative to doing a merge commit is using the rebase command.
Merge Commit (i.e. Recursive Merging) (Just a reminder of how you do merge commits, if you wanted to)
$ git pull
$ git push
Rebase
$ git fetch
$ git rebase
An Explanation of Rebase
In this example situation, Gregg and Jane are working on the same code on their local machines, but Jane beats Gregg to the punch and pushes her commits to the remote github repository before Gregg does. Now, Gregg's local code is out of date. When Gregg tries to push his commits to the remote repository, he will get a message saying his commit is ![rejected], and that his code cannot write over the existing remote code. How to fix:
Git Fetch
This is how Gregg would use the fetch and rebase commands to get back in sync with the remote repository. Gregg runs:
$ git fetch
This will pull down the remote repository, including Jane's commits, and place them on an automatically created branch called 'origin/master'.
![]() |
git fetch workflow |
Git Rebase
Now Gregg runs:
$ git rebase master
This will do 3 things:
1. Move all changes to master that are not in 'origin/master' to a temporary area (this would be all the changes Gregg made to the code since the last time he pulled the remote repository)
![]() |
git rebase step 1 |
2. Runs all commits on 'origin/master' (these would be Jane's commits that Gregg pulled from the remote repository in the git fetch step)
![]() |
git rebase step 2 |
3. Runs all commits in the temporary area one at a time.
![]() |
git rebase step 3 |
Now you have one smooth timeline showing first Jane's commits, then Gregg's with no empty merge commits inbetween. And lastly to sync with the remote repository, you would run $ git push. Just a reminder that you do not need to run $ git rebase three times, you only run it once, but the command executes three distinct steps.
Local Branch Rebase
How to use rebase to merge branches. For example, you are working on a local branch called 'admin', have made a couple of commits and are ready to merge it with master.
![]() |
commits on both master and branch need to be merged |
First, you need to switch (or make sure you are on the admin branch):
$ git checkout admin
Then run:
$ git rebase master
This will first run the master commits, then after, run the admin branch commits. So your new timeline will look like this:
![]() |
git rebase master will add master commits to branch |
What this does is act as though you ran made those master branch commits before you created the admin branch, thus making everything in sync. Now, since the admin branch is up to date, you can do a 'fast-forward' merge easily. In this case, you would switch back to the master branch:
$ git checkout master
And then merge admin into master:
$ git merge admin
At this point, you can delete the admin branch altogether.
How to Deal with Merge Conflicts in Git
In this example, both Jane and Gregg made changes to the same document, a README file. Again, Jane pushes her changes first, so Gregg will end up getting a conflict message. But first, Gregg knows that Jane has made changes to the remote repository, so he does a:
$ git fetch
(fetches all files from the remote repository)
$ git rebase
Git rebase tries to syncs the changes from remote, but Gregg will receive an error message:
Conflict(content): merge conflict in README.txt
Failed to merge changes
To fix this, Gregg must manually go into the file in question, README.txt in this case, and set the correct version. He can now go back to his console and type the command:
$ git rebase --continue
However, if he wanted to skip the patch and leave the file as is, he could run:
$ git rebase --skip
And if he wanted to rollback the rebase, and pretend he never ran it, he would do:
$ git rebase --abort
Now Gregg's commit log will include Jane's commits and his commits, but no merge commit conflict resolved message.
When Merge Commits Are a Good Idea
Previously they said that merge commits are bad, and that rebase is better. But sometimes merge commits can be good, for example if you wanted to document when a branch got merged into master. Then you could to a merge commit to ensure that step is timestamped/identified.
No comments:
Post a Comment