S C M
Source of Complete Mortification
Source Control Mamangement system
commit ----------REDACTED------------- Author: REDACTED Date: Fri Nov 4 17:06:46 2016 -0700 very important feature!
commit ----------REDACTED------------- Author: REDACTED Date: Fri Nov 4 20:47:59 2016 -0700 fix tests
commit ----------REDACTED------------- Author: REDACTED Date: Fri Nov 4 23:08:13 2016 -0700 Up JVM heap size for tests to prevent OOM (Deja vu moment - we do this every year or so ...)
commit ----------REDACTED------------- Author: REDACTED Date: Fri Nov 4 23:32:03 2016 -0700 more test fixes
commit ----------REDACTED------------- Author: REDACTED Date: Fri Nov 4 23:37:44 2016 -0700 moar test fixes
commit ----------REDACTED------------- Author: REDACTED Date: Sat Nov 5 00:09:31 2016 -0700 very important feature! ... finally
commit ----------REDACTED------------- Author: kenegozi Date: Sat Nov 5 00:09:31 2016 -0700 very important feature! ... finally
a fast, scalable, distributed revision control system with an unusually rich command set that provides both high-level operations and full access to internals.
it's in the README so it must be true
also in the README
replicable, versionable, highly-available, fault-tolerant, eventually-consistent, distributed object database
replicable, versionable, highly-available, fault-tolerant, eventually-consistent, distributed object database source control manager
finally git made simple ?
L O L
me? using git 15-ε years ! . . . not a pro
yet for me it's been working better than printouts zip files SourceSafe SourceGear Mercurial Subversion TFS

a clever way of using branches for tracking and managing commits
a clever way of using branches post-it notes for tracking and managing commits changes
not in the README
not in any official documentation
not accurate
a point in time
what is the current content?
how did we get here?
A A: My first commit! diff: +a.txt parents:[ ] Files: └── a.txt
A <- B B: My second commit! diff: +b.txt parents:[ A ] Files: ├── a.txt └── b.txt
A <- B <- C C: Ready for release! diff: +c.txt parents:[ B ] Files: ├── a.txt ├── b.txt └── c.txt
DAG (Directed Acyclic Graph) of commits representing a progression of content deltas through history
how are we doing on "made simple"?
a movable, auto-advancing post-it note referencing a specific commit in the graph
*main ↓ A
*main
↓
A <- B
[main] $ git commit
*main
↓
A <- B <- C
[main] $ git commit
*main
↓
A <- B <- C
*names
↓
A <- B <- C
*derp
↓
A <- B <- C
*main
↓
A <- B <- C
main
↓
A <- B <- C
↑
*feature
[main] $ git checkout -b feature
[feature] $
main
↓
A <- B <- C <- D
↑
*feature
[feature] $ git commit
moving a branch pointer to a different commit, covering current and merged-with branch history
$ git man merge--ff --no-ff --ff-only
*main
↓
A <- B <- C <- D
↑
feature
[main] $
*main
↓
A <- B <- C <- D
↑
feature
[main] $ git merge feature --ff-only
*main
↓
A <- B <- C <- D
↑
feature
[main] $
*main
↓
A <- B <- C <- E
↖
D
↑
feature
[main] $ git commit
main
↓
A <- B <- C <- E
↖ ↖
D <- F
↑
*feature
[main] git checkout feature
[feature] $ git merge main
A <- B <- C <- E *main
↖ ↖ ↙
D <- F
↑
feature
[feature] $ git checkout main
[main] $ git merge feature
$ git man merge--ff --no-ff --ff-only
serializing (and rewriting) history
working concurrenty, exploring linearly
main
↓
A <- B <- C <- E
↖
D
↑
*feature
[feature] $
added a.txt
added b.txt
added c.txt
added d.txt
added e.txt
but what if ...
added a.txt
added b.txt
added c.txt
added e.txt
added d.txt
main
↓
A <- B <- C <- E <- D'
↖ ↑
D *feature
[feature] $ git rebase main
main
↓
A <- B <- C <- E <- D'
↖ ↑
D *feature
D: diff: +cool-feature, parents: [ C ]
D': diff: +cool-feature, parents: [ E ]
*main
↓
A <- B <- C <- E <- D'
↖ ↑
D feature
[feature] $ git checkout main
[main] $ git merge feature --ff-only
main
↓
A <- B <- F
↖
C <- D <- E
↑
*feature
main
↓
A <- B <- F <- C'
↖ ↖
C <- D <- E *feature
[feature] $ git rebase main
main
↓
A <- B <- F <- C' <- D'
↖ ↑
C <- D <- E *feature
[feature] $ git rebase main
main
↓
A <- B <- F <- C' <- D' <- E'
↖ ↑
C <- D <- E *feature
[feature] $ git rebase main

[somebranch] $ checkout REF => HEAD = REF [current] $ checkout COMMIT_HASH => HEAD = &COMMIT_HASH [current] $ checkout -b feature => var feature = current [current] $ reset REF => HEAD = current = REF [current] $ reset COMMIT => HEAD = current = &COMMIT

git gui and gitk are your friends
three-way merge tools (KDIFF3, p4merge, etc)
git is great
history is graph of commits
branches and tags are post-it notes
keep calm and gitk
@kenegozi
linkedin.com/in/kenegozi
github.com/kenegozi