4.8 KiB
4.8 KiB
<style>
.reveal strong {
font-weight: bold;
color: orange;
}
.reveal p {
text-align: left;
}
.reveal section h1 {
color: orange;
}
.reveal section h2 {
color: orange;
}
.reveal code {
font-family: 'Ubuntu Mono';
color: orange;
}
.reveal section img {
background:none;
border:none;
box-shadow:none;
}
</style>
Merge vs. Rebase
Linear History
- Commits are snapshots + pointer to parent, not diffs
- But for linear history, this makes no difference
- Each normal commit has one parent commit
c05f017^<–c05f017A=B^<–B- (
^is the same as~1) - Pointer to parent commit goes into hash
git showgives diff of commit to parent
Merge Commits
git checkout main && git merge feature
- A merge commit (normally) has two parent commits
M^1andM^2(don’t confuse^2with~2)- Can’t show unique diff
- First parent relative to the branch you are on (
M^1=C,M^2=E)
git showgit show: “combined diff”- GitHub:
git show --first-parent git show -m: separate diff to all parents
Why is a Linear History Important?
We use here:
Linear history := no merge commits
- Merge commits are hard to understand per se.
- A merge takes all commits from
featuretomain(ongit log). –> Hard to understand - Developers often follow projects by reading commits (reading the diffs). –> Harder to read (where happened what)
- Tracing bugs easier with linear history (see
git bisect)- Example: We know a bug was introduced between
v1.3andv1.4.
- Example: We know a bug was introduced between
How to get a Linear History?
- Real conflicts are very rare in real projects, most merge commits are false positives (not conflicts) and should be avoided.
- If there are no changes on
main,git mergedoes a “fast-forward” merge (no merge commit). - If there are changes on
main, rebasefeaturebranch.
Rebase
git checkout feature && git rebase main
- States of issues change (and new parents) –> history is rewritten
- If
featureis already on remote, it needs a force pushgit push --force myfork feature(or--force-with-lease). - Be careful: Only use rebase if only you work on a branch (a local branch or a branch on your fork).
- For local branches very helpful:
git pull --rebase(fetch & rebase)
GitHub PR Merge Variants
- GitHub offers three ways to merge a non-conflicting (no changes in
same files) PR:
- Create a merge commit
- Squash and merge
- Rebase and merge
- Look at a PR together, e.g. PR 1432 from preCICE (will be closed eventually)
What do the options do?
Squash and Merge
- … squashes all commits into one
- Often, single commits of feature branch are important while developing the feature,
- … but not when the feature is merged
- Works well for small feature PRs
- … also does a rebase (interactively,
git rebase -i)
Conflicts
But what if there is a conflict?
- Resolve by rebasing
featurebranch (recommended) - Or resolve by merging
mainintofeature
Summary and Final Remarks
- Try to keep a linear history with rebasing whenever reasonable
- Don’t use rebase on a public/shared branch during development
- Squash before merging if reasonable
- Delete
featurebranch after merging - Local view:
git log --graph - Remote view on GitHub, e.g. for preCICE
