Git Fork Workflow Using Rebase
Here is a suggested git forking workflow for a team, utilizing rebase:
[1–3 same as the flow we’re used to, you’ll only have to do these once]
- Fork the official remote repo (in Github in your browser)
- Clone your new repo to your computer git clone http://rmpardee/foodiepal
- Add the official repo as an upstream so you can pull from it later git remote add upstream http://protolux/foodiepal
[4–7 we’ll be repeating with each feature]
4. Make a new branch to work on whatever you’re working on. Don’t work directly on master
git checkout master
→ make sure you start on the master branch so that your new branch is based on that and not on a different branch
git checkout -b myFeatureBranch
→ this creates the new branch called myFeatureBranch and the -b then moves you to that new branch.
Likely some time will pass here while you’re working on this feature. You will be making frequent commits and push to the same branch on your origin remote repo with ‘git push origin myFeatureBranch’, as well as doing steps 5–6 at least each day or two so you stay up-to-date with what’s on your upstream repo:
5. Every day or so, and ALWAYS before you’re ready to deploy the feature and make your PR, make sure your master branch is up-to-date with the official repo’s master branch, before pushing up to your origin myFeatureBranch
git checkout myFeatureBranch
→ make sure you’re on your feature branch first
git pull — rebase upstream master
→ rebase the branch you’re on onto whatever is on the upstream’s master branch (the changes other team members have made since the last time you did this)
What does this mean?
- A normal merge would put the commits your team members have done INTERSPERSED between all the commits you’ve made in chronological order. This makes the commit history look messy later, and it also adds a new unnecessary empty merge commit.
- A rebase instead would put the commits your team members have done BELOW all the commits you’ve made. This makes the commit history linear (related commits are still grouped together not interspersed), and avoids the unnecessary empty merge commit.
— — If merge conflicts emerge while rebasing:
a) git will rewind your code back to the commit you made where the conflict emerged, and stop. When you look at your code, it will look like all your hard work has been undone! Don’t worry, it’s just reverting to that version so you can fix the merge conflict, and then it will continue to put your other commits on top of that until it’s back to the way you had it.
b) In the file where the conflict is, you’ll see both conflicting versions. Change the file to exactly how you want it (removing all >>> etc that were added), and save.
c) Back in your CL, git add that file (but no need to do a commit. Essentially because there was a conflict, rebase will be making a merge commit automatically at the end of its process, so you’re just adding that file to that commit before you continue): git add [file]
d) Move on to the next merge conflict (if any) with:
git rebase — continue
and repeat until completed.
6. Now push up to your origin repo. First try:
git push origin myFeatureBranch
→ if this works fine, great, move on. If not (more likely)…
Another side effect of rebasing is it actually recreates new versions of each commit you’ve made on top of your team member’s commits. So if you’ve pushed those commits to your origin repo already (which you likely have done as you worked on the feature), git will not recognize the commits the origin repo has as the same as what you have locally anymore. Therefore it will think your origin is ahead of local, and ask you to pull before pushing.
If you’re sure this is the scenario that’s happening, you instead have to force git to overwrite your origin repo with what you have locally:
git push origin myFeatureBranch -f
7. On GitHub’s site in your browser, submit a pull request from your origin remote repo’s feature branch to the official repo’s master branch. → Other team members should review any pull requests and be merging them in. You should NOT merge your own pull requests, you should only merge other team members’.
8. Once your feature’s been merged by someone else, back in your local repo, go to your master branch and update it with what’s currently on the upstream’s master.
git checkout master
git pull — rebase upstream master
→ If you’ve done nothing since you made the PR, the only commit you’ll be rebasing down will be the merge commit when your PR was merged by your teammate.
→ Your master should now match the official repo’s master.
git push origin master → Bring your origin remote repo’s master up-to-date
You will now repeat #4–8 on your next feature, and the newFeatureBranch will be left behind and not ever updated again.