A good workflow leads to a usable, in-use and useful git tree.
Get up to date
- Update the
masterbranch in my local environment:
git checkout master git pull
master is never changed in local,
git pull will always do a fast-forward merge.
- Update a feature branch against the remote tracking branch:
git checkout feat1 git pull --rebase
- Update a feature branch against the
git checkout feat1 git pull --rebase origin master
You could be tempted to
git merge origin/master into your local branch creating a merge commit. This makes the graph more complex.
⚠️ Difference between merging
origin/master into a feature branch and rebasing your feature branch on the top of
C8 only exists on
side2, two feature branches, need to be updated before being shared with your central repository and your teammates.
side1 is a local feature branch updated with
git pull --rebase → no new commit are created.
side2 is a local feature branch updated with
git pull → a merge commit
C9 is created.
The git tree for
side1 is more straight forward than the git tree for
side2 which contains complicated branching links.
Start a new branch
- From the local environment
git checkout master git pull git checkout -b feat1
- Push the change
git checkout feat1 git pull --rebase origin/master git push
Clean your commits 📖
For many reasons, you can decide to keep your commits in local and push them all at once at the end of your development. In this case you may need to rewrite some of your commit messages to clarify or clean them.
Learn to play with your bunch of commits to share beautiful branches to your teammates.
git checkout feat1 git fetch git rebase -i origin/master
As you rewriting history, the
push command could be rejected.
--force-with-lease is a safer alternative than
--force as it refuses to push changes if the remote branch contains commits from teammates. 📖
There is no need to clean your commits afterwards after using these commands:
git add --patch📖
git add -p ## select the changes to be added to the next commit git commit -m "fix: Found this issue while working on this" git add -p ## select the other changes not added to the previous commit git commit -m "feat: New behavior added"
git commit --amend --no-edit📖
touch "Hello" >> README.md git add README.md git commit -m "doc: Introduce the project" touch "Hello\n" >> README.md git commit --amend --no-edit ## instead of `git commit -m "oops, new line"
git commit --fixup📖
touch "Hello" >> README.md git add README.md git commit -m "doc: Introduce the project" ## create commit 7736d8e touch "How to contribute" >> CONTRIBUTING.md git commit -m "doc: How to contribute" touch "Hello\n" >> README.md git commit --fixup 7736d8e ## create a special commit git rebase -i --autosquash ## do what is expected
Rebase vs Merge Commit
True merge is done by
git merge --no-ff while
git merge --ff-only force a rebase instead. Using
git merge without any flag make a fast-forward if possible (equivalent to
git rebase or
git merge --ff-only or create a merge commit instead (equivalent to
git merge --no-ff).
The default commit message of a merge commit is standard :
"Merge branch '<branch_name>'". This commit message is not very useful because it does not say anything that is not visible in the git tree.
* 58361b3 (HEAD -> master) feat: Add the Login functionnality |\ | * f8c02aa (feat/Login) doc: Add some explanation for login capabilities | * 7333496 feat: Add login button on home screen | * d76776c feat: Add login behavior |/ * aff31df initial commit
* f8c02aa (HEAD -> master, feat/Login) doc: Add some explanation for login capabilities * 7333496 feat: Add login button on home screen * d76776c feat: Add login behavior * aff31df initial commit
In the former example with
--no-ff the git tree shows explicitly the new functionality and the detailed work that has been done. When the second one, with
--ff-only displays a linear history without grouping the commits around a feature.
A third version is possible with a well-known behavior from git platforms (github, gitlab, bitbucket) called squash and merge. The resulting git tree will be:
* 402b615 (HEAD -> master, feat/Login) feat: Add the Login functionnality * aff31df initial commit
There are many commands to perform exactly the same action with git.
git pull --no-ff origin master is the same as
git fetch origin && git merge --no-ff origin/master.
git pull --rebase origin master is the same as
git fetch && git merge --ff-only origin/master and the same as
git fetch && git rebase origin/master.