This document discusses common Git anti-patterns and provides recommendations to avoid them. It begins by explaining how Git works under the hood in terms of files, folders, references, and objects. It then covers 15 specific anti-patterns to avoid, such as treating Git like Dropbox, having long-living topic branches, merging too late without validation, and being afraid to delete branches. For each anti-pattern, it provides alternatives and recommendations, such as splitting work into small tasks, committing early and often, rebasing rather than merging, and deleting merged branches. The overall message is how to use Git properly and cure common issues by following best practices.
Git Anti-Patterns - Extended Version With 28 Common Anti-Patterns) - SCTurkey Meetup
1. GITANTI
PATTERNS
How To Mess Up With Git and Love It Again
LEMi ORHAN ERGiN
Agile Software Craftsman, iyzico
/lemiorhan
lemiorhanergin.com
@lemiorhan
28 common git anti-patterns
2. DISCLOSURE
There is no formula for using git efficiently.
Opinions are my own. It means the opposites
might work perfectly for your conditions.
4. Are you using git
if all you do is commit-push-pull
use dropbox instead
ANTIPATTERN DANGER
as if it is dropbox ?
1DROPBOX-ISH GIT ANTI-PATTERN
5. learn how git works
no worries, I will cover how git behaves
6. the way it keeps
FILES & FOLDERS
working copy
staging area
objects database
repository
the way it keeps
REFERENCES
directed acyclic graph
keeping snapshots
traversing graph
branches, tags, heads
git has 2 mechanisms
12. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
$ git add .
preparing commits
13. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
$ git commit -m “initial commit”
commi!ing
14. $ git commit -m “initial commit”
commi!ing
folder
folder
folder
file
file
file
commit
branch
HEAD
For more details, refer to book
Git Internals by Scott Chacon
17. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
$ git commit -m “initial commit”
commi!ing
18. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
$ git remote add origin http://upstream.repo
$ git push -u origin master pushing to remote
19. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
new changes from others are pushed
20. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
$ git fetch
fetching changes
21. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
$ git merge FETCHED_HEAD
updating working copy
22. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
$ git pull
git fetch + git merge
ge!ing changes to source code
23. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
want to update last commit
24. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
$ git reset --soft $ git commit --amend/ so" reseting
cannot be reached
Only the cache for
the commit you reseted
is removed from staging area
for your current branch
27. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
want to squash or change last commits
28. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
$ git reset --mixed
mixed reseting
cannot be reached
entries for commits, files
and folders are removed
from staging area
29. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
want to get rid of last commits
30. Object Database
.git Folder / Object Database
Cache
Staging Area / The Index
Remote
Upstream Repo / Remote Repo
Server
Source Code
Working Copy
$ git reset --hard
hard reseting
cannot be reached
removed from staging area
removed from working copy
31. are you brave enough to
jump to any commit ?
jump to a branch
create a branch from a commit
create a branch from a tag
ANTIPATTERN DANGER
$ git checkout feature/PA-121
$ git checkout -b fix/missing-sign-parameter 2449be8
$ git checkout -b hotfix/v1.1 tags/v1
2BROKEN TIME MACHINE ANTI-PATTERN
35. before merging
do you validate commits
back to source ?
ANTIPATTERN DANGER
code review, continuous integration, automated testing…
4TOO LATE TO VALIDATE ANTI-PATTERN
37. merge and unmerge
do you o!en want to
just before releases ?
ANTIPATTERN DANGER
5CHERRY-PICK OBSSESSION ANTI-PATTERN
38. merge and unmerge
do you o!en want to
just before releases ?
master
HEAD
TAG/v13
version 14
$ git cherry-pick Every-Single-Commit-We-Want-To-Deploy
39. the commit graph ?
do you fully understand
ANTIPATTERN DANGER
6DEATH ON COMMIT GRAPH ANTI-PATTERN
40. the commit graph ?
do you fully understand
topic and shared branches, tracking branches, tags, HEADs, merge commits, reverted commits…
43. STEP 0
split your big feature into
mini shippable tasks
master
HEAD
TOPIC
ORIGIN/master
refactorings
tasks, like rest endpoints
testable, deployable
each task will have a
branch, not a feature
44. STEP 1
commit early
commit o!en
no need to compile
no need for CI
it’s only for versioning
do not push
master
HEAD
TOPIC
ORIGIN/master
45. always pull with rebase
$ git pull --rebase origin master
to get forced pushes securely
to rebase your commits
master
HEAD
TOPIC
STEP 2
ORIGIN/master
46. always pull with rebase
$ git pull --rebase origin master
to get forced pushes securely
to rebase your commits
master
HEAD
TOPIC
STEP 2
ORIGIN/master
47. always pull with rebase
$ git pull --rebase origin master
to get forced pushes securely
to rebase your commits
master
HEAD
TOPIC
STEP 2
ORIGIN/master
if you branch is pushed already
$ git push -f
48. always pull with rebase
$ git pull --rebase origin master
to get forced pushes securely
to rebase your commitsmaster
HEAD
TOPIC
STEP 2
ORIGIN/master
if you branch is pushed already
$ git push -f
Sync source branch a!erwards
$ git fetch origin master:master
49. perfect later
make it single commit
$ git reset HEAD~3
or
$ git rebase -i HEAD~3
HEAD
TOPIC
STEP 3
ORIGIN/master
tests are passing
app is working
code is reviewed (*)
master
50. $ git reset HEAD~3 (then commit)
or
$ git rebase -i HEAD~3
HEAD
TOPIC
STEP 3
ORIGIN/master
perfect later
make it single commit
tests are passing
app is working
code is reviewed (*)
master
53. Continuous Integration
validates master branch
continuouslymaster
HEAD
TOPIC
ORIGIN/master
Pull requests can be
used to review code
and to validate before
merging back to master
Scrum tasks are
mapped to commits,
not stories
Github Flow can be
used to govern overall
TAMING
THE POWER OF GIT
make git the king again
Feature flags should be
used whenever possible
Commit early & o"en
perfect later, publish
once philosophy
Deliver frequently
be prepared to send
every single commit
Deleting branches a"er
merge will make your
commit graph readable
54. use terminal
GUIs are prison balls of developers
it’s ok to use GUIs while checking diffs,
resolving conflicts and viewing commit graph
BUTTON ADDICT ANTI-PATTERN
7
ANTIPATTERN DANGER
55. do not lose
take extra care while using hard reset
$ git reset --merge HEAD~
Use stash $ git stash save “updates local settings to keep db safe”
$ git reset --hard HEAD~
$ git stash apply stash@{0}
Create a new branch $ git checkout -b feature/PA-121
$ git add settings.xml
$ git commit -m “adds new settings config”
Use hard reset
with merge
and commit into it
uncommited changes
CODE LOSING SYNDROME ANTI-PATTERN
8
ANTIPATTERN DANGER
56. TOPIC
HEAD
MASTER
$ git merge --squash fix
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested
$ git add .
$ git commit -m “adds a feature”
$ git branch -D topic
TRASH HOUSE ANTI-PATTERN
9
long living branches with care
handle
ANTIPATTERN DANGER
Squash all commits in your topic branch and
make them available in working copy
57. long living branches with care
handle
TOPIC
HEAD
MASTER
$ git merge --squash fix
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested
$ git add .
$ git commit -m “adds a feature”
$ git branch -D topic
Squash all commits in your topic branch and
make them available in working copy
58. stop adding
prevent commits from being big ball of muds
every change
OMNIBUS BILL ANTI-PATTERN
10
ANTIPATTERN DANGER
61. messages
are
read!
# WHAT
# <issue id> (this commit will...) <subject>
# WHY and HOW
# Explain why this change is being made
# RELATED
# Provide links or keys to any relevant issues or other resources
# REMEMBER
# use lower case in the subject line
# start with a verb in imperative tone in the subject line
# do not end the subject line with a period
# separate subject from body with a blank line
# use the body to explain what and why vs. how
# can use multiple lines with "-" for bullet points in body
$ git config --global commit.template ~/.git-commit-template.txt
$ git config --global commit.cleanup strip
use git commit
templates to
create be"er
commit messages
comtmi
F*CKING COMMIT MESSAGES ANTI-PATTERN
11
ANTIPATTERN DANGER
63. by adding new commits ?
do you rollback your mistakes
ANTIPATTERN DANGER
12MESS UP WITH THE ROLLBACK ANTI-PATTERN
64. hard reset the merge commit
$ git reset --hard HEAD~
if you haven't pushed yet
HEAD
MASTER
Bug fıx
65. never force push
and change the history
if you already pushed to shared branch
Bug fıx
HEAD
MASTER
66. revert the merge commit
$ git revert 8f937c6 -m 1
if you already pushed
Bug fıx
HEAD
MASTER
67. is not the only method
pushing commits to server
ANTIPATTERN DANGER
for sharing your code
13CENTRALIZED GIT ANTI-PATTERN
68. Git Pong Pairing
$ git remote add personA <URL>
$ git fetch personA
$ git checkout personA/master
$ git checkout -b feature/PA-231
add your changes and commit
$ git push personA feature/PA-231
A B
$ git checkout feature/PA-231
add your changes and commit
$ git pull personA feature/PA-231
69. with the ones in source
branch ?
how do you sync your commits
ANTIPATTERN DANGER
14MERGE FANATIC ANTI-PATTERN
83. Depend on each other
Too many repositories
ANTIPATTERN DANGER
for sharing your code
17WEB OF REPOSITORIES ANTI-PATTERN
84. Mono Repository
System
Even though our services are still developed and deployed
independently, the code for all services lives in one
repository
The repository contains more than one logical project (e.g.
an iOS client and a web-application)
These projects are most likely unrelated, loosely
connected or can be connected by other means (e.g via
dependency management tools)
Twi#er, Facebook, Google, Digital Ocean,
Foursquare, Etsy, Shippable, Plataformatec, Ravelin
85. You can not do CI without using monorepos
- Xebia
“When you start a new project,” Potvin tells WIRED, “you
have a wealth of libraries already available to you. Almost
everything has already been done.”
- Rachel Potvin, Engineering Manager at Google
Our productivity has increased at least 5x.
- Shippable
86. v1, v2, v3…
having branch for every release
ANTIPATTERN DANGER
18ORACLE SYNDROME ANTI-PATTERN
at the same time
87. Commit early & o"en
perfect later, publish
once philosophy
Deploy frequently
be prepared to send
every single commit
Newer keep release
branches for a long time
master branch should be
enough for all your needs
88. to git repo
you pushed confidential info
ANTIPATTERN DANGER
19WAITING FOR HACKERS ANTI-PATTERN
96. hard reset
committed
Track ediliyor
untracked unmodified pushedmodified
staged
Staging Alanında Local Repoda Uzak Repoda
added
hard reset
hard reset
mixed reset
mixed reset
soft reset
rm --cached
rm
x
111. are you scared of using rebase?
ANTIPATTERN DANGER
26REBASE-FOBIA ANTI-PATTERN
112. rebasenot to merge your unpushed
commits with the fetched ones
use pull with
prepared by @lemiorhan
rebaseto get rebased commits
from upstream safely
use pull with
REBASEfeature branches to integrate
into public branches
that you pushed
or that you pulled
from another person
Never use Rebase
USE
113. do you know when we get
conflicts and how to resolve it?
ANTIPATTERN DANGER
27CONFLICT-FOBIA ANTI-PATTERN
117. master
TAG/v1.1
login
HEAD
DETACHED HEAD STATE
$ git checkout cecd95914
Note: checking out 'cecd95914'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
LIVING AT DETACHED HEAD STATE ANTI-PATTERN
28
ANTIPATTERN DANGER
121. master
TAG/v1.1
login
HEAD
$ git reflog
aa67e3a2c HEAD@{0}: rebase finished: returning to refs/heads/fix/java-sql-Date-violates-LSR
aa67e3a2c HEAD@{1}: rebase: fixes UnsupportedOperationException while calling toIstant() method of java.sql.Date
a45f3c4e5 HEAD@{2}: rebase: checkout develop
630ddad6e HEAD@{3}: checkout: moving from develop to fix/java-sql-Date-violates-LSR
b26cf7a1a HEAD@{4}: rebase: checkout develop
630ddad6e HEAD@{5}: checkout: moving from develop to fix/java-sql-Date-violates-LSR
b26cf7a1a HEAD@{6}: pull: Fast-forward
8b59f8f50 HEAD@{7}: checkout: moving from fix/java-sql-Date-violates-LSR to develop
122. $ git reflog
630ddad6e
the one we are
searching for
master
TAG/v1.1
login
HEAD
aa67e3a2c HEAD@{0}: rebase finished: returning to refs/heads/fix/java-sql-Date-violates-LSR
aa67e3a2c HEAD@{1}: rebase: fixes UnsupportedOperationException while calling toIstant() method of java.sql.Date
a45f3c4e5 HEAD@{2}: rebase: checkout develop
630ddad6e HEAD@{3}: checkout: moving from develop to fix/java-sql-Date-violates-LSR
b26cf7a1a HEAD@{4}: rebase: checkout develop
630ddad6e HEAD@{5}: checkout: moving from develop to fix/java-sql-Date-violates-LSR
b26cf7a1a HEAD@{6}: pull: Fast-forward
8b59f8f50 HEAD@{7}: checkout: moving from fix/java-sql-Date-violates-LSR to develop