Created
September 21, 2012 21:24
-
-
Save klj613/3763991 to your computer and use it in GitHub Desktop.
Rebase git flow
This file contains 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
Rebasing Git Flow | |
================= | |
TL;DR | |
----- | |
- All feature branches are rebased to latest master | |
- All staging branches are rebased to latest master | |
- All finalized feature branches are rebased then --no-ff merged into a staging branch | |
- All staging branches gets signed off and tested before --no-ff into master | |
- Remove all history of staging branches | |
- All feature branches prefixed by an author name is only to be used by the author. | |
- If any feature-branches rely heavily on each other then they are actually sub-feature-branches of the same feature-branch. | |
- If any feature-branches rely lightly on each other then you can use `git cherry-pick` to pick up specific commits (e.g. something small) from another branch. | |
- Once a staging branch is merged into master, all the branches for the features introduced in the that stage branch should be removed. | |
Basic Example | |
------------- | |
* feature-x * feature-y | |
* * | |
* * | |
* * | |
* * | |
/ / | |
* master | |
Creating a staging branch | |
------------------------- | |
`git checkout master` | |
`git checkout -b stage-1` | |
`git checkout feature-x` | |
`git checkout -b stage-1-feature-x` | |
`git rebase stage-1` | |
`git checkout stage-1` | |
`git merge stage-1-feature-x --no-ff -m "Merge branch 'feature-x' into master"` | |
Note: since feature-x is already on latest master, stage-1-feature-x and feature-x will be on the same commit (fast-forward) | |
* stage-1 - Merge branch 'feature-x' into master | |
| \ | |
| * feature-x stage-1-feature-x * feature-y | |
| * * | |
| * * | |
| * * | |
| * * | |
/ / / | |
* master | |
Staging feature-y with feature-x | |
-------------------------------- | |
`git checkout feature-y` | |
`git checkout -b stage-1-feature-y` | |
`git rebase stage-1` | |
`git checkout stage-1` | |
`git merge stage-1-feature-y --no-ff -m "Merge branch 'feature-y' into master"` | |
* stage-1 - Merge branch 'feature-y' into master | |
| \ | |
| *' stage-1-feature-y | |
| *' | |
| *' [solved conflict here] | |
| *' | |
| *' | |
| / | |
* Merge branch 'feature-x' into master | |
| \ | |
| * feature-x stage-1-feature-x * feature-y | |
| * * | |
| * * | |
| * * | |
| * * | |
/ / / | |
* master | |
Stage passed QA. Fastforward merge to master | |
-------------------------------------------- | |
`git checkout master` | |
`git merge stage-1 --ff-only` | |
* master stage-1 - Merge branch 'feature-y' into master | |
| \ | |
| *' stage-1-feature-y | |
| *' | |
| *' [solved conflict here] | |
| *' | |
| *' | |
| / | |
* Merge branch 'feature-x' into master | |
| \ | |
| * feature-x stage-1-feature-x * feature-y | |
| * * | |
| * * | |
| * * | |
| * * | |
| / / | |
* | |
Cleanup feature branches | |
------------------------ | |
`git checkout master` | |
`git branch -d stage-1` | |
`git branch -d feature-x` | |
`git branch -D feature-y` (feature-y is not within branch master so have to use -D. However stage-1-feature-y is in master) | |
`git branch -d stage-1-feature-x` | |
`git branch -d stage-1-feature-y` | |
* master - Merge branch 'feature-y' into master | |
| \ | |
| *' | |
| *' | |
| *' [solved conflict here] | |
| *' | |
| *' | |
| / | |
* Merge branch 'feature-x' into master | |
| \ | |
| * | |
| * | |
| * | |
| * | |
| * | |
| / | |
* | |
Advantages | |
---------- | |
- Feature branches self-contained | |
- Pretty/_sane_ history | |
- Want to deploy feature-x before the sprint ends? create a new stage branch, rebase/merge, merge master. Feature-x already in old staging branch? recreate it! (or rebase) | |
Disadvantages | |
------------- | |
- Use of rebase (most people will discourage this) | |
- Git beginners might get confused | |
- If you build feature branches and want to keep that history, history will be messy (see above whilst feature-y co-existed with stage-1-feature-y) | |
- Pull Requests will get 'outdated diffs' messages. However PR's should only happen on a stage branch when it is ready to be merged into master or on a staged feature branch ready to be merged into a stage branch. Please don't use automatic merging! Merge it yourself with custom message. | |
Special circumstances | |
--------------------- | |
You've got stage-1 which contains feature-y, feature-x and feature-z. However you need to deploy feature-x ASAP. You'd create stage-2 and rebase/merge feature-x within stage-2 and then fast-forward merge master. | |
However, feature-y and feature-z was branched off old version of master. We must rebase. | |
Also stage-1 is branched off old version of mater. We must rebase. | |
Clean way to do this (as rebase ignores merge commits) is to: | |
`git branch -D stage-1` | |
`git checkout feature-y` | |
`git rebase master` | |
`git checkout feature-z` | |
`git rebase master` | |
`git checkout master` | |
`git checkout -b stage-1` | |
`git checkout stage-1-feature-y` | |
`git rebase stage-1` | |
`git checkout stage-1` | |
`git merge stage-1-feature-y --no-ff` | |
`git checkout stage-1-feature-x` | |
`git rebase stage-1` | |
`git checkout stage-1` | |
`git merge stage-1-feature-x --no-ff` | |
Now we've got stage-1 up to date with master and all features not merged into master is up to date with master. | |
(Diagrams to follow in near future) | |
Note | |
---- | |
- _Do not_ work off master branch. | |
- _Do not_ work off staging branches. | |
- _Always_ work off feature branches, not staged feature branches. | |
- _Always_ rebase to the branch you want to merge to (`git checkout -b stage-1-feature-x` `git rebase stage-1` `git checkout stage-1` `git merge stage-1-feature-x --no-ff`) | |
- _Only_ merge QA'd/authorised staging branches to master. | |
- _Stage branches_ can be re-created (or reset). | |
- Once a stage branch is merged into master then the _feature branches_ are immutable (finalized) and the original feature branches (non-rebased) should be | |
removed as shown above. | |
- Feature branches prefixed with author name should be not be touched by anyone except the author as they wish to change the history as they please. | |
- You should remove the history of any staging branches to keep a clean history. Such as changing the merge commit messages like the following: | |
"Merge branch 'feature-x' into master" | |
instead of | |
"Merge branch 'stage-n-feature-x' into 'stage-n" | |
- Therefore when you fast-forward merge master into stage-n it will appear that each feature was actually merged into master and the use of staging branches is hidden. | |
- As discussed, if you cannot fast-forward merge master into stage-n then you'd have to rebase/reset/recreate the stage-n onto latest master. This will only occur if you | |
create stage-1 then stage-2 then stage-2 gets merged in before stage-1 and stage-1 has to be updated. | |
Disclaimer | |
---------- | |
- This model is untested and still not finalized. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment