During the development process the code changes relate to each feature are being committed to separate feature branch
. Due to the fact that the team works on several features in parallel in most cases the default branch's head commit changes since a feature branch created until it is merged.
So, the developer that wants to merge their changes into the default branch first should update the feature branch. There are two main options to do it: merge and rebase.
- Prop: The PR is tidier and contains only relevant to the work on the feature commits.
- Cons: The conflicts resolution process is more challenging.
Note: Using merge we need to solve conflicts only once. For rebase we have to do it almost for each commit. If we'd have multiple commits in the branch the rebase could be very hard and painful process. The solution is to keep the branch lean.
-
Create folder for workshop and initialize git
mkdir workshop cd workshop git init git commit --allow-empty -m "First commit" git commit --allow-empty -m "Second commit" git commit --allow-empty -m "Third commit" git --no-pager log --format=oneline
-
Create the big feature branch with one commit
git checkout -b my-big-feature touch big-feature-file.txt echo Hello > big-feature-file.txt git add big-feature-file.txt git commit -m "feat: the first big feature commit"
-
Return to the main branch
git checkout -
-
Create the small feature branch with two commits
git checkout -b my-small-feature touch small-feature-file.txt echo "Hello" > small-feature-file.txt git add small-feature-file.txt git commit -m "feat: the small feature first commit" echo "World" >> small-feature-file.txt git add small-feature-file.txt git commit -m "feat: the small feature second commit" git --no-pager log --format=oneline
-
Merge it into main branch
git checkout main git merge --squash my-small-feature git commit -m "feat: the small feature" git branch -D my-small-feature git --no-pager log --format=oneline
-
Find last commit that is common for the feature and the default branch
git checkout my-big-feature echo "Last common commit: " `git merge-base my-big-feature main` git --no-pager log --format=oneline
-
Rebase the big feature branch on main and see that is the last common commit now
git rebase main echo "Last common commit: " `git merge-base my-big-feature main` git --no-pager log --format=oneline
-
Return to the default branch and delete the
my-big-feature
onegit checkout - git branch -D my-big-feature
Now the last default branch's commit is the last common commit for the feature and the default branches.
-
Create new branch
git checkout -b lean-branch
-
Add the first commit
touch code.txt echo "My feature code" > code.txt git add code.txt git commit -m "feat: cool feature"
-
Add the second commit
touch tests.txt echo "My feature tests" > tests.txt git add tests.txt git commit -m "tests: cool feature" git --no-pager log --format=oneline
-
OMG! You've run tests and figured out that there is a bug. Fix it!
echo "My feature fixed code" > code.txt
-
Insert the fix into the first commit so nobody will know we had bugs.
git add code.txt git commit --fixup HEAD~1 git --no-pager log --format=oneline
Note: You can use the commit sha instead of
HEAD~X
.
-
Now we need to rebase commits.
git rebase -i --autosquash HEAD~3
Press
ESCAPE
and:q!
in the vim editor.
-
What do we have now?
git --no-pager log --format=oneline
Note: If you pushed the changes to the upstream after rebase you have to use
git push --force
to replace fixed commits.
Rebase helps to keep the branch both up-to-date and clean, w/o any extraneous commits. Using interactive rebase we can fixup every commit in our branch even if there are others on top of it. We can rename and drop commits and even to change the order.