Git and Visual Studio 2017 part 6 : Rebasing
In previous article, we did merge the changes from different branch. In this article, I dig into rebasing.
Rebase in Git
Rebase is opposite to merge. I did merge dev into master in the previous article, but if I rebase, I do it from dev branch to get changes from master. Changes from master? Yes I want to rebase as master has new commit after I created dev branch and did some commit.
1. Run ‘git log --oneline --graph’ to see current commit history. It is right after I did merge commit from previous article. Let’s reset this first.
2. Run ‘git reset --hard 473591c’ and ‘git log --oneline --graph’ again. It is reverted back to before merging.
3. Make sure dev branch has two new commits to master. Run ‘git checkout dev’ and ‘git log --oneline --graph’.
4. Add new commit to master branch. You can create new branch as proper workflow, but I just commit directly to master branch. I added Patch1.cs from Visual Studio and committed. Don’t forget to save project otherwise it won’t be considered as modified.
5. Run ‘git log --oneline --graph --all’, which shows commit history from all branches. The master and dev branch has it own commits now.
6. Time to rebase. I would like to get the change from master to dev branch. Run ‘git checkout dev’ and ‘git rebase master’. Then I see warning. What happens? As csproj file conflicts, Git asked me to resolve the conflict. Why it conflicts? Because master has Patch1.cs and dev has Class5.cs and Class6.cs, therefore information inside csproj is different.
7. Run ‘git merge tool’. As message says, hit return. It will launch Visual Studio (as merging tool).
8. Note that only Class5.cs exists. Why? Because Git is rebasing commits one by one. So at this point, it only rebasing commit d47a278. Check the line which you want to merge. In this case, I check both from Source and Target as I need all. Click save and then click “Accept Merge” button on the top.
9. As conflict resolved, run ‘git rebase --continue’. Now you see another warning. The reason is same as csproj has conflict.
10. Run 'git mergetool’ and hit enter key to launch Visual Studio again for merging.
11. This time, you see Class6.cs line. Take both and click “Accept Merge”.
12. Run ‘git rebase --continue”. No more errors.
13. Run ‘git log --oneline --graph --all’. It becomes straight line again, therefore dev branch had commit 7053b89, then two more commit. However commit SHA1 hash value has been changed for these two. Why? Because it is pointing back to different commit now.
14. Run ‘git reset --hard 096f270’ to reset the rebase. Now dev branch points to commit 096f270, and everything back to before rebasing. Run ‘git log --oneline --graph --all’ to confirm.
Rebase in VS
Okay, time to use Visual Studio for rebasing!
1. View history to confirm the current status. Unfortunately, I couldn’t find a way to show commit history for all branches. There are bunch of extensions though.
2. Go to “Branches” from Team Explorer, make sure to checkout dev branch, then select “Rebase”.
3. Select master branch as “Onto branch” and click “Rebase”.
4. As you expected (from Git test above), you see conflict message. Click “Conflicts: 1” link.
5. It lists all conflicts. Select csproj file and click “Merge”, which is same as ‘git merge tool’ If you know which version you want to keep, you can simply click “Take Source” or “Keep Target”. In this case, “Source” means dev branch and “Traget” means master branch.
6. Use merge tool to take both and “Accept Merge”.
7. You see no conflicts any more. Click “View Changes”.
8. It shows you the current status. Just click “Continue” link, which is same as ‘git rebase –continue’.
9. Now you have second conflict as expected. Click “Conflicts: 1” link.
10. The the same merging process and click View Changes once merged. Click “Continue” again.
11. Refresh the history to see it worked as expected.
Once you understand what rebase really does, it it not that difficult to handle. Otherwise you get confusing by seeing some many conflicts and continue operations, it seems to take forever . Rebase has many useful options such as --skip or --abort. When you get confused, just run ‘git rebase --abort’ which reset everything! Go to next article.