- The seven rules of a great Git commit message
- Learn these rules! The rest of this article is very informative as well.
- What should be in version control... and what should not.
- This is the mother of all informative resources about Git. Read it very carefully.
- There is also a good web-app which helps you learn the behavior of git: https://learngitbranching.js.org/
- The commit DAG is frequently reported to be "the most important thing to realize about git". You should strive to understand every git command in terms of how it manipulates the commit graph! The VGR is an excellent resource to understand this.
- Have a look at the DAG of your repository with
git log --all --decorate --oneline --graph
(log adog / "look, a dog!") - What you need to internalize is that commits are nodes in a DAG. All commits have one parent commit, merge commits have two parents.
- Another concept you need to understand are references. Branches, tags and HEAD are all references. Which basically means they are an alias of a particular commit.
- Examples: "
merge
creates a commit with two parent commits", "cherry-pick
takes a list of commit hashes and applies them as patches onto HEAD" and "reset
takes a reference to or the hash of a commit and makes the current branch point to it". - HEAD is a special reference.
- Relative references, like
HEAD~2
are very helpful too.
- Rebasing is an alternative to merging in as far as both of them are ways to integrate two branches. A
rebase
is a special case ofcherry-pick
.
- Select commits by their hashes and apply them one-by-one onto HEAD
- See the VGR for visual aid.
- Rebase does the same as cherry-pick, only for entire branches automatically. The VGR explains the technical side of rebases pretty well.
- This guide -- Getting solid at Git rebase vs. merge -- explains in depth the pros and cons of rebase and merge. It's a very long post and many of its contents will also be covered in this guide. However, you should definitely add this to your read-later list.
- After you rebased a branch it contains different commits than before. Because of that
git push
will reject your changes. - A full explanation of the problem and why
--force-with-lease
is a better solution than--force
can be found here.
- Learn about tracking upstream branches. This link covers
git push --set-upstream
akagit push -u
.git branch -vva
will give you an overview of which remote branches your local branches track
-
Before turning to
pull
, let's make clear what a fast-forward merge is. -
Fast-forward merges
- A fast-forward merge is the special case where a merge can be completed without creating an extra merge commit.
- Refer to the VGR or https://sandofsky.com/images/fast_forward.pdf
-
pull
vspull --rebase
vspull --ff-only
- What's the difference between
pull
andpull --rebase
? (spoiler:pull --rebase
is what you want to use):- When should I use
git pull --rebase
? - And another article discouraging
pull
: https://adamcod.es/2014/12/10/git-pull-correct-workflow.html
- When should I use
pull
is actually considered harmful!- The preferred way to get remote changes is: Use
pull --ff-only
and if it fails consciously take appropriate actions with merge, rebase, cherry-pick, whatever. - Read the answers to this SO question
- The preferred way to get remote changes is: Use
- What's the difference between
-
In order to have a broad understanding of Git let's have a look at a couple of popular usage paradigms
-
A very basic introductory article on how to use branches in Git: https://sandofsky.com/blog/git-workflow.html
-
The Git flow. A very popular branching model for git.
-
Maximum historical innformation
-
- Example of a centralized workflow: Gitlab's Merge Request workflow
- Example of a Integration-Manager Workflow: Fork and Pull Request Workflow (GitHub's Pull Request workflow)
- Example of a Dictator and Lieutenants Workflow: The Linux kernel's patch-based workflow
-
-
git rebase -i
- Git Interactive Rebase, Squash, Amend and Other Ways of Rewriting History -
Undoing things in Git
-
squash
/commit --fixup
/rebase --auto-squash
-
A clean commit history is nice, but sometimes you end up wasting time on it. So keep in mind that sometimes branching and merging is a good enough workflow. Also, here's an opinion that you should stop using rebase.