{"thread":{"id":"17028","subject":"Comments on Presentation Notes Request.","startedAt":"2009-01-06T22:33:02Z","lastAt":"2009-01-09T13:50:40Z","messageCount":10,"participants":["Tim Visher","Jeff King","david@lang.hm","Daniel Barkalow","Boyd Stephen Smith Jr.","Jakub Narebski"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"99516","messageId":"c115fd3c0901061433i78bf3b26v77e5981aada6728e@mail.gmail.com","threadId":"17028","inReplyTo":null,"subject":"Comments on Presentation Notes Request.","fromName":"Tim Visher","fromEmail":"tim.visher@gmail.com","sentAt":"2009-01-06T22:33:02Z","receivedAt":"2009-01-06T22:33:02Z","isPatch":false,"sender":{"key":"tim.visher@gmail.com","avatar":"https://gravatar.com/avatar/98307ce54bcac1a46b5d845827d5386e2a27895ff08790cdd3877ad527760575?d=mp&s=160"},"body":"Hello Everyone,\n\nI'm putting together a little 15 minute presentation for my company\nregarding SCMSes in an attempt to convince them to at the very least\nuse a Distributed SCMS and at best to use git.  I put together all my\nnotes, although I didn't put together the actual presentation yet.  I\nfigured I'd post them here and maybe get some feedback about it.  Let\nme know what you think.\n\nThanks in advance!\n\nNotes\n---------\n\nSCM: Distributed, Centralized, and Everything in Between.\n\n* What is SCM and Why is it Useful?\n\n** Definition\n\nSCM is the practice of committing the revisions of your source code to\na system that can faithfully reproduce historical snap shots of your\nsource code.\n\n** Advantages of SCM\n\n*** One Source to Rule Them All.\n\nInstead of having a bunch of source files spread across multiple\ndevelopers machines with multiple versions on each machine that may or\nmay not be labeled correctly, you have one repository containing every\nartifact that your project includes.\n\n*** Unlimited Undo/Redo.\n\nNot only is it unlimited, but it's random access.  If you changed a\nfunction a week ago, continued to work, and then decide that you want\nthe function back the way it was, it's as simple as pulling the\nfunction back out of the SCMS.\n\n*** Safe Concurrent Editing.\n\nMany people can edit the same code base at the same time and know,\nwithout a doubt, that when they pull all those changes together, the\nsystem will merge the content intelligently or inform you of the\nconflict and let you merge it.  You don't need to lock files.\nObviously, if there is bad coordination then the possibilities of\nconflicts rise, but this should not happen regularly.\n\n*** Diff Debugging\n\nYou can find where a bug was introduced by learning how to reproduce\nthe bug and then doing a binary chop search back through the History\nto come to the exact commit that introduced the bug.\n\n* SCM Best Practices\n\n** Commit Early, Commit Often\n\nThe more you commit, the more fine grained control you have over the\nundo feature of SCM.  Most documents that I have read suggested a TDD\napproach wherein you commit whenever you have written just enough code\nfor your test to pass. But...\n\n** Don't Commit Broken Code (To the Public Tree)\n\nOf primary concern is the fact that your central HEAD should _always_\nbuild.  This is why practices like Continuous Integration and TDD are\nso important.  TDD gives you the freedom to be sure that a change you\nmade hasn't broken anything you weren't expecting it to break.\nContinuous Integration allows you to be sure that your whole system\nwill build every time.  Thus, you should _never_ commit broken code to\nthe (public) tree.\n\nOf course, in a centralized system, committing is intrinsically\npublic.  Even on branches, every time you commit any sort of change,\neveryone is able to see it and so you could be breaking the build for\nsomeone (even if it's just yourself and the build system).  One of the\nnice features of a distributed system is that your public/private\nontology is much richer and thus allows you to have broken code in\nyour SCMS.\n\n** Whole Hog\n\nYou should put everything necessary to build your system into SCM.\nThis includes user documentation, requirements documentation, software\ntools, build tools, etc.  The only artifacts that don't need to be\nmanaged are auto-generated artifacts such as javadocs, jar files, exe\nfiles, etc.  This is so that you can reproduce entire releases using\nonly a simple checkout.\n\n** Perform Updates and Commits on the Whole Tree\n\nUpdates and Commits should always be done on the whole tree so that\nyou're sure you have the latest source.  Never assume that nothing has\nchanged elsewhere.\n\n** Allow and Encourage Customer Participation\n\nMost shops seem to attempt to funnel customer participation through\nthe developers.  This is a cache miss for many operations such as\ndeveloping the user manual by a design team external to the\ndevelopment team.  Basic operations such as commit and update are\nfairly simple to grasp and can even be simplified further through\nscripts and other such tools that non-developers can quickly be taught\nto use.\n\nOf note is the Tortoise family of tools which integrate directly into\nWindows Explorer.  This makes it fairly easy for anyone who is\nfamiliar with Windows Explorer to get into using any of the tools that\nthere is a Tortoise implementation for.\n\n* The Centralized Model\n\n** We Know About This One\n\nThis is traditional, plain vanilla, ubiquitous SCM.\n\nThe great majority of the SCMSes out there are centralized.\n\nClosely resembles the Client/Server system model.\n\n** Work Flow\n\n<http://whygitisbetterthanx.com/#any-workflow>\n\n*** 2 basic models: 'Lock, Modify, Unlock' and 'Copy, Modify, Merge'.\n\nOlder systems were primarily Lock, Modify, Unlock implementations.\nYou would checkout a file that you intended to work on, and no one\nelse would be able to check it out until you unlocked it, signaling\nthat you were done editing it.  This is inherently inefficient as on a\nteam of developers, the chances that two are working on the exact same\npart of a system without knowing it and coordinating are fairly low.\nAlso, any disparate features that still touch the same files in the\nsystem cannot be worked on simultaneously.\n\nThe answer to this is Copy, Modify, Merge.  In this system, every\ndeveloper gets a complete copy of the HEAD.  Everyone changes the HEAD\nconcurrently.  When commits happen, the system attempts to\nintelligently merge them.  If it fails (usually doesn't happen unless\nthere is bad coordination), then it asks you to merge them.  This has\nbeen proven to work well.\n\n** Key Properties\n\n*** Only One Repository\n\nIn centralized systems, there is only one global, public repository.\nThis has certain significant effects, such as an intrinsically global\nname space for branches and tags, a restrictive public/private concept\n(no such thing as committed but private), need for a backup process\naware of the possibility of in-progress commits, etc.\n\nSince the repository only exists in a single location, the developers\nonly have copies of a specific revision and any uncommitted changes\nthey've made to that copy.\n\n*** All Committed Changes Are Public\n\nThis includes regular commits (what we'd typically think of commits),\nbranches, and tags.\n\nAs previously mentioned, in centralized systems, all committed changes\nare public.  Even if you are working on a private branch (which you\ntypically wouldn't be because branches are expensive in centralized\nsystems), the changes you are making are still visible publicly\nbecause your branch exists in the global, public repository.\n\n*** Intrinsically Uses the Network.\n\nBecause you must have a single repository that all developers are\naccessing, you must use the network for many common operations.\nCommits must be made to the central repository, Logs live centrally,\nbranches live centrally, diffing between revisions is a network\noperation, blaming is a network operation, etc.\n\n*** Backup Becomes A Separate Process\n\nBecause there is only a single repository, you need a back-up strategy\nor else you are exposing yourself to a single point of failure.\nUnfortunately, this is not as simple as it sounds.  The global, public\nnature of the repository makes the chances of creating a corrupt back\nup very high.  Because of this, tools have grown up around and in many\ncentralized systems that automate the process of backing it up while\nremaining aware of the problems that can arise.  However, the point\nremains that there is no intrinsic back up of a centralized system.\n\n*** Need A Repository Admin.\n\nBecause the system is centralized, you need a repository\nadministrator.  This is true in most modern centralized systems where\nnew repositories are created on a per project basis (as in, not VSS).\nIn other words, when you want a new repository, you need to go through\nsome sort of admin interface or through the administrator of the\nrepository server to make it happen.\n\n* The Distributed Model\n\n** This Ones New\n\nAt least new as in unfamiliar.  The concept is over a decade old.\n\nThere are a few different popular distributed SCMSes (Git, Mercurial\n(hg), Bazaar (bzr), Bitkeeper)\n\nVery closely resembles a peer-to-peer network and the organic\nrelationships that evolve in that space.\n\nIn a distributed system, there is no one point where all development\ncomes together to for any reason other than policy.  Everyone who is\nworking on a system intrinsically has their own copy of the entire\nrepository.  All of the history, all of the source code, all of the\npublic branches, all of the public tags, etc.  Because of this,\ndevelopers can also have private branches, private tags, private\ncommits, private history.  The distinction between public and private\nis very important in this context.  This has several distinct features\nwhich I'll go into now.\n\n** Work Flow (Pick Your Poison)\n\n<http://whygitisbetterthanx.com/#any-workflow>\n\n** Key Properties\n\n*** Private/Public Concept\n\nDistributed SCMSes Private/Public ontology is __much__ richer.\nWhereas in a central system, private means only what you have yet to\ncommit or what you are leaving untracked, in a distributed system,\nprivate means anything that you have not yet _chosen_ to make public.\nIn other words, you can have private branches, private tags, private\ncommitted changes to your copy of the head, etc.  Anything that you do\nnot specifically publish to a location that others can access is\nintrinsically private.\n\nIn other words, you can finally SCM your sandbox!  You can commit as\nmany broken things as you want to a private repository, giving you the\nability to have a nearly infinite set of undoable and recoverable\nchanges, without breaking anyone else's build.  Or, you can just as\neasily ignore TDD, never commit anything for 3 weeks and then do a\nbig, massive commit and as long as your final product is tested and\nmerges with the rest of the tree, you're good to go and no one cares.\n\nBecause you have a rich ontology for private/public data, you can also\ndo crazy things like rewriting your local history before anyone else\nsees it.  Because your repository is the only one that has to know\nabout the history as long as you're dealing with private data, this is\na completely safe (although policy debatable) operation.  Of course,\nonce data has been published, you really shouldn't mess with its\nhistory anymore.\n\n*** Network(less)\n\nIn distributed systems, networks are optional for almost every\noperation (and indeed, every operation prior to publishing).  Of\ncourse, you could put your repository on a network drive and then\nyou'd be doing everything over the network like you would in a\ncentralized system, but if you put your repository clone on your local\nsystem, then everything you do in that repository is local.  Viewing\nyour history, committing, branching, merging, everything.\n\nOnce you've published, however, not much changes.  Almost everything\nexcept updating and publishing (_not_ committing) remains local.\nRemember that committing no longer means publicly publishing.  You can\ncommit many revisions, even to the master HEAD and nothing at all has\nbeen published until you push those changes to your public HEAD.\n\n*** Natural Backup\n\nBecause every developer has a copy of the repository, every developer\nyou add adds an extra failure point.  The more developers you have,\nthe more backups you have of the repository.\n\n*** Must Learn New Work Flows.\n\nIn order to fully experience the advantages of distributed systems,\nnew work flows must be learned.  In other words, it's possible to use\ndistributed systems nearly the exact same way as you use a centralized\nsystem (you just need to learn new commands), but you don't get many\nof the benefits except the speed improvements.  The real game change\nhappens when you realize that you can keep things private until their\nfinished.  Once you realize that, new branching patterns emerge, new\nwork flows happen, you commit more often, and have the ability to\nbecome much looser and freer in your development process.\n\n*** Impossible To Completely Enforce A Single, Canonical\nRepresentation of the Code Base.\n\nBy nature, a distributed system cannot enforce a single canonical\nrepresentation of the code base except by policy, and policies can\nalways be broken.  Also, any intentionally private data is not backed\nup because it is not shared.  However, backup becomes much simpler\nbecause you know that no one else is committing to your repository.\n\nThis bears some explanation.  Within a distributed system, you can\nhave a single official release point that everyone has blessed (or the\ncompany has blessed, or the original developer has blessed, or\nwhatever).  However, you cannot _stop_ someone else from making a\nrelease point because their repository is just as valid as yours.  You\ncannot _stop_ developers from sharing code between themselves without\ngoing out to the official central location.  All you can do is ask\nthem not to.\n\n* Why Git is the Best Choice\n\n** Fast\n\nGit's implementation just happens to be wickedly fast.  It's faster\nthan mercurial, it's faster than bazaar, etc.  Everything, committing,\nmerging, viewing history, branching, and even updating and and pushing\nare all faster.\n\n** Tracks Content, not Files\n\nGit tracks content, not files, and it's the only SCMS at the moment\nthat does this.  This has many effects internally, but the most\napparent effect I know of is that for the first time Git can easily\ntell you the history of even a function in a file because Git can tell\nyou which files that function existed (or does exist) in over the\ncourse of development.\n\n** Extremely Efficient.\n\nBecause Git tracks content, it can also be extremely efficient\nspacewise, simplifying the files to be nothing but pointers to a set\nof objects in Git's internal file system.  Thus, if you have\nduplicated hunks, git uses a single object to represent them.  Git has\nbeen proven to be more efficient space wise than any other system out\nthere.\n\n** (Un)Staged Changes\n\nGit employs the concept of the Index or Cache or Commit Stage.  This\nis also unique to Git, and it's pretty strange for developers coming\nfrom a system without it.\n\nBasically, There are 4 states that any content can be in under Git.\n\n1. Untracked: This is content that Git is completely unaware of.\n2. Tracked but Unstaged: This is content that has changed that Git is\naware of but will not commit on the next commit command.\n3. Tracked and Staged: This is the same as unstaged except that this\ncontent will be committed on the next commit.\n4. Tracked and Committed:  This is content that has not changed since\nthe previous commit that Git is aware of.\n\nThis is very powerful yet somewhat awkward to grasp.  Basically, the\nupshot of this feature is that you can manually build commits if you\nwant to.  Say you were working on feature foo and then made some other\nchanges because you came across feature bar and thought it would be\nquick to do.  In any other system, the only way you could commit parts\nof what you'd changed is if you were lucky enough for the disparate\nchanges to be in different files.  In that case, you could commit only\nthe files that you wanted to change for the different features.\nHowever, if you made disparate changes to the same file, you were\nstuck.  In Git, you can stage only parts of the files to an extreme\ndegree.  This allows you to create as many commits as you want out of\na single change set until the whole change set is committed.\n\nI've found this to be particularly useful when working with an\nexisting code base that was not properly formatted.  Often, I'll come\nto a file that has a bunch of wonky white space choices and improperly\nindented logical constructs and I'll just quickly run through it\ncorrecting that stuff before continuing with the feature I was working\non.  Afterwords, I'll stage the formatting and commit it, and then\nstage the feature I was working on and commit that.  You may not want\nthat kind of control (and if you don't, you don't need to use it), but\nI like it.\n\n** Excellent Merge algorithms\n\nGit has excellent merge algorithms.  This is widely attributed and\ndoesn't require much explanation.  It was one of Git's original design\ngoals, and it has been proven by Git's implementation.  Merging in Git\nis _much_ less painful than in other systems.\n\n** Has powerful 'maintainer tools'\n\nBeyond the basics of committing, updating, pushing, viewing logs, etc.\nGit is known to have very powerful tools maintainer level tools.  You\ncan modify your history, you can automatically perform binary searches\nto locate errors, you can communicate via patches, it's highly\ncustomizable, has the concept of submodules (projects within\nprojects), etc.  It gets complicated, but at this level of SCM it is\ncomplicated.\n\n** Cryptographically Guarantees Content\n\nOne of the most surprising things I learned as I was researching this\nwas that most SCMSes do not guarantee that your content does not get\ncorrupted.  In other words, if the repository's disk doesn't fail but\ninstead just gets corrupted, you'll never know unless you actually\nnotice the corruption in the files.  If you have memory corruption\nlocally and commit your changes, you just won't know.\n\nGit guarantees absolutely that if corruption happens, you will know\nabout it.  It does this by creating SHA-1 hashes of your content and\nthen checking to make sure that the SHA-1 hash does not change for an\nobject.  The details of this aren't as important as the fact that Git\nis one of the very few systems that do this and it's obviously\ndesirable.\n\n* References\n\n- <http://git-scm.com/> - The Git homepage\n- <http://whygitisbetterthanx.com/> - An excellent resource explaining\nthe benefits of using git in relation to other common SCMSes\n- <http://www.youtube.com/watch?v=4XpnKHJAok8> - Linus Torvalds's\nGoogle Talk on Git.  Covers mainly what Git is Not and Why\nDistribution is the model that works.\n- <http://www.youtube.com/watch?v=8dhZ9BXQgc4> - Randal Schwartz's\nGoogle Talk on Git.  Covers what Git is, including some implementation\ndetails, some use case scenarios, and the like.\n- <http://book.git-scm.com/> - A community written book on Git with\nvideo tutorials about many of Git's features.\n- <http://subversion.tigris.org/> - Subversion's homepage.  An\nextremely popular open source centralized system.\n- <http://svnbook.red-bean.com/> - Rolling publish book on Subversion.\n Chapter 1 is a good introduction to general centralized SCM concepts\nand principles.\n- <http://www.perforce.com/perforce/bestpractices.html> - An excellent\nset of best practices from the Perforce team.  Some of it (especially\nthe branches) has a distinct centralized lean, but most of it is quite\ngood.\n- <http://www.bobev.com/PresentationsAndPapers/Common%20SCM%20Patterns.pdf>\n- Interesting presentation by Pretzel Logic from 2001 attempting to\noutline some common SCM best practices as Patterns.\n\n---------------\nEnd Notes\n\n-- \n\nIn Christ,\n\nTimmy V.\n\nhttp://burningones.com/\nhttp://five.sentenc.es/ - Spend less time on e-mail\n"},{"id":"99547","messageId":"20090107063629.GB22616@coredump.intra.peff.net","threadId":"17028","inReplyTo":"c115fd3c0901061433i78bf3b26v77e5981aada6728e@mail.gmail.com","subject":"Re: Comments on Presentation Notes Request.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-01-07T06:36:29Z","receivedAt":"2009-01-07T06:36:29Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Jan 06, 2009 at 05:33:02PM -0500, Tim Visher wrote:\n\n> ** Advantages of SCM\n> *** One Source to Rule Them All.\n> *** Unlimited Undo/Redo.\n> *** Safe Concurrent Editing.\n> *** Diff Debugging\n\nI would add to this metadata and \"software archeology\": finding the\nauthor of a change or piece of code, the motivation behind it, related\nchanges (by position within history, by content, or by commit message),\netc.\n\nI think people who have not used an SCM before, and people coming from\nSCMs where it is painful to look at history (like CVS) undervalue this\nbecause it's not part of their workflow.  But having used git for a few\nyears now, it is an integral part of how I develop (especially when\ndoing maintenance or bugfixes).\n\nYou touch on this in \"Diff Debugging\", but I think bisection is just a\npart of it.\n\n> * SCM Best Practices\n>\n> ** Commit Early, Commit Often\n> ** Don't Commit Broken Code (To the Public Tree)\n\nPeople talk a lot about using their SCM on a plane, but I think these\ntwo seemingly opposite commands highlight the _real_ useful thing about\na distributed system for most people: commit and publish are two\nseparate actions.\n\nSo I think it might be better to say \"Commit Early, Commit Often\" but\n\"Don't _Publish_ Broken Code\". Which is what you end up saying in the\ndiscussion, but I think using that terminology makes clear the important\ndistinction between two actions that are convoluted in centralized\nsystems.\n\n> *** Backup Becomes A Separate Process\n> Because there is only a single repository, you need a back-up strategy\n> or else you are exposing yourself to a single point of failure.\n> [...]\n> *** Natural Backup\n> Because every developer has a copy of the repository, every developer\n> you add adds an extra failure point.  The more developers you have,\n> the more backups you have of the repository.\n\nThe \"natural backup\" thing gets brought out a lot for DVCS. And it is\nsort of true: instead of each developer having a backup of the latest\nversion (or some recent version which they checked out), they have a\nbackup of the whole history. But they still might not have everything.\nDevelopers might not clone all branches. They might not be up to date\nwith some \"master\" repository. Useful work might be unpublished in the\nmaster repo (e.g., I am working on feature X which is 99% complete, but\nnot ready for me to merge into master and push).\n\nSo yes, you are much more likely to salvage useful (if not all) data\nfrom developer repositories in the event of a crash. But I still think\nit's crazy not to have a backup strategy for your DVCS repo.\n\n> ** Fast\n> \n> Git's implementation just happens to be wickedly fast.  It's faster\n> than mercurial, it's faster than bazaar, etc.  Everything, committing,\n> merging, viewing history, branching, and even updating and and pushing\n> are all faster.\n\nA lot of people say \"So what? System X is fast enough for me already.\"\nAnd I used to be one of them. But one point I have made in similar talks\nis that it isn't just about shaving a few seconds off your task. It's\nabout being able to ask fundamentally different questions because they\ncan be answered in seconds, not minutes or hours. I haven't benchmarked,\nbut I shudder at the thought of pickaxe (git log -S), code movement in\nblame, or bisecting in CVS.\n\n> ** Excellent Merge algorithms\n> \n> Git has excellent merge algorithms.  This is widely attributed and\n> doesn't require much explanation.  It was one of Git's original design\n> goals, and it has been proven by Git's implementation.  Merging in Git\n> is _much_ less painful than in other systems.\n\nActually, git has a really _stupid_ merge algorithm that has been around\nforever: the 3-way merge. And by stupid I don't mean bad, but just\nsimple and predictable. I think the git philosophy is more about making\nit easy to merge often, and about making sure conflicts are simple to\nunderstand and fix, than it is about being clever.\n\nWhich isn't to say there aren't systems with less clever merge\nalgorithms. CVS doesn't even do a 3-way merge, since it doesn't bother\nto remember where the last branch intersection was.\n\nBTW, I think Junio's 2006 OLS talk has some nice pictures of a 3-way\nmerge which help to explain it (see slides 23-32):\n\n  http://members.cox.net/junkio/200607-ols.pdf\n\n\nThat's just my two cents from skimming over your notes. Hope it helps.\n\n-Peff\n"},{"id":"99552","messageId":"alpine.DEB.1.10.0901070030320.31038@asgard.lang.hm","threadId":"17028","inReplyTo":"c115fd3c0901061433i78bf3b26v77e5981aada6728e@mail.gmail.com","subject":"Re: Comments on Presentation Notes Request.","fromName":"","fromEmail":"david@lang.hm","sentAt":"2009-01-07T08:33:09Z","receivedAt":"2009-01-07T08:33:09Z","isPatch":false,"sender":{"key":"david@lang.hm","avatar":null},"body":"On Tue, 6 Jan 2009, Tim Visher wrote:\n\n> *** Natural Backup\n>\n> Because every developer has a copy of the repository, every developer\n> you add adds an extra failure point.  The more developers you have,\n> the more backups you have of the repository.\n\nthis needs to be re-worded. 'extra failure point' can be read to mean \nredundancy in what would otherwide be a single point of failure, but it \ncan also mean another point where things can fail.\n\nsomething like 'every developer adds an extra layer of redundancy' would \nbe much less ambiguous.\n\nDavid Lang\n"},{"id":"99591","messageId":"c115fd3c0901070811x323e51e4r1aae3021e6f431aa@mail.gmail.com","threadId":"17028","inReplyTo":"alpine.DEB.1.10.0901070030320.31038@asgard.lang.hm","subject":"Re: Comments on Presentation Notes Request.","fromName":"Tim Visher","fromEmail":"tim.visher@gmail.com","sentAt":"2009-01-07T16:11:43Z","receivedAt":"2009-01-07T16:11:43Z","isPatch":false,"sender":{"key":"tim.visher@gmail.com","avatar":"https://gravatar.com/avatar/98307ce54bcac1a46b5d845827d5386e2a27895ff08790cdd3877ad527760575?d=mp&s=160"},"body":"Thanks for the suggestions so far.  I've updated the notes.\n\n@Peff: Thanks especially for pointing me towards Junio's\npresentatation.  That's an excellent source.\n\nHere's the patch for your suggestions:\n\ndiff --git a/scmOutline.txt b/scmOutline.txt\nindex 1791fa0..d25198c 100644\n--- a/scmOutline.txt\n+++ b/scmOutline.txt\n@@ -1,4 +1,4 @@\n-SCM: Distributed, Centralized, and Everything in Between.\n\n+SCM: Centralized, Distributed, and Everything in Between.\n\n\n\n * What is SCM and Why is it Useful?\n\n\n\n@@ -20,7 +20,11 @@ Not only is it unlimited, but it's random access.\nIf you changed a function a w\n\n\n Many people can edit the same code base at the same time and know,\nwithout a doubt, that when they pull all those changes together, the\nsystem will merge the content intelligently or inform you of the\nconflict and let you merge it.  You don't need to lock files.\nObviously, if there is bad coordination then the possibilities of\nconflicts rise, but this should not happen regularly.\n\n\n\n-*** Diff Debugging\n\n+*** Software Archeology\n\n+\n\n+With a proper SCMS, it becomes a somewhat trivial operation to\ndiscover the author and reasons for a given change.  This is because\nof the rich metadata associated with commits (author, date, complete\nchange set, diffs, and commentary).  So rather than wandering asking\nif anyone remembers doing something and why, you simply commit that\ninformation into the system and then refer to it when you need to.\n\n+\n\n+**** Diff Debugging\n\n\n\n You can find where a bug was introduced by learning how to reproduce\nthe bug and then doing a binary chop search back through the History\nto come to the exact commit that introduced the bug.\n\n\n\n@@ -30,11 +34,11 @@ You can find where a bug was introduced by\nlearning how to reproduce the bug and\n\n\n The more you commit, the more fine grained control you have over the\nundo feature of SCM.  Most documents that I have read suggested a TDD\napproach wherein you commit whenever you have written just enough code\nfor your test to pass. But...\n\n\n\n-** Don't Commit Broken Code (To the Public Tree)\n\n+** Don't _Publish_ Broken Code\n\n\n\n Of primary concern is the fact that your central HEAD should _always_\nbuild.  This is why practices like Continuous Integration and TDD are\nso important.  TDD gives you the freedom to be sure that a change you\nmade hasn't broken anything you weren't expecting it to break.\nContinuous Integration allows you to be sure that your whole system\nwill build every time.  Thus, you should _never_ commit broken code to\nthe (public) tree.\n\n\n\n-Of course, in a centralized system, committing is intrinsically\npublic.  Even on branches, every time you commit any sort of change,\neveryone is able to see it and so you could be breaking the build for\nsomeone (even if it's just yourself and the build system).  One of the\nnice features of a distributed system is that your public/private\nontology is much richer and thus allows you to have broken code in\nyour SCMS.\n\n+Of course, in a centralized system, committing is intrinsically\npublic.  Even on branches, every time you commit any sort of change,\neveryone is able to see it and so you could be breaking the build for\nsomeone (even if it's just yourself and the build system).  One of the\nnice features of a distributed system is that your public/private\nontology is much richer and thus allows you to have broken code in\nyour SCMS, so long as you haven't published it, at no penalty to\nanyone but yourself.\n\n\n\n ** Whole Hog\n\n\n\n@@ -130,7 +134,9 @@ Once you've published, however, not much changes.\nAlmost everything except upda\n\n\n *** Natural Backup\n\n\n\n-Because every developer has a copy of the repository, every developer\nyou add adds an extra failure point.  The more developers you have,\nthe more backups you have of the repository.\n\n+Because every developer has a copy of the repository, every developer\nyou add adds an extra layer of redundancy.  The more developers you\nhave, the more backups you have of the repository.\n\n+\n\n+An important point to make clear here is that you only are backing up\nwhat everyone is duplicating.  If you have 10 unpublished branches\nthat no one else has cloned, then those are obviously not backed up.\nHowever, the idea here would be that anything that is being developed\nactively by multiple people is backed up by as many developers.  Other\nthan that, your private data must be backed up by you (which is what\nyou do anyway, right? ;).\n\n\n\n *** Must Learn New Work Flows.\n\n\n\n@@ -148,6 +154,8 @@ This bears some explanation.  Within a distributed\nsystem, you can have a single\n\n\n Git's implementation just happens to be wickedly fast.  It's faster\nthan mercurial, it's faster than bazaar, etc.  Everything, committing,\nmerging, viewing history, branching, and even updating and and pushing\nare all faster.\n\n\n\n+This is much more important than just shaving a few seconds off the\noperations.  Because Git is so much faster, you begin to do things\ndifferently because of how fast it is.  Git's blazing fast branching\nand merging wouldn't matter at all if you never branched and merged\n(which is possible), but because their blazing fast you _should_ begin\nto branch and merge much more often, which __does__ fundamentally\nchange the way you develop your code (hopefully for the better).\n\n+\n\n ** Tracks Content, not Files\n\n\n\n Git tracks content, not files, and it's the only SCMS at the moment\nthat does this.  This has many effects internally, but the most\napparent effect I know of is that for the first time Git can easily\ntell you the history of even a function in a file because Git can tell\nyou which files that function existed (or does exist) in over the\ncourse of development.\n\n@@ -171,9 +179,9 @@ This is very powerful yet somewhat awkward to\ngrasp.  Basically, the upshot of t\n\n\n I've found this to be particularly useful when working with an\nexisting code base that was not properly formatted.  Often, I'll come\nto a file that has a bunch of wonky white space choices and improperly\nindented logical constructs and I'll just quickly run through it\ncorrecting that stuff before continuing with the feature I was working\non.  Afterwords, I'll stage the formatting and commit it, and then\nstage the feature I was working on and commit that.  You may not want\nthat kind of control (and if you don't, you don't need to use it), but\nI like it.\n\n\n\n-** Excellent Merge algorithms\n\n+** Stupid but _Fast_ Merge Algorithms\n\n\n\n-Git has excellent merge algorithms.  This is widely attributed and\ndoesn't require much explanation.  It was one of Git's original design\ngoals, and it has been proven by Git's implementation.  Merging in Git\nis _much_ less painful than in other systems.\n\n+Merging in Git is _much_ less painful than in other systems.  This is\nmainly because of how fast it is and how much data it remembers when\nit does a merge.  As opposed to CVS which can't merge a branch twice\nbecause it doesn't remember where the last merge happened, Git keeps\ntrack of that information so you can merge between branches as much as\nyou want.  Git's philosophy is to make merging as fast and painless as\npossible so that you merge early and often enough to not develop\nreally bad conflicts that are nearly impossible to resolve.\n\n\n\n ** Has powerful 'maintainer tools'\n\n\n\n@@ -196,3 +204,4 @@ Git guarantees absolutely that if corruption\nhappens, you will know about it.  I\n - <http://svnbook.red-bean.com/> - Rolling publish book on\nSubversion.  Chapter 1 is a good introduction to general centralized\nSCM concepts and principles.\n\n - <http://www.perforce.com/perforce/bestpractices.html> - An\nexcellent set of best practices from the Perforce team.  Some of it\n(especially the branches) has a distinct centralized lean, but most of\nit is quite good.\n\n - <http://www.bobev.com/PresentationsAndPapers/Common%20SCM%20Patterns.pdf>\n- Interesting presentation by Pretzel Logic from 2001 attempting to\noutline some common SCM best practices as Patterns.\n\n+- <http://members.cox.net/junkio/200607-ols.pdf> - A presentation by\nJunio Hamano (the Git maintainer) at a Linux symposium on what Git is\nwith some tutorials.\n\n\nI've also attached it as a file.  It was generated by `git diff -p`.\n\nI'm also looking for anyplace where I'm technically inaccurate.\nUnfortunately, I've written a lot of this from things that I've either\nread or heard.  I'm mainly experienced with VSS and Subversion (and\nboth of those to a very small degree), and making a lot of progress\nwith Git.  I've kind of been swept away by all the energy surrounding\ngit right now, though, so I'm sure my judgement is somewhat clouded.\n\nThanks again for your help!\n\n-- \n\nIn Christ,\n\nTimmy V.\n\nhttp://burningones.com/\nhttp://five.sentenc.es/ - Spend less time on e-mail\n"},{"id":"99622","messageId":"alpine.LNX.1.00.0901071654530.19665@iabervon.org","threadId":"17028","inReplyTo":"20090107063629.GB22616@coredump.intra.peff.net","subject":"Re: Comments on Presentation Notes Request.","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-01-07T22:30:04Z","receivedAt":"2009-01-07T22:30:04Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 7 Jan 2009, Jeff King wrote:\n\n> On Tue, Jan 06, 2009 at 05:33:02PM -0500, Tim Visher wrote:\n> \n> > ** Advantages of SCM\n> > *** One Source to Rule Them All.\n> > *** Unlimited Undo/Redo.\n> > *** Safe Concurrent Editing.\n> > *** Diff Debugging\n> \n> I would add to this metadata and \"software archeology\": finding the\n> author of a change or piece of code, the motivation behind it, related\n> changes (by position within history, by content, or by commit message),\n> etc.\n\nIf you look at the git source code, the comments in the code are almost \nnever sufficient to really understand the code, because a full \nline-by-line explanation would make it hard to find the code under the \ncomments. On the other hand, if you take \"git blame\" in one window and a \nseries of \"git show\"s in another window, and look at the commit messages \nfor the commits that introduced each of those lines, you get really \ndetailed and in-depth documentation of the subtle changes.\n\n> I think people who have not used an SCM before, and people coming from\n> SCMs where it is painful to look at history (like CVS) undervalue this\n> because it's not part of their workflow.  But having used git for a few\n> years now, it is an integral part of how I develop (especially when\n> doing maintenance or bugfixes).\n> \n> You touch on this in \"Diff Debugging\", but I think bisection is just a\n> part of it.\n> \n> > * SCM Best Practices\n> >\n> > ** Commit Early, Commit Often\n> > ** Don't Commit Broken Code (To the Public Tree)\n> \n> People talk a lot about using their SCM on a plane, but I think these\n> two seemingly opposite commands highlight the _real_ useful thing about\n> a distributed system for most people: commit and publish are two\n> separate actions.\n> \n> So I think it might be better to say \"Commit Early, Commit Often\" but\n> \"Don't _Publish_ Broken Code\". Which is what you end up saying in the\n> discussion, but I think using that terminology makes clear the important\n> distinction between two actions that are convoluted in centralized\n> systems.\n> \n> > *** Backup Becomes A Separate Process\n> > Because there is only a single repository, you need a back-up strategy\n> > or else you are exposing yourself to a single point of failure.\n> > [...]\n> > *** Natural Backup\n> > Because every developer has a copy of the repository, every developer\n> > you add adds an extra failure point.  The more developers you have,\n> > the more backups you have of the repository.\n> \n> The \"natural backup\" thing gets brought out a lot for DVCS. And it is\n> sort of true: instead of each developer having a backup of the latest\n> version (or some recent version which they checked out), they have a\n> backup of the whole history. But they still might not have everything.\n> Developers might not clone all branches. They might not be up to date\n> with some \"master\" repository. Useful work might be unpublished in the\n> master repo (e.g., I am working on feature X which is 99% complete, but\n> not ready for me to merge into master and push).\n\nIt is the case that everything in the central repo (including speculative \nstuff) will also be on its author's machine, with the metadata needed to \nidentify that it's not in the main history and how everything is supposed \nto be arranged. This is likely to be particularly helpful for the work \nthat everybody did between the last backup and the crash.\n\n> So yes, you are much more likely to salvage useful (if not all) data\n> from developer repositories in the event of a crash. But I still think\n> it's crazy not to have a backup strategy for your DVCS repo.\n\nI think it's very important to have a backup strategy, but it's nice that \nthe developers can get work done while the server is still down.\n\n> > ** Excellent Merge algorithms\n> > \n> > Git has excellent merge algorithms.  This is widely attributed and\n> > doesn't require much explanation.  It was one of Git's original design\n> > goals, and it has been proven by Git's implementation.  Merging in Git\n> > is _much_ less painful than in other systems.\n> \n> Actually, git has a really _stupid_ merge algorithm that has been around\n> forever: the 3-way merge. And by stupid I don't mean bad, but just\n> simple and predictable. I think the git philosophy is more about making\n> it easy to merge often, and about making sure conflicts are simple to\n> understand and fix, than it is about being clever.\n\nGit is clever about finding the 3 inputs to the 3-way merge, particularly \nthe common ancestor of commits that don't have a common ancestor. I think \nmerge-recursive is novel to git, and may not be available anywhere else.\n\n> Which isn't to say there aren't systems with less clever merge\n> algorithms. CVS doesn't even do a 3-way merge, since it doesn't bother\n> to remember where the last branch intersection was.\n\nCVS did do 3-way merge, but only between your uncommited changes, the \nlatest commit, and the common ancestor (the commit that you started \nchanging). IIRC, arch actually didn't support 3-way merge at all.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"99623","messageId":"200901071640.06288.bss@iguanasuicide.net","threadId":"17028","inReplyTo":"alpine.LNX.1.00.0901071654530.19665@iabervon.org","subject":"Re: Comments on Presentation Notes Request.","fromName":"Boyd Stephen Smith Jr.","fromEmail":"bss@iguanasuicide.net","sentAt":"2009-01-07T22:40:02Z","receivedAt":"2009-01-07T22:40:02Z","isPatch":false,"sender":{"key":"bss@iguanasuicide.net","avatar":"https://gravatar.com/avatar/84b95eeff194b816c1568b1339e63e4b229825298664a9037b9f1ec713ead1e3?d=mp&s=160"},"body":"On Wednesday 2009 January 07 16:30:04 Daniel Barkalow wrote:\n> Git is clever about finding [...]\n> the common ancestor of commits that don't have a common ancestor.\n\n*confused*\n\nPlease elaborate.\n-- \nBoyd Stephen Smith Jr.                     ,= ,-_-. =. \nbss@iguanasuicide.net                     ((_/)o o(\\_))\nICQ: 514984 YM/AIM: DaTwinkDaddy           `-'(. .)`-' \nhttp://iguanasuicide.net/                      \\_/     \n"},{"id":"99638","messageId":"alpine.LNX.1.00.0901071731050.19665@iabervon.org","threadId":"17028","inReplyTo":"c115fd3c0901061433i78bf3b26v77e5981aada6728e@mail.gmail.com","subject":"Re: Comments on Presentation Notes Request.","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-01-08T00:14:35Z","receivedAt":"2009-01-08T00:14:35Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 6 Jan 2009, Tim Visher wrote:\n\n> Hello Everyone,\n> \n> I'm putting together a little 15 minute presentation for my company\n> regarding SCMSes in an attempt to convince them to at the very least\n> use a Distributed SCMS and at best to use git.  I put together all my\n> notes, although I didn't put together the actual presentation yet.  I\n> figured I'd post them here and maybe get some feedback about it.  Let\n> me know what you think.\n> \n> Thanks in advance!\n> \n> Notes\n> ---------\n> \n> SCM: Distributed, Centralized, and Everything in Between.\n> \n> * SCM Best Practices\n> \n> ** Allow and Encourage Customer Participation\n> \n> Most shops seem to attempt to funnel customer participation through\n> the developers.  This is a cache miss for many operations such as\n> developing the user manual by a design team external to the\n> development team.  Basic operations such as commit and update are\n> fairly simple to grasp and can even be simplified further through\n> scripts and other such tools that non-developers can quickly be taught\n> to use.\n> \n> Of note is the Tortoise family of tools which integrate directly into\n> Windows Explorer.  This makes it fairly easy for anyone who is\n> familiar with Windows Explorer to get into using any of the tools that\n> there is a Tortoise implementation for.\n\nI still want an office software package with \"commit\" instead of \"save\" \n(when in a repository), and a mail program with \"push\" instead of \"attach\" \nand \"fetch\" instead of \"open\". (See below)\n\nI think that the sales department should be using distributed version \ncontrol, neatly packaged up.\n\n> * The Centralized Model\n> \n> ** We Know About This One\n> \n> This is traditional, plain vanilla, ubiquitous SCM.\n> \n> The great majority of the SCMSes out there are centralized.\n> \n> Closely resembles the Client/Server system model.\n> \n> ** Work Flow\n> \n> <http://whygitisbetterthanx.com/#any-workflow>\n> \n> *** 2 basic models: 'Lock, Modify, Unlock' and 'Copy, Modify, Merge'.\n> \n> Older systems were primarily Lock, Modify, Unlock implementations.\n> You would checkout a file that you intended to work on, and no one\n> else would be able to check it out until you unlocked it, signaling\n> that you were done editing it.  This is inherently inefficient as on a\n> team of developers, the chances that two are working on the exact same\n> part of a system without knowing it and coordinating are fairly low.\n> Also, any disparate features that still touch the same files in the\n> system cannot be worked on simultaneously.\n> \n> The answer to this is Copy, Modify, Merge.  In this system, every\n> developer gets a complete copy of the HEAD.  Everyone changes the HEAD\n> concurrently.  When commits happen, the system attempts to\n> intelligently merge them.  If it fails (usually doesn't happen unless\n> there is bad coordination), then it asks you to merge them.  This has\n> been proven to work well.\n\nGit is almost unique in that, at the point where the user is asked to do a \nmerge, the user's work is already preserved.\n\nThat is, most systems are: Copy, Modify, Merge, Commit. Git is: Copy, \nModify, Commit, Merge.\n\n> * The Distributed Model\n> \n> ** This Ones New\n> \n> At least new as in unfamiliar.  The concept is over a decade old.\n\nIn some fundamental ways, this actually resembles the \"broadcast email\" \ncollaboration method. That is, a group is writing a document. Someone \nwrites a skeleton, and emails it to everybody else. They make changes to \ndifferent sections. When each person has changed something, they email the \nfull document to everybody else. Before people send out their \nversions, they check their email and (painfully) merge the changes into \nwhat they've done.\n\nThis evolved into having a certain location to avoid the painful merge, \nand then to version control. Distributed systems go back to this model, \nexcept without the \"(painfully)\" and with all the other benefits of \nversion control.\n\n> There are a few different popular distributed SCMSes (Git, Mercurial\n> (hg), Bazaar (bzr), Bitkeeper)\n> \n> Very closely resembles a peer-to-peer network and the organic\n> relationships that evolve in that space.\n> \n> In a distributed system, there is no one point where all development\n> comes together to for any reason other than policy.  Everyone who is\n> working on a system intrinsically has their own copy of the entire\n> repository.  All of the history, all of the source code, all of the\n> public branches, all of the public tags, etc.  Because of this,\n> developers can also have private branches, private tags, private\n> commits, private history.  The distinction between public and private\n> is very important in this context.  This has several distinct features\n> which I'll go into now.\n> \n> ** Work Flow (Pick Your Poison)\n> \n> <http://whygitisbetterthanx.com/#any-workflow>\n> \n> ** Key Properties\n> \n> *** Private/Public Concept\n> \n> Distributed SCMSes Private/Public ontology is __much__ richer.\n> Whereas in a central system, private means only what you have yet to\n> commit or what you are leaving untracked, in a distributed system,\n> private means anything that you have not yet _chosen_ to make public.\n> In other words, you can have private branches, private tags, private\n> committed changes to your copy of the head, etc.  Anything that you do\n> not specifically publish to a location that others can access is\n> intrinsically private.\n> \n> In other words, you can finally SCM your sandbox!  You can commit as\n> many broken things as you want to a private repository, giving you the\n> ability to have a nearly infinite set of undoable and recoverable\n> changes, without breaking anyone else's build.  Or, you can just as\n> easily ignore TDD, never commit anything for 3 weeks and then do a\n> big, massive commit and as long as your final product is tested and\n> merges with the rest of the tree, you're good to go and no one cares.\n\nAlthough you'll be really sad if you accidentally wipe out your work after \n2 1/2 weeks...\n\n> Because you have a rich ontology for private/public data, you can also\n> do crazy things like rewriting your local history before anyone else\n> sees it.  Because your repository is the only one that has to know\n> about the history as long as you're dealing with private data, this is\n> a completely safe (although policy debatable) operation.  Of course,\n> once data has been published, you really shouldn't mess with its\n> history anymore.\n\nYou can also see this as writing a new history. If you knew starting out \neverything that you knew when you finished, you might do things \ndifferently, and the results would likely be more useful. Writing a new \nhistory lets you start over from where you started, while being able to \nrefer to the final working state that you came up with.\n\n> *** Must Learn New Work Flows.\n> \n> In order to fully experience the advantages of distributed systems,\n> new work flows must be learned.  In other words, it's possible to use\n> distributed systems nearly the exact same way as you use a centralized\n> system (you just need to learn new commands), but you don't get many\n> of the benefits except the speed improvements.  The real game change\n> happens when you realize that you can keep things private until their\n> finished.  Once you realize that, new branching patterns emerge, new\n> work flows happen, you commit more often, and have the ability to\n> become much looser and freer in your development process.\n\nMy experience bring git to a small company is that people don't need to \nlearn new workflows. They can go on with their old workflows and develop \nnew ones as they streamline their work. The one exception is really that \nthey have to be told that, in git, you commit before merging instead of \nmerging before committing.\n\n> *** Impossible To Completely Enforce A Single, Canonical\n> Representation of the Code Base.\n> \n> By nature, a distributed system cannot enforce a single canonical\n> representation of the code base except by policy, and policies can\n> always be broken.  Also, any intentionally private data is not backed\n> up because it is not shared.  However, backup becomes much simpler\n> because you know that no one else is committing to your repository.\n> \n> This bears some explanation.  Within a distributed system, you can\n> have a single official release point that everyone has blessed (or the\n> company has blessed, or the original developer has blessed, or\n> whatever).  However, you cannot _stop_ someone else from making a\n> release point because their repository is just as valid as yours.  You\n> cannot _stop_ developers from sharing code between themselves without\n> going out to the official central location.  All you can do is ask\n> them not to.\n\nAnd you might not want to ask them not to. It's really nice to be able to \nreassign a developer to a different task and pass that developer's \nincomplete and not-ready-for-prime-time work to somebody else.\n\n> * Why Git is the Best Choice\n> \n> ** (Un)Staged Changes\n> \n> Git employs the concept of the Index or Cache or Commit Stage.  This\n> is also unique to Git, and it's pretty strange for developers coming\n> from a system without it.\n> \n> Basically, There are 4 states that any content can be in under Git.\n> \n> 1. Untracked: This is content that Git is completely unaware of.\n> 2. Tracked but Unstaged: This is content that has changed that Git is\n> aware of but will not commit on the next commit command.\n> 3. Tracked and Staged: This is the same as unstaged except that this\n> content will be committed on the next commit.\n> 4. Tracked and Committed:  This is content that has not changed since\n> the previous commit that Git is aware of.\n\n1, 4, and something in between are normal; the only extra is \ndistinguishing 2 and 3.\n\n> This is very powerful yet somewhat awkward to grasp.  Basically, the\n> upshot of this feature is that you can manually build commits if you\n> want to.  Say you were working on feature foo and then made some other\n> changes because you came across feature bar and thought it would be\n> quick to do.  In any other system, the only way you could commit parts\n> of what you'd changed is if you were lucky enough for the disparate\n> changes to be in different files.  In that case, you could commit only\n> the files that you wanted to change for the different features.\n> However, if you made disparate changes to the same file, you were\n> stuck.  In Git, you can stage only parts of the files to an extreme\n> degree.  This allows you to create as many commits as you want out of\n> a single change set until the whole change set is committed.\n\nIt's pretty common for a system to support:\n\n$ (sys) commit <filenames...>\n\nAt its core, the index just lets you tell git about those files on \nmultiple command lines instead of just one. And it lets you make \nunincluded changes after you give it a file but before you commit. And it \nlets you fabricate the contents that you're putting in. But really, it's \nabout being able to list the things to include one-by-one. (Well, really, \nit's about being able to make 100 commits of a 30000-file project in under \na second, but that's just the original inspiration.)\n\n> I've found this to be particularly useful when working with an\n> existing code base that was not properly formatted.  Often, I'll come\n> to a file that has a bunch of wonky white space choices and improperly\n> indented logical constructs and I'll just quickly run through it\n> correcting that stuff before continuing with the feature I was working\n> on.  Afterwords, I'll stage the formatting and commit it, and then\n> stage the feature I was working on and commit that.  You may not want\n> that kind of control (and if you don't, you don't need to use it), but\n> I like it.\n> \n> ** Cryptographically Guarantees Content\n> \n> One of the most surprising things I learned as I was researching this\n> was that most SCMSes do not guarantee that your content does not get\n> corrupted.  In other words, if the repository's disk doesn't fail but\n> instead just gets corrupted, you'll never know unless you actually\n> notice the corruption in the files.  If you have memory corruption\n> locally and commit your changes, you just won't know.\n>\n> Git guarantees absolutely that if corruption happens, you will know\n> about it.  It does this by creating SHA-1 hashes of your content and\n> then checking to make sure that the SHA-1 hash does not change for an\n> object.  The details of this aren't as important as the fact that Git\n> is one of the very few systems that do this and it's obviously\n> desirable.\n\nYou can still get a situation where the content gets corrupted before it \ngets into git, and git happily tracks your corrupt content. But that's \npretty obvious.\n"},{"id":"99639","messageId":"alpine.LNX.1.00.0901071914490.19665@iabervon.org","threadId":"17028","inReplyTo":"200901071640.06288.bss@iguanasuicide.net","subject":"Re: Comments on Presentation Notes Request.","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-01-08T00:28:17Z","receivedAt":"2009-01-08T00:28:17Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 7 Jan 2009, Boyd Stephen Smith Jr. wrote:\n\n> On Wednesday 2009 January 07 16:30:04 Daniel Barkalow wrote:\n> > Git is clever about finding [...]\n> > the common ancestor of commits that don't have a common ancestor.\n> \n> *confused*\n> \n> Please elaborate.\n\nI meant to say \"a *unique* closest common ancestor\". The clever trick is \nthat, if there are multiple common ancestors which aren't closer than each \nother, you can merge those ancestors (based, recursively, on their common \nancestors) to generate a new commit with merge conflicts in it. You then \npretend that this commit is the unique common ancestor for 3-way merge. \nThis works because the merge conflicts in the commit all seem to have been \nreplaced in each branch, and the conflict region is some arbitrary chunk \nof text in between other context, and the 3-way merge output doesn't show \nthe original text (which would be weird junk in this case: a merge \nconflict that didn't really happen in the middle of other merge \nconflicts), but only the text from the two sides being merged, so it's not \nnecessary to resolve the old merge that didn't happen.\n\nI think all of the other systems, if you have crossing history such that \nthere isn't a unique common ancestor do one of: (a) give up, (b) generate \nconflicts between your change as it stayed in your branch and the same \nchange as it went out and came back, or (c) mishandle some cases involving \nreverts.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"99692","messageId":"20090108095603.GA16136@coredump.intra.peff.net","threadId":"17028","inReplyTo":"alpine.LNX.1.00.0901071654530.19665@iabervon.org","subject":"Re: Comments on Presentation Notes Request.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-01-08T09:56:03Z","receivedAt":"2009-01-08T09:56:03Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jan 07, 2009 at 05:30:04PM -0500, Daniel Barkalow wrote:\n\n> > So yes, you are much more likely to salvage useful (if not all) data\n> > from developer repositories in the event of a crash. But I still think\n> > it's crazy not to have a backup strategy for your DVCS repo.\n> \n> I think it's very important to have a backup strategy, but it's nice that \n> the developers can get work done while the server is still down.\n\nI think everything you said in your email was correct, and I agree with\nit, but I just wanted to clarify one thing about what I said.\n\nI really _do_ think you are better off in a disaster or backup situation\nwith a DVCS. Both this past year and 2007, Junio dropped off the face of\nthe git planet for a few weeks, and everyone seamlessly switched to\nShawn as maintainer. So I think of the DVCS model almost more as \"high\navailablity\": even if you model your workflow around a central server,\nit's easy to route around the failure.\n\nIt's just that I don't think these features totally _replace_ backups as\na concept. And I feel like that notion creeps up now and again in the\ncentralized versus distributed holy wars.\n\nSo I think we agree; I just wasn't sure if I gave the wrong impression\nfrom my first email.\n\n-Peff\n"},{"id":"99791","messageId":"m31vvc37x0.fsf@localhost.localdomain","threadId":"17028","inReplyTo":"c115fd3c0901061433i78bf3b26v77e5981aada6728e@mail.gmail.com","subject":"Re: Comments on Presentation Notes Request.","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-01-09T13:50:40Z","receivedAt":"2009-01-09T13:50:40Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"\"Tim Visher\" <tim.visher@gmail.com> writes:\n\n> Hello Everyone,\n> \n> I'm putting together a little 15 minute presentation for my company\n> regarding SCMSes in an attempt to convince them to at the very least\n> use a Distributed SCMS and at best to use git.  I put together all my\n> notes, although I didn't put together the actual presentation yet.  I\n> figured I'd post them here and maybe get some feedback about it.  Let\n> me know what you think.\n> \n> Thanks in advance!\n\nTake a look at the following links:\n * \"Understanding Version-Control Systems (DRAFT)\" by Eric Raymond\n   http://www.catb.org/esr/writings/version-control/version-control.html\n * \"Version Control Habits of Effective Developers\" at The Daily Build\n   http://blog.bstpierre.org/version-control-habits\n\nNote that the first one is DRAFT; on the other hand it explains\nlock-edit, merge-then-commit, and commit-then-merge workflows quite\nwell, and has a host of links.\n   \n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"}]}