DVCS makes life better!• Less time ﬁghting your tool, More time writing code!• Less time ﬁguring out what happened, More time solving the problem.
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 its called an update, and SVN doesnt 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 ﬁles over againInfrequent commits lead to gargantuan merges, which suck in any system, and SVNs merge tools arent great.Expensive branch check-out makes developers reluctant to branch
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 synchronizeswith, is just one of a few potential conﬁgurations. This is themodel that is used most frequently in a corporate environment. Git RemoteThis gives a single place that can be managed including thingslike back-ups and high-availability.This model allows for a few things that make lifefor developers signiﬁcantly better: • Frequent commits • Horizontal change-set sharing • Commits without internet connectivity • Branches retain all comments and context especially around merges Klag Marie
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 conﬂicts than other systemsExtremely 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!
Get the code from the remote repository git clone http://github.com/foo What happened? Remote ServerLocal System Checkout Clone Working Copy Local Remote On a clone, git assumes Remote git packs you also want local ﬁles, so does a checkout. Remotes 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.
Sending changes back to the repository Add Commit Push Remote ServerLocal System Commit Push Working Copy git clone http://github.com/foo Local Remote Add ﬁles: 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
Filling in a Few Gaps The Index is gits log of whats going on. It contains a list of ﬁles and their state relative to HEAD.Local System Index Commit Add Remote Server Checkout Push Working Copy Local Remote Commit Fetch
What is a Branch? master 8a63a7 test 76f43a master test8a63a7 76f43a 8a63a7 76f43a 26df25c 463e5c 26df25c463e5c6c75877 6c7587726a562c 26a562c A revision keeps track of its predecessor(s). This is how a branch is deﬁned, 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 isnt a name per se, its a reference or pointer. You can change the label, or move it, but the underlying branch lineage doesnt change.
Pushing Changes - A Fast Forward When there are only a single persons changes being sent upstream, its pretty easy. This operation is described as a fast-forward Local System Remote Server Push Local Remote 8a63a7 8a63a7 463e5c Fast Forward 463e5c 6c75877 6c75877Common Ancestor 26a562c 26a562c
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 26a562cThe 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. Whenthis occurs, what transpires is described as a fast-forward.
Retrieving and Merging Local System Remote Server Fetch Local Remote 6c75877 463e5c 26a562c 26a562c Show the difference: git diff --stat origin/masterRetrieve the changes: Perform the Merge:git fetch git merge origin/master Show the difference detail: git diff origin/master
Merging - What happens 26a562c 6c75877 master Merge 26a562c 463e5c 8a63a7 origin/masterWhen a merge occurs, git uses one of the merge strategies to resolve differences: • resolve 3-way merge that is good at detecting crisscross merges, doesnt do renames • recursive • ours conﬂicts are resolved with our version • theirs conﬂicts are resolved with their version • patience takes a bit more time, good for merging highly divergent branches • renormalize pre-ﬂight 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
Merge Outcome - What does it look like?origin/master master The revision 8a63a7 has two predecessors • 6c75877 • 463e5c 8a63a7 463e5c 6c75877 26a562c
Conﬂict Conﬂagration! When there are intersecting changes that cant be resolved by the merge tool Manual intervention is required!6c75877master Conﬂict! Merge Index Working Copyorigin/master463e5c
The Index keeps track of the status of things Index Query the index to ﬁnd out if theres more left to merge git status Add ﬁles to indicate they are merged git add poem.txt Working Copy Commit ﬁles once theyve all been merge and push Fix poem.txt git commit -m "Merged, dropped Klags changes"Index Still conﬂicted? Fix index.htmlIndex Still conﬂicted? Nope Add Working Copy Index Commit master Remote Push
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 ﬁles ﬁles 26a562c 463e5c conﬂicted local changes origin/masterThis also works for reverting changes
Ammending a Commit • I wrote a message, but it was crap • I forgot to add some ﬁles master amend 26a562c 8a63a7 463e5cAmending a commit after pushing will result in a conﬂict!You created a new revision, with a new hash, and the remote has your oldcommit as HEAD which isnt an ancestor for your local master so a push is nolonger a fast-fowardAll is not lost though, you can fetch and merge like normal
Good Git UsageUse .gitignore • It contains a list of patterns for ﬁles to ignoreAlways 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, youll end up with ﬁles that shouldnt be there!