This is an introductory level workshop on using git rebase
to keep your local changes up-to-date
with a master
branch and resolve conflicts.
This is an imaginary scenario and restrictions are here to help you focus on learning git rebase
.
Read more about tidy git history in the article A tidy, linear git history.
git-rebase - Reapply commits on top of another base tip
(https://git-scm.com/docs/git-rebase)
When resolving conflicts during git rebase
, HEAD ("current change") will be the tip of the branch
you're adding commits to, and "Incoming change" will be (consequently) commits from the branch
you are currently rebasing.
This repository consists of a number of branches. Each branch corresponds to a certain "feature",
while all features contribute to writing an agile manifesto. You'll have to merge these branches to
the release
branch in a correct order (see below).
The result contents of the manifesto.md
should look like this:
# Manifesto for Agile Software Development
We are uncovering better ways of developing
software by doing it and helping others do it.
Through this work we have come to value:
**Individuals and interactions** over processes and tools
**Working software** over comprehensive documentation
**Customer collaboration** over contract negotiation
**Responding to change** over following a plan
That is, while there is value in the items on
the right, we value the items on the left more.
- Create manifesto
- Clean-up
- Paragraph 1
- Paragraph 2
- Paragraph 3
- Formatting
- Title
- You can use
git rebase
with any options for feature branches. - You can't use
cherry-pick
. - You can't commit anything.
- Use
git checkout manifesto && git merge --ff-only <feature-branch>
to update themanifesto
branch (let's imagine it's our GitHub merge PR button).
git checkout master
chmod +x ./reinit.sh
./reinit.sh
Thanks to @zoheiry and @ajantis for reviewing and commenting on the original implementation.
git checkout manifesto
Notice that paragraph-1
and manifesto
both contain the Create manifesto
commit:
git log --graph --pretty=oneline manifesto paragraph-1
Let's try merging (that's what would normally happen instide the GitHub):
git merge --ff-only paragraph-1
You'll see a message that fast-forward merge is not possible (due to conflicts).
Now we can start rebasing. Our goal is to put paragraph-1
on top of manifesto
.
git checkout paragraph-1
git rebase manifesto
git status
git diff
# resolve conflicts (accept incoming change)
git add manifesto.md
git rebase --continue
git checkout manifesto && git merge --ff-only paragraph-1
git checkout paragraph-2
git rebase manifesto
git status
git diff
# resolve conflicts (keep both changes, add an empty line in between)
git add manifesto.md
git rebase --continue
git checkout manifesto && git merge --ff-only paragraph-2
NB! Don't forget to use git log --graph --pretty=oneline <branch names>
to see what's going on.
git checkout paragraph-3
git log --graph --pretty=oneline manifesto paragraph-3
# copy previous commit hash (Paragraph 1)
git diff manifesto <commit hash> # see that there's no diff
git rebase --onto manifesto <commit hash> paragraph-3
git status
git diff
# resolve conflicts (keep both changes, add an empty line in between)
git add manifesto.md
git rebase --continue
git checkout manifesto && git merge --ff-only paragraph-3
git checkout formatting
git log --graph --pretty=oneline manifesto formatting
git rebase -i manifesto
# Drop the first one (Paragraph 2), pick Formatting 1 and squash Formatting 2.
# Then `Esc :wq`
git status
git diff
# resolve conflicts
git add manifesto.md
git rebase --continue
# resolve conflicts
git add manifesto.md
git rebase --continue
git log --graph --pretty=oneline manifesto formatting
git show formatting # or commit hash
git checkout manifesto && git merge --ff-only formatting