Last active
June 22, 2016 18:17
-
-
Save davidbarkhuizen/81300114b894a12b0706567155d3b63e to your computer and use it in GitHub Desktop.
git rebase merge branch workflow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| tldr; | |
| to incorporate changes from branch feature_branch into the master branch, retaining commits in master that occurred | |
| subsequent to branching: | |
| $ git checkout master | |
| $ git pull origin | |
| $ git checkout feature_branch | |
| $ git rebase master | |
| [ # if a conflict is found in /model/user.js, then manually resolved | |
| $ git add /model/user.js | |
| $ git rebase --continue | |
| ] | |
| $ git checkout master | |
| $ git merge feature_branch | |
| $ git push origin | |
| The Situation: | |
| You have a git repo, with a master branch. A while back you created a new branch named feature_branch, and commited code | |
| a couple of times, and now want to incorporate the changes in your branch back into the master branch. To complicate things, | |
| in the meantime a colleague of yours has committed a bunch of hot-fixes to the master branch. Luckily they're a competent | |
| developer, and we're happy with their changes, but we want to get our new feature incorporated into the master branch, and | |
| deployed to production. | |
| The Method - rebase merge | |
| I won't wade into the merge versus rebase debate further than to say that with the rebase-merge method, you (in general) only | |
| ever have to merge changes that _you_ made (and hence understand the logic behind) - as opposed to the merge approach, where | |
| the contrary applies. | |
| Assuming that we are starting from a situation where we have feature_branch checked out, and are in the root folder of the repo, | |
| and have all changes committed, in other words, a | |
| $ git status | |
| returns 'nothing to commit'. | |
| First, assuming that no-one else is working on feature_branch, so that our local branch is the most current, we need to ensure | |
| that the local master branch is up to date with the remote branch, so: | |
| $ git checkout master | |
| $ git pull origin | |
| Happy that the local master branch is current, we check out feature_branch | |
| $ git checkout feature_branch | |
| We start by rebasing feature_branch against master. | |
| $ git rebase master | |
| This entails first undoing all the commits to feature_branch, essentially returning it to the state it was in when it first | |
| diverged from the master branch (barring other unknown madness having occurred in the meantime) - git calls this 'rewinding'. | |
| Git then attempts to apply the commits (diff patches, in this case the hot-fixes our colleague put into production) from master | |
| to feature_branch, one at a time. If it encounters a problem at any point, it will pause, inform you of the problem, and the | |
| need for you to edit the files to resolve to a final state. This is typically not going to happen when git applies the diffs | |
| from the master branch, but when it attempt to apply the diffs from your commits afterwards. | |
| For every file where there is a conflict, you will see markers indicating where the divergence has taken place. Edit the file, | |
| manually, merging the logic, and removing any git merge indicator markers. Once the file is good, you need to add it back to | |
| the change-set. So, assuming a conflict in file /model/user.js. | |
| $ git add /model/user.js | |
| Once you've resolved all the files, then instruct git to continue with the rebasing: | |
| $ git rebase --continue | |
| Git will then keep applying diffs, until it either encounters another problem, or finishes. So, at this point, we're almost | |
| done, as our local copy of feature_branch has all the changes from both master and feature_branch, so all that is left to do | |
| is to checkout the master branch, and merge our feature_branch, which (unless some has beaten us to it), should be trivial, | |
| since we've already informed git as to how the tricky merges (if there were anything): | |
| $ git checkout master | |
| $ git merge feature_branch | |
| Pushing the local master to the remote origin completes our code delivery: | |
| $ git push origin | |
| If you want to push the local copy of now-rebased feature_branch to the remote (which is actually not recommended, because you | |
| effectively lose information when doing the rebase-merge), then you will have to force the push, which you would do with a: | |
| $ git checkout feature_branch | |
| $ git push origin --force |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment