5. DVCS makes life better!
• Less time fighting your tool,
More time writing code!
• Less time figuring out what happened,
More time solving the problem.
6. SVN, The Straight Jacket
SVN is a single source system. Everybody speaks to the central repository, and every
check-in and check-out is put and made from there.
To check code in, you must have a network connection, and a route to the server.
A check-in cannot occur if the branch has diverged, a merge is required, though it's
called an update, and SVN doesn't keep any knowledge that it was actually a merge!
SVN
Server
Klag Marie Joe
• Check-outs are slow
• Commits are infrequent
• Branching causes a checkout to pull all the files over again
Infrequent commits lead to gargantuan merges, which suck in any system, and SVN's merge tools aren't great.
Expensive branch check-out makes developers reluctant to branch
7. DVS - The general proposition
Each repository in a DVCS (Distributed Version Control System) has a complete revision history
for any branch that is present, including remotely tracked branches (mostly).
For Git, having a single server that everybody synchronizes
with, is just one of a few potential configurations. This is the
model that is used most frequently in a corporate environment. Git
Remote
This gives a single place that can be managed including things
like back-ups and high-availability.
This model allows for a few things that make life
for developers significantly better:
• Frequent commits
• Horizontal change-set sharing
• Commits without internet connectivity
• Branches retain all comments and context
especially around merges
Klag Marie
8. Git - Emerging as the leading DVCS
• Git designed and initially built by Linus Torvalds
• Designed to manage the codebase for the Linux kernel
Why is it called git?
• Linus jokes that he names programs after himself.
• Git is a British English term that roughly means a person who is somewhat
arrogant, obnoxious and slightly sadistic.
• Linus hates wasting time having to merge many many changes every day, so
he made git as fast as possible, and he knows the kernel, so it is very fast.
Very very fast, all network transfers are heavily compressed, large merges
happen with sub-second response time on UNIXish OSes generating fewer
conflicts than other systems
Extremely powerful functionality:
• Cheap branching and merging
• Guarenteed data integrity
• Selective commits
• Sophisticating merging algorithms
• Stashing
• Multiple merge strategies that can merge multiple branches
• Fast diffs
• Patchset generation
• Compact Syntax
• Cherry Picking
• Rebasing
• Branch Filtering
• SVN Porting tools!
10. Get the code from the remote repository
git clone http://github.com/foo
What happened?
Remote Server
Local System
Checkout Clone
Working Copy Local Remote
On a clone, git assumes Remote git packs
you also want local files,
so does a checkout. Remote's HEAD gets copied to local,
which is a branch labelled "master".
HEAD is a descriptor that references the last element of a branch in a repository that is
the current branch.
11. Sending changes back to the repository
Add Commit Push
Remote Server
Local System
Commit Push
Working Copy
git clone http://github.com/foo Local Remote
Add files: What justCommit:
happened? Push local to remote: Remote git packs
git add git commit -m git push
file1.txt src/main "Added some files" origin master
12. Filling in a Few Gaps
The Index is git's log of what's going on. It contains a list of files and their
state relative to HEAD.
Local System
Index
Commit
Add
Remote Server
Checkout Push
Working Copy Local Remote
Commit Fetch
13. What is a Branch?
master 8a63a7
test 76f43a
master test
8a63a7 76f43a 8a63a7 76f43a
26df25c 463e5c 26df25c
463e5c
6c75877 6c75877
26a562c 26a562c
A revision keeps track of its predecessor(s).
This is how a branch is defined, a successive set of revisions that have a
common ancestor. The lineage is given a label, and that is a reference to
the branch. It isn't a name per se, it's a reference or pointer. You can
change the label, or move it, but the underlying branch lineage doesn't
change.
14. Pushing Changes - A Fast Forward
When there are only a single person's changes being sent upstream, it's pretty easy.
This operation is described as a fast-forward
Local System Remote Server
Push
Local Remote
8a63a7 8a63a7
463e5c Fast Forward 463e5c
6c75877 6c75877
Common Ancestor 26a562c 26a562c
15. Divergent branches
When you try to push, and the remote has been updated since you last fetched, it will reject your push
Local System Remote Server
Push
Local Remote
6c75877 463e5c
26a562c 26a562c
The two branches have a common ancestor, but a divergent HEAD. Pushing to a remote branch must be a "fast-
forward". This means that the current revision on the remote, must be an ancestor of your current HEAD. When
this occurs, what transpires is described as a fast-forward.
16. Retrieving and Merging
Local System Remote Server
Fetch
Local Remote
6c75877 463e5c
26a562c 26a562c
Show the difference:
git diff --stat origin/master
Retrieve the changes: Perform the Merge:
git fetch git merge origin/master
Show the difference detail:
git diff origin/master
17. Merging - What happens
26a562c 6c75877
master
Merge
26a562c 463e5c
8a63a7
origin/master
When a merge occurs, git uses one of the merge strategies to resolve differences:
• resolve 3-way merge that is good at detecting crisscross merges, doesn't do renames
• recursive
• ours conflicts are resolved with our version
• theirs conflicts are resolved with their version
• patience takes a bit more time, good for merging highly divergent branches
• renormalize pre-flight normalization for things like line-endings
• no-renormalize disable the previous
• subtree[=<path>] merge knowing that one branch is in a subdirectory of the other
• octopus merge more than two branches
• ours merge taking our history exclusively
• subtree less granular subdirectory merge
18. Merge Outcome - What does it look like?
origin/master master
The revision 8a63a7 has two predecessors
• 6c75877
• 463e5c
8a63a7
463e5c 6c75877
26a562c
19. Conflict Conflagration!
When there are intersecting changes that can't be resolved by
the merge tool
Manual intervention is required!
6c75877
master
Conflict!
Merge Index Working Copy
origin/
master
463e5c
20. The Index keeps track of the status of things
Index Query the index to find out if there's more left to merge
git status
Add files to indicate they are merged
git add poem.txt
Working Copy
Commit files once they've all been merge and push
Fix poem.txt git commit -m "Merged, dropped Klag's changes"
Index Still conflicted?
Fix index.html
Index Still conflicted?
Nope
Add
Working Copy Index
Commit
master Remote
Push
21. I totally fubared the Merge!
You can get back to pre-merge state with a reset:
get reset --hard HEAD
6c75877 - HEAD
26a562c
reset
master
working working
Index files files
26a562c 463e5c
conflicted local changes
origin/master
This also works for reverting changes
22. Ammending a Commit
• I wrote a message, but it was crap
• I forgot to add some files
master
amend
26a562c 8a63a7 463e5c
Amending a commit after pushing will result in a conflict!
You created a new revision, with a new hash, and the remote has your old
commit as HEAD which isn't an ancestor for your local master so a push is no
longer a fast-foward
All is not lost though, you can fetch and merge like normal
23. Good Git Usage
Use .gitignore
• It contains a list of patterns for files to ignore
Always add explicitly, never use git commit -a, or git add.
Always check your status with git status before you commit
• If you commit hastily and push too quick, you'll end up
with files that shouldn't be there!