<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Developer Tools &#8211; BetterExplained</title>
	<atom:link href="https://betterexplained.com/articles/series/devtools/feed/" rel="self" type="application/rss+xml" />
	<link>https://betterexplained.com</link>
	<description>Math lessons that click</description>
	<lastBuildDate>Thu, 17 Sep 2026 23:28:31 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>Aha! Moments When Learning Git</title>
		<link>https://betterexplained.com/articles/aha-moments-when-learning-git/</link>
					<comments>https://betterexplained.com/articles/aha-moments-when-learning-git/#disqus_thread</comments>
		
		<dc:creator><![CDATA[kalid]]></dc:creator>
		<pubDate>Wed, 10 Mar 2010 16:00:45 +0000</pubDate>
				<category><![CDATA[Guides]]></category>
				<category><![CDATA[Programming]]></category>
		<guid isPermaLink="false">http://betterexplained.com/?p=603</guid>

					<description><![CDATA[Git is a fast, flexible but challenging distributed version control system. Before jumping in: Understand regular version control Understand distributed version control Along with a book , tutorial and cheatsheet , here are the insights that helped git click. There's a staging area! Git has a staging area. Git has a staging area!!! Yowza, did [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Git is a fast, flexible but challenging distributed version control system. Before jumping in:</p>

<ul>
<li><a href="https://betterexplained.com/articles/a-visual-guide-to-version-control/" title="https://betterexplained.com/articles/a-visual-guide-to-version-control/">Understand regular version control</a></li>
<li><a href="https://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/" title="https://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/">Understand distributed version control</a></li>
</ul>

<p>Along with a <a href="http://progit.org/book/" title="http://progit.org/book/">book</a>, <a href="http://www.eecs.harvard.edu/~cduan/technical/git/" title="http://www.eecs.harvard.edu/~cduan/technical/git/">tutorial</a> and <a href="http://jonas.nitro.dk/git/quick-reference.html" title="http://jonas.nitro.dk/git/quick-reference.html">cheatsheet</a>, here are the insights that helped git click.</p>

<h2>There's a staging area!</h2>

<p>Git has a staging area. <strong>Git has a staging area!!!</strong></p>

<p>Yowza, did this ever confuse me. There's both a repo ("object database") and a staging area (called "index"). Checkins have two steps:</p>

<ul>
<li><code>git add foo.txt</code>

<ul>
<li>Add foo.txt to the index. It's not checked in yet!</li>
</ul></li>
<li><code>git commit -m "message"</code>

<ul>
<li>Put staged files in the repo; they're now tracked</li>
<li>You can "<code>git add --update"</code> to stage all tracked, modified files</li>
</ul></li>
</ul>

<p><strong>Why stage?</strong> Git's flexible: if a, b and c are changed, you can commit them separately or together.</p>

<p>But now there's two undos:</p>

<ul>
<li><code>git checkout foo.txt</code>

<ul>
<li>Undo local changes (like svn revert)</li>
</ul></li>
<li><code>git reset HEAD foo.txt</code>

<ul>
<li>Remove from staging area (local copy still modified).</li>
</ul></li>
</ul>

<p>Add and commit, add and commit -- Git has a rhythm.</p>

<h2>Branching is "Save as..."</h2>

<p>Branches are like "Save as..." on a directory. Best of all:</p>

<ul>
<li>Easily merge changes with the original (changes tracked and never applied twice)</li>
<li>No wasted space (common files only stored once)</li>
</ul>

<p><strong>Why branch?</strong> Consider the utility of "Save as..." for regular files: you tinker with multiple possibilities while keeping the original safe. Git enables this for directories, with the power to merge. (In practice, svn is like a single shared drive, where you can only revert to one backup).</p>

<h2>Imagine virtual directories</h2>

<p>I see branches as "virtual directories" in the .git folder. While inside a physical directory (c:\project or ~/project), you traverse virtual directories with a checkout.</p>

<ul>
<li><code>git checkout master</code>

<ul>
<li>switch to master branch ("cd master")</li>
</ul></li>
<li><code>git branch dev</code>

<ul>
<li>create new branch from existing ("cp * dev")</li>
<li>you still need to "cd" with "git checkout dev"</li>
</ul></li>
<li><code>git merge dev</code>

<ul>
<li>(when in master) pull in changes from dev ("cp dev/* .")</li>
</ul></li>
<li><code>git branch</code>

<ul>
<li>list all branches ("ls")</li>
</ul></li>
</ul>

<p>My inner dialogue is "change to dev directory (checkout)... make changes... save changes (add/commit)... change to master directory... copy in changes from dev (merge)".</p>

<p>The physical directory is a scratchpad. Virtual directories are affected by git commands:</p>

<ul>
<li><code>rm foo.txt</code>

<ul>
<li>Remove foo.txt from your sandbox (restored if you checkout the branch again)</li>
</ul></li>
<li><code>git rm foo.txt</code>

<ul>
<li>Remove foo.txt from current virtual directory</li>
<li>Gotcha: you need to commit that change!</li>
</ul></li>
</ul>

<h2>Know the current branch</h2>

<p>Just like seeing your current directory, <strong>put the current branch in your prompt!</strong></p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/git/git_prompt.png" alt="git branch highlighting" /></p>

<p>In my .bash_profile:</p>

<pre><code>parse_git_branch() {
    git branch 2&gt; /dev/null | sed -e '/^[^*]/d' -e 's/* (.*)/(1)/'
}

export PS1="[33[00m]u@h[33[01;34m] W [33[31m]$(parse_git_branch) [33[00m]$[33[00m] "
</code></pre>

<h2>Visualize your branch structure</h2>

<p>Git leaves branch organization to you. Nvie.com has a <a href="http://nvie.com/git-model" title="http://nvie.com/git-model">great branch strategy</a>:</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/git/git_branch_strategy.png" alt="Aha! Moments When Learning Git" class="webpexpress-processed"></p>

<ul>
<li>Have a mainline (master). Mentally it's on the far right.</li>
<li>Create branches (master -> dev) and subbranches (dev -> featureX). The further from master, the crazier.</li>
<li>Only merge with neighbors (master -> dev -> feature X, or featureX -> dev -> master)</li>
</ul>

<p>Stay sane by choosing a branch layout up front. I have a master tracking a svn project, and dev for my own code. In general, master is clean so I can branch anytime for one-off fixes.</p>

<h2>Understand local vs. remote</h2>

<p>Git has local and remote commands; seeing both confused me ("When do you checkout vs. pull?"). Work locally, syncing remotely as needed.</p>

<p><strong>Local data</strong></p>

<ul>
<li><code>git init</code>

<ul>
<li>create local repo</li>
<li>use git add/commit/branch to work locally</li>
</ul></li>
</ul>

<p><strong>Remote data</strong></p>

<ul>
<li><code>git remote add name path-to-repo</code>

<ul>
<li>track a remote repo (usually "origin") from an existing repo</li>
<li>remote branches are "origin/master", "origin/dev" etc.</li>
</ul></li>
<li><code>git branch -a</code>

<ul>
<li>list all branches (remote and local)</li>
</ul></li>
<li><code>git clone path-to-repo</code>

<ul>
<li>create a new local git repo copied from a remote one</li>
<li>local master tracks remote master</li>
</ul></li>
<li><code>git pull </code>

<ul>
<li>merge changes from tracked remote branch (if in dev, pull from origin/dev)</li>
</ul></li>
<li><code>git push</code>

<ul>
<li>send changes to tracked remote branch (if in dev, push to origin/dev)</li>
</ul></li>
</ul>

<p><strong>Why local and remote?</strong> Subversion has central checkins, so you avoid committing unfinished work. With git, local commits are frequent and you only push when ready.</p>

<h2>GUIDs are GOOD</h2>

<p>Git addresses information by a hash (<a href="https://betterexplained.com/articles/the-quick-guide-to-guids/" title="https://betterexplained.com/articles/the-quick-guide-to-guids/">GUID</a>) of its contents. If two branches are the same, they have the same GUID (and vice versa).</p>

<p>Why's this cool? We can create branches independently, merge them, and have a common GUID. No central numbering needed. Usually, we just compare the first few digits: "Are you on a93?".</p>

<h2>Tips &amp; Tricks</h2>

<p>For your .gitconfig:</p>

<pre><code>[alias]
        ci = commit
        st = status
        co = checkout
        oneline = log --pretty=oneline
        br = branch
        la = log --pretty="format:%ad %h (%an): %s" --date=short
</code></pre>

<p>There are some GUI tools for git, but I prefer to learn via the command line. Git is opinionated software (which I like), and analogies help me understand its world view.</p>

]]></content:encoded>
					
					<wfw:commentRss>https://betterexplained.com/articles/aha-moments-when-learning-git/feed/</wfw:commentRss>
			<slash:comments>36</slash:comments>
		

			</item>
	<item>
		<title>Intro to Distributed Version Control (Illustrated)</title>
		<link>https://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/</link>
					<comments>https://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/#disqus_thread</comments>
		
		<dc:creator><![CDATA[kalid]]></dc:creator>
		<pubDate>Mon, 15 Oct 2007 07:00:39 +0000</pubDate>
				<category><![CDATA[Guides]]></category>
				<category><![CDATA[Programming]]></category>
		<guid isPermaLink="false">http://betterexplained.com/articles/a-visual-look-at-distributed-version-control/</guid>

					<description><![CDATA[Traditional version control helps you backup, track and synchronize files. Distributed version control makes it easy to share changes. Done right, you can get the best of both worlds: simple merging and centralized releases. Distributed? What’s wrong with regular version control? Nothing — read a visual guide to version control if you want a quick [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/distributed/distributed_logo.png" alt="Intro to Distributed Version Control (Illustrated)" class="webpexpress-processed"></p>

<p>Traditional version control helps you backup, track and synchronize files. Distributed version control makes it easy to share changes. Done right, you can get the best of both worlds: simple merging and centralized releases.</p>

<h2>Distributed? What’s wrong with regular version control?</h2>

<p>Nothing — read <a href="https://betterexplained.com/articles/a-visual-guide-to-version-control/">a visual guide to version control</a> if you want a quick refresher. Sure, <em>some people</em> will deride you for using an “ancient” system. But you’re still OK in my book: using <em>any</em> VCS is a positive step forward for a project.</p>

<p>Centralized <span class="caps">VCS </span>emerged from the 1970s, when programmers had thin clients and admired “big iron” mainframes (how can you <em>not</em> like a machine with a then-gluttonous <a href="https://en.wikipedia.org/wiki/System/360">8 bits to a byte</a>?).</p>

<p><strong>Centralized is simple</strong>, and what you’d first invent: a single place everyone can check in and check out. It’s like a library where you get to scribble in the books.</p>

<p>This model works for backup, undo and synchronization but isn’t great for merging and branching changes people make. As projects grow, you want to split features into chunks, developing and testing in isolation and slowly merging changes into the main line. In reality, branching is cumbersome, so new features may come as a giant checkin, making changes difficult to manage and untangle if they go awry.</p>

<p>Sure, merging is always “possible” in a centralized system, but it’s not easy: you often need to track the merge yourself to avoid making the same change twice. Distributed systems make branching and merging painless because they rely on it.</p>

<div class="textad sponsored_footer" style="display:none;"><span class="meta">Advertisement:</span> Use [Springloops](http://springloops.com) for your secure and rapid web deployment. Easily share and deploy your code. Free &#038; paid plans and no contracts: [Try it today](http://springloops.com/signup)!
</div>

<h2>A Few Diagrams, Please</h2>

<p>Other tutorials have plenty of nitty-gritty text commands; here’s a <strong>visual</strong> look. To refresh, developers use a central repo in a typical <span class="caps">VCS</span>:</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/distributed/centralized_example.png" alt="centralized version control" class="webpexpress-processed"></p>

<p>Everyone syncs and checks into the main trunk: Sue adds soup, Joe adds juice, and Eve adds eggs.</p>

<p>Sue’s change must go into main before it can be seen by others. Yes, theoretically Sue <em>could</em> make a new branch for other people to try out her changes, but this is a pain in a regular <span class="caps">VCS.</span></p>

<h2>Distributed Version Control Systems (DVCS)</h2>

<p>In a distributed model, every developer has their own repo. Sue’s changes live in her local repo, which she can share with Joe or Eve:</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/distributed/distributed_example.png" alt="distributed version control example" class="webpexpress-processed"></p>

<p>But will it be a circus with no ringleader? Nope. If desired, everyone can push changes into a common repo, suspiciously like the centralized model above. This franken-repo contains the changes of Sue, Joe and Eve.</p>

<p><strong>I wish distributed version control had a different name</strong>, such as “independent”, “federated” or “peer-to-peer.” The term “distributed” evokes thoughts of distributed computing, where work is split among a grid of machines (like searching for signals with <a href="http://setiathome.berkeley.edu/"><span class="caps">SETI</span>@home</a> or doing <a href="http://folding.stanford.edu/">protein folding</a>).</p>

<p>A <span class="caps">DVCS </span>is not like Seti@home: each node is completely independent and sharing is optional (in Seti you must phone back your results).</p>

<h2>Key Concepts In 5 Minutes</h2>

<p>Here’s the basics; there’s a <a href="https://en.wikibooks.org/wiki/Understanding_darcs/Patch_theory">book</a> on patch theory if you’re interested.</p>

<p><strong>Core Concepts</strong></p>

<ul>
<li>Centralized version control focuses on <strong>synchronizing, tracking, and backing up files.</strong></li>
<li>Distributed version control focuses on <strong>sharing changes</strong>; every change has a <a href="https://betterexplained.com/articles/the-quick-guide-to-guids/">guid or unique id</a>.</li>
<li><strong>Recording/Downloading</strong> and <strong>applying</strong> a change are separate steps (in a centralized system, they happen together).</li>
<li><strong>Distributed systems have no forced structure</strong>. You can create “centrally administered” locations or keep everyone as peers.</li>
</ul>

<p><strong>New Terminology</strong></p>

<ul>
<li><strong>push</strong>: send a change to another repository (may require permission)</li>
<li><strong>pull</strong>: grab a change from a repository</li>
</ul>

<p><strong>Key Advantages</strong></p>

<ul>
<li><strong>Everyone has a local sandbox.</strong> You can make changes and roll back, all on your local machine. No more giant checkins; your incremental history is in your repo.</li>
<li><strong>It works offline.</strong> You only need to be online to share changes. Otherwise, you can happily stay on your local machine, checking in and undoing, no matter if the “server” is down or you’re on an airplane.</li>
<li><strong>It’s fast.</strong> Diffs, commits and reverts are all done locally. There’s no shaky network or server to ask for old revisions from a year ago.</li>
<li><strong>It handles changes well.</strong> Distributed version control systems were <em>built</em> around sharing changes. Every change has a guid which makes it easy to track.</li>
<li><strong>Branching and merging is easy.</strong> Because every developer “has their own branch”, every shared change is like reverse integration. But the guids make it easy to automatically combine changes and avoid duplicates.</li>
<li><strong>Less management.</strong> Distributed <span class="caps">VCS</span>es are easy to get running; there’s no “always-running” server software to install. Also, <span class="caps">DVCS</span>es may not require you to “add” new users; you just pick what <span class="caps">URL</span>s to pull from. This can avoid political headaches in large projects.</li>
</ul>

<p><strong>Key Disadvantages</strong></p>

<ul>
<li><strong>You still need a backup.</strong> Some claim your “backup” is the other machines that have your changes. I don’t buy it — what if they didn’t accept them all? What if they’re offline and you have new changes? With a <span class="caps">DVCS, </span>you still want a machine to push changes to “just in case”. (In Subversion, you usually dedicate a machine to store the main repo; do the same for a <span class="caps">DVCS</span>).</li>
<li><strong>There’s not really a “latest version”</strong>. If there’s no central location, you don’t immediately know whether to see Sue, Joe or Eve for the latest version. Again, a central location helps clarify what the latest “stable” release is.</li>
<li><strong>There aren’t really revision numbers.</strong> Every repo has its own revision numbers depending on the changes. Instead, people refer to change numbers: <em>Pardon me, do you have change fa33e7b?</em> (Remember, the id is an ugly guid). Thankfully, you can tag releases with meaningful names.</li>
</ul>

<h2>Mercurial Quickstart</h2>

<p>Mercurial is a fast, simple <span class="caps">DVCS.</span> The nickname is hg, like the element Mercury.</p>

<pre><code>cd project
hg init                                (create repo here)
hg add list.txt                        (start tracking file)
hg commit -m "Added file"              (check file into local repo)
hg log                                 (see history; notice guid)

changeset:   0:55bbcb7a4c24
user:        Kalid@kazad-laptop
date:        Sun Oct 14 21:36:18 2007 -0400
summary:     Added file

[edit file]
hg revert list.txt                 (revert to previous version)

hg tag v1.0                        (tag this version)
[edit file]
hg update -C v1.0                  ("update" to the older tagged version; -C forces overwrite of local copy)
</code></pre>

<p>Once Mercurial has initialized a directory, it looks like this:</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/distributed/distributed_repo_layout.png" alt="distributed version control repo layout" /></p>

<p>You have:</p>

<ul>
<li><strong>A working copy</strong>. The files you are currently editing.</li>
<li><strong>A repository</strong>. A directory (.hg in Mercurial) containing all patches and metadata (comments, guids, dates, etc.). There’s no central server so the data stays with you.</li>
</ul>

<p>In our distributed example, Sue, Joe and Eve have their own repos, with independent revision histories.</p>

<h2>Understanding Updates and Merging</h2>

<p>There’s a few items that confused me when learning about <span class="caps">DVCS.</span> First, updates happen in several steps:</p>

<ul>
<li><strong>Getting</strong> the change into a repo (pushing or pulling)</li>
<li><strong>Applying</strong> the change to the files (update or merge)</li>
<li><strong>Saving</strong> the new version (commit)</li>
</ul>

<p>Second, depending on the change, you can update or merge:</p>

<ul>
<li><strong>Updates</strong> happen when there’s no ambiguity. For example, I pull changes to a file that only you’ve been editing. The file just jumps to the latest revision, since there’s no overlapping changes.</li>
<li><strong>Merges</strong> are needed when we have conflicting changes. If we both edit a file, we end up with two “branches” (i.e. alternate universes). One world has my changes, the other world has yours. In this case we (probably) want to merge the changes together into a single universe.</li>
</ul>

<p>I’m still wrapping my head around how easily branches spring up and collapse in a <span class="caps">DVCS</span>:</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/distributed/distributed_merge.png" alt="distributed version control merge changes" class="webpexpress-processed"></p>

<p>In this case, a merge is needed because (+Soup) and (+Juice) are changes to a common parent: the list with just “Milk”. After Joe merges the files, Sue can do a regular “pull and update” to get the combined file from Joe. She doesn’t have to merge again on her own.</p>

<p>In Mercurial you can run:</p>

<pre><code>hg incoming ../another-dir  (see pending changes)
hg pull ../another-dir      (download changes)

hg update                   (actually apply changes...)
hg merge                    (... or merge if needed)

hg commit                   (check in merged file; unite branches)
</code></pre>

<p>Yep, the “pull-merge-commit” cycle is long. Luckily, Mercurial has shortcuts to combine commands into a single one. Though it seems complex, it’s much easier than handling merges manually in Subversion.</p>

<p><strong>Most merges are automatic.</strong> When conflicts come up, they are typically resolved quickly. Mercurial keeps track of the parent/child relationship for every change (our merged list has two parents), as well as the “heads” or latest changes in each branch. Before the merge we have two heads; afterwards, one.</p>

<h2>Organizing a Distributed Project</h2>

<p>Here’s one way to organize a distributed project:</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/distributed/distributed_push_pull.png" alt="distributed version control push pull model" class="webpexpress-processed"></p>

<p>Sue, Joe and Eve check changes into a common branch. They can trade patches with each other to do simple “buddy builds”: <em>Hey buddy, can you try out these patches? I need to see if it works before I push to the experimental branch.</em></p>

<p>Later, a maintainer can review and pull changes from the experimental branch into a stable branch, which has the latest release. A distributed <span class="caps">VCS </span>helps isolate changes but still provide the “single source” of a centralized system. There are many models of development, from “pull only” (where maintainers decide what to take, and is used when developing Linux) to “shared push” (which acts like a centralized system). A distributed <span class="caps">VCS </span>gives you <strong>flexibility</strong> in how a project is maintained.</p>

<h2>Practice And Scathing Ridicule Makes Perfect</h2>

<p>I’m a <span class="caps">DVCS </span>newbie, but am happy with what I’ve learned so far. I enjoy <span class="caps">SVN, </span>but it’s “fun” seeing how easy a merge can be. My suggestion is to start with Subversion, get a grasp for team collaboration, then experiment with a distributed model. With the proper layout a <span class="caps">DVCS </span>can do anything a centralized system can, with the added benefit of easy merging.</p>

<p><strong>Online Resources</strong></p>

<ul>
<li><a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a> has an <a href="http://hgbook.red-bean.com/hgbook.html">excellent book</a>. On Windows you may need <a href="http://kdiff3.sourceforge.net/">diffing/merging software</a> or <a href="http://tortoisesvn.tigris.org/TortoiseMerge.html">TortoiseMerge</a> (if you have TortoiseSVN installed).</li>
<li><a href="http://darcs.net/">Darcs</a> has a detailed <a href="https://en.wikibooks.org/wiki/Understanding_Darcs/Patch_theory">wikibook</a> (has some math theory about changes).</li>
<li><a href="http://git.or.cz">Git</a> was created by Linus Torvalds. Here’s an <a href="https://www.youtube.com/watch?v=4XpnKHJAok8">interesting lecture</a> on <span class="caps">DVCS</span>; prepare to be berated for using a centralized system:</li>
</ul>

<iframe width="640" height="360" src="https://www.youtube.com/embed/4XpnKHJAok8" frameborder="0" allowfullscreen></iframe>

<p>Notable Quotes:</p>

<ul>
<li>“How many have done a branch and merged it? How many of you enjoyed it?”</li>
<li>“When you do a merge, you plan ahead for a week, then set aside a day to do it.”</li>
<li>“Some people have 5, 10, 15 branches”. One branch is experimental. One branch is maintenance, etc.</li>
<li>“CVS — you don’t commit. You make changes without committing. You never commit until it passes a giant test suite. People make 1-liner changes, knowing it can’t <em>possibly</em> break.”</li>
</ul>

<p>So good luck, and watch out for the holy wars. Feel free to share any tips or suggestions below.</p>

<div class="postad"><a href="http://gum.co/bex-versioncontrol">Like these diagrams? Buy the original slides for just \$5.</a>
</div>

]]></content:encoded>
					
					<wfw:commentRss>https://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/feed/</wfw:commentRss>
			<slash:comments>73</slash:comments>
		

			</item>
	<item>
		<title>A Visual Guide to Version Control</title>
		<link>https://betterexplained.com/articles/a-visual-guide-to-version-control/</link>
					<comments>https://betterexplained.com/articles/a-visual-guide-to-version-control/#disqus_thread</comments>
		
		<dc:creator><![CDATA[kalid]]></dc:creator>
		<pubDate>Thu, 27 Sep 2007 14:59:53 +0000</pubDate>
				<category><![CDATA[Guides]]></category>
				<category><![CDATA[Programming]]></category>
		<guid isPermaLink="false">http://betterexplained.com/articles/a-visual-guide-to-version-control/</guid>

					<description><![CDATA[Version Control (aka Revision Control aka Source Control) lets you track your files over time. Why do you care? So when you mess up you can easily get back to a previous working version. You’ve probably cooked up your own version control system without realizing it had such a geeky name. Got any files like [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/version_control_intro_small.png" alt="A Visual Guide to Version Control" class="webpexpress-processed"></p>

<p>Version Control (aka Revision Control aka Source Control) lets you track your files over time. Why do you care? So when you mess up you can easily get back to a previous working version.</p>

<p><strong>You’ve probably cooked up your own</strong> version control system without realizing it had such a geeky name. Got any files like this? (Not these exact ones I hope).</p>

<ul>
<li>KalidAzadResumeOct2014.doc</li>
<li>KalidAzadResumeMar2015.doc</li>
<li>instacalc-logo3.png</li>
<li>instacalc-logo4.png</li>
<li>logo-old.png</li>
</ul>

<p><strong>It’s why we use “Save As”.</strong> You want the new file without obliterating the old one. It’s a common problem, and solutions are usually like this:</p>

<ul>
<li>Make a <strong>single backup copy</strong> (Document.old.txt).</li>
<li>If we’re clever, we add a <strong>version number or date</strong>: Document_V1.txt, DocumentMarch2015.txt</li>
<li>We may even use a <strong>shared folder</strong> so other people can see and edit files without sending them over email. Hopefully they relabel the file after they save it.</li>
</ul>

<h2>So Why Do We Need A Version Control System (VCS)?</h2>

<p>Our shared folder/naming system is fine for class projects or one-time papers. But software projects? Not a chance.</p>

<p>Do you think the Windows source code sits in a shared folder like “Windows2007-Latest-UPDATED!!”, for anyone to edit? That every programmer just works in a different subfolder? No way.</p>

<p>Large, fast-changing projects with many authors need a Version Control System (geekspeak for “file database”) to track changes and avoid general chaos. A good VCS does the following:</p>

<ul>
<li><strong>Backup and Restore.</strong> Files are saved as they are edited, and you can jump to any moment in time. Need that file as it was on Feb 23, 2007? No problem.</li>
<li><strong>Synchronization.</strong> Lets people share files and stay up-to-date with the latest version.</li>
<li><strong>Short-term undo.</strong> Monkeying with a file and messed it up? (That’s just like you, isn’t it?). Throw away your changes and go back to the “last known good” version in the database.</li>
<li><strong>Long-term undo.</strong> Sometimes we mess up bad. Suppose you made a change a year ago, and it had a bug. Jump back to the old version, and see what change was made that day.</li>
<li><strong>Track Changes</strong>. As files are updated, you can leave messages explaining why the change happened (stored in the VCS, not the file). This makes it easy to see how a file is evolving over time, and why.</li>
<li><strong>Track Ownership.</strong> A VCS tags every change with the name of the person who made it. Helpful for <del><a href="http://www.unwords.com/unword/blamestorming.html">blamestorming</a></del> giving credit.</li>
<li><strong>Sandboxing</strong>, or insurance against yourself. Making a big change? You can make temporary changes in an isolated area, test and work out the kinks before “checking in” your changes.</li>
<li><strong>Branching and merging</strong>. A larger sandbox. You can <strong>branch</strong> a copy of your code into a separate area and modify it in isolation (tracking changes separately). Later, you can <strong>merge</strong> your work back into the common area.</li>
</ul>

<p>Shared folders are quick and simple, but can’t beat these features.</p>

<h2>Learn the Lingo</h2>

<p>Most version control systems involve the following concepts, though the labels may be different.</p>

<p>Basic Setup</p>

<ul>
<li><strong>Repository (repo)</strong>: The database storing the files.</li>
<li><strong>Server</strong>: The computer storing the repo.</li>
<li><strong>Client</strong>: The computer connecting to the repo.</li>
<li><strong>Working Set/Working Copy</strong>: Your local directory of files, where you make changes.</li>
<li><strong>Trunk/Main</strong>: The primary location for code in the repo. Think of code as a family tree — the trunk is the main line.</li>
</ul>

<p>Basic Actions</p>

<ul>
<li><strong>Add</strong>: Put a file into the repo for the first time, i.e. begin tracking it with Version Control.</li>
<li><strong>Revision</strong>: What version a file is on (v1, v2, v3, etc.).</li>
<li><strong>Head</strong>: The latest revision in the repo.</li>
<li><strong>Check out</strong>: Download a file from the repo.</li>
<li><strong>Check in</strong>: Upload a file to the repository (if it has changed). The file gets a new revision number, and people can “check out” the latest one.</li>
<li><strong>Checkin Message</strong>: A short message describing what was changed.</li>
<li><strong>Changelog/History</strong>: A list of changes made to a file since it was created.</li>
<li><strong>Update/Sync</strong>: Synchronize your files with the latest from the repository. This lets you grab the latest revisions of all files.</li>
<li><strong>Revert</strong>: Throw away your local changes and reload the latest version from the repository.</li>
</ul>

<p>Advanced Actions</p>

<ul>
<li><strong>Branch</strong>: Create a separate copy of a file/folder for private use (bug fixing, testing, etc). Branch is both a verb (“branch the code”) and a noun (“Which branch is it in?”).</li>
<li><strong>Diff/Change/Delta</strong>: Finding the differences between two files. Useful for seeing what changed between revisions.</li>
<li><strong>Merge (or patch)</strong>: Apply the changes from one file to another, to bring it up-to-date. For example, you can merge features from one branch into another. (At Microsoft this was called <a href="http://blogs.msdn.com/larryosterman/archive/2005/02/01/364840.aspx">Reverse Integrate and Forward Integrate</a>)</li>
<li><strong>Conflict</strong>: When pending changes to a file contradict each other (both changes cannot be applied).</li>
<li><strong>Resolve</strong>: Fixing the changes that contradict each other and checking in the correct version.</li>
<li><strong>Locking</strong>: Taking control of a file so nobody else can edit it until you unlock it. Some version control systems use this to avoid conflicts.</li>
<li><strong>Breaking the lock</strong>: Forcibly unlocking a file so you can edit it. It may be needed if someone locks a file and goes on vacation (or “calls in sick” the day Halo 3 comes out).</li>
<li><strong>Check out for edit</strong>: Checking out an “editable” version of a file. Some VCSes have editable files by default, others require an explicit command.</li>
</ul>

<p>And a typical scenario goes like this:</p>

<p>Alice <strong>adds</strong> a file (<code>list.txt</code>) to the <strong>repository</strong>. She <strong>checks it out</strong>, makes a change (puts “milk” on the list), and checks it back in with a checkin message (“Added required item.”). The next morning, Bob <strong>updates</strong> his local working set and sees the latest revision of <code>list.txt</code>, which contains “milk”. He can browse the <strong>changelog</strong> or <strong>diff</strong> to see that Alice put “milk” the day before.</p>

<h2>Visual Examples</h2>

<p>This guide is purposefully high-level: most tutorials throw a bunch of text commands at you. Let’s cover the high-level concepts without getting stuck in the syntax (the <a href="http://svnbook.red-bean.com/">Subversion manual</a> is always there, don’t worry). Sometimes it’s nice to <strong>see what’s possible</strong>.</p>

<h2>Checkins</h2>

<p>The simplest scenario is checking in a file (<code>list.txt</code>) and modifying it over time.</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/basic_checkin.png" alt="version control checkin" title="version control checkin" class="webpexpress-processed"></p>

<p>Each time we check in a new version, we get a new revision (r1, r2, r3, etc.). In Subversion you’d do:</p>

<pre><code>svn add list.txt
(modify the file)
svn ci list.txt -m "Changed the list"
</code></pre>

<p>The <code>-m</code> flag is the message to use for this checkin.</p>

<h2>Checkouts and Editing</h2>

<p>In reality, you might not keep checking in a file. You may have to <strong>check out, edit and check in</strong>. The cycle looks like this:</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/checkout_edit.png" alt="version control checkout" title="version control checkout" class="webpexpress-processed"></p>

<p>If you don’t like your changes and want to start over, you can <strong>revert</strong> to the previous version and start again (or stop). When checking out, you get the latest revision by default. If you want, you can specify a particular revision. In Subversion, run:</p>

<pre><code>svn co list.txt (get latest version)
…edit file…
svn revert list.txt (throw away changes)
svn co -r2 list.txt (check out particular version)
</code></pre>

<h2>Diffs</h2>

<p>The trunk has a history of <strong>changes</strong> as a file evolves. Diffs are the changes you made while editing: imagine you can “peel” them off and apply them to a file:</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/basic_diffs.png" alt="version control diff" title="version control diff" class="webpexpress-processed"></p>

<p>For example, to go from r1 to r2, we add eggs (+Eggs). Imagine peeling off that red sticker and placing it on r1, to get r2.</p>

<p>And to get from r2 to r3, we add Juice (+Juice). To get from r3 to r4, we remove Juice and add Soup (-Juice, +Soup).</p>

<p>Most version control systems <strong>store diffs rather than full copies of the file</strong>. This saves disk space: 4 revisions of a file doesn’t mean we have 4 copies; we have 1 copy and 4 small diffs. Pretty nifty, eh? In SVN, we diff two revisions of a file like this:</p>

<pre><code>svn diff -r3:4 list.txt
</code></pre>

<p>Diffs help us notice changes (“How did you fix that bug again?”) and even apply them from one branch to another.</p>

<p><strong>Bonus question:</strong> what’s the diff from r1 to r4?</p>

<pre><code>+Eggs
+Soup
</code></pre>

<p>Notice how “Juice” wasn’t even involved — the direct jump from r1 to r4 doesn’t need that change, since Juice was overridden by Soup.</p>

<h2>Branching</h2>

<p>Branches let us copy code into a separate folder so we can monkey with it separately:</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/first_branch.png" alt="version control branch" title="version control branch" class="webpexpress-processed"></p>

<p>For example, we can create a branch for new, experimental ideas for our list: crazy things like Rice or Eggo waffles. Depending on the version control system, creating a branch (copy) may change the revision number.</p>

<p>Now that we have a branch, we can change our code and work out the kinks. (<em>“Hrm… waffles? I don’t know what the boss will think. Rice is a safe bet.”</em>). Since we’re in a separate branch, we can make changes and test in isolation, knowing our changes won’t hurt anyone. And our branch history is under version control.</p>

<p>In Subversion, you create a branch simply by copying a directory to another.</p>

<pre><code>svn copy http://path/to/trunk http://path/to/branch
</code></pre>

<p>So branching isn’t too tough of a concept: <strong>Pretend you copied your code into a different directory.</strong> You’ve probably branched your code in school projects, making sure you have a “fail safe” version you can return to if things blow up.</p>

<h2>Merging</h2>

<p>Branching sounds simple, right? Well, it’s not — figuring out how to merge changes from one branch to another can be tricky.</p>

<p>Let’s say we want to get the “Rice” feature from our experimental branch into the mainline. How would we do this? Diff r6 and r7 and apply that to the main line?</p>

<p><strong>Wrongo.</strong> We only want to apply the changes <strong>that happened in the branch!</strong>. That means we diff r5 and r6, and apply that to the main trunk:</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/merging.png" alt="version control merge" title="version control merge" class="webpexpress-processed"></p>

<p>If we diffed r6 and r7, we would lose the “Bread” feature that was in main. This is a subtle point — imagine “peeling off” the changes from the experimental branch (+Rice) and adding that to main. Main may have had other changes, which is ok — we just want to insert the Rice feature.</p>

<p>In Subversion, merging is very close to diffing. Inside the main trunk, run the command:</p>

<pre><code>svn merge -r5:6 http://path/to/branch
</code></pre>

<p>This command diffs r5-r6 in the experimental branch and applies it to the current location. Unfortunately, Subversion doesn’t have an easy way to keep track of what merges have been applied, so if you’re not careful you may apply the same changes twice. It’s a planned feature, but the current advice is to keep a changelog message reminding you that you’ve already merged r5-r6 into main.</p>

<h2>Conflicts</h2>

<p>Many times, the VCS can automatically merge changes to different parts of a file. <strong>Conflicts</strong> can arise when changes appear that don’t gel: Joe wants to remove eggs and replace it with cheese (-eggs, +cheese), and Sue wants to replace eggs with a hot dog (-eggs, +hot dog).</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/vcs_conflict.png" alt="version control conflict" title="version control conflict" class="webpexpress-processed"></p>

<p>At this point it’s a race: if Joe checks in first, that’s the change that goes through (and Sue can’t make her change).</p>

<p>When changes overlap and contradict like this, the VCS may report a <strong>conflict</strong> and not let you check in — it’s up to you to check in a newer version that <strong>resolves</strong> this dilemma. A few approaches:</p>

<ul>
<li><strong>Re-apply your changes</strong>. Sync to the latest version (r4) and re-apply your changes to this file: Add hot dog to the list that already has cheese.</li>
<li><strong>Override their changes with yours</strong>. Check out the latest version (r4), copy over your version, and check your version in. In effect, this removes cheese and replaces it with hot dog.</li>
</ul>

<p>Conflicts are infrequent but can be a pain. Usually I update to the latest and re-apply my changes.</p>

<h2>Tagging</h2>

<p>Who would have thought a version control system would be Web 2.0 compliant? Many systems let you tag (label) any revision for easy reference. This way you can refer to “Release 1.0” instead of a particular build number:</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/tagging.png" alt="version control tag" title="version control tag" class="webpexpress-processed"></p>

<p>In Subversion, tags are just branches that you agree not to edit; they are around for posterity, so you can see exactly what your version 1.0 release contained. Hence they end in a stub — there’s nowhere to go.</p>

<pre><code>(in trunk)
svn copy http://path/to/revision http://path/to/tag
</code></pre>

<h2>Real-life example: Managing Windows Source Code</h2>

<p>We guessed that Windows was managed out of a shared folder, but it’s not the case. So <a href="http://blogs.msdn.com/larryosterman/archive/2005/02/01/364840.aspx">how’s it done</a>?</p>

<ul>
<li>There’s a <strong>main line</strong> with stable builds of Windows.</li>
<li>Each group (Networking, User Interface, Media Player, etc.) <strong>has its own branch</strong> to develop new features. These are under development and less stable than main.</li>
</ul>

<p>You develop new features in your branch and “Reverse Integrate (RI)” to get them into Main. Later, you “Forward Integrate” to bring the latest changes from Main into your branch:</p>

<p><img decoding="async" src="https://betterexplained.com/wp-content/uploads/version_control/windows.png" alt="version control branch example" title="version control branch example" class="webpexpress-processed"></p>

<p>Let’s say we’re at Media Player 10 and IE 6. The Media Player team makes version 11 in their own branch. When it’s ready and tested, there’s a patch from 10 – 11 which is applied to Main (just like the “Rice” example, but a tad more complicated). This is a <strong>reverse integration</strong>, from the branch to the trunk. The IE team can do the same thing.</p>

<p>Later, the Media Player team can pick up the latest code from other teams, like IE. In this case, Media Player <strong>forward integrates</strong> and gets the latest patches from main into their branch. This is like pulling in the “Bread” feature into the experimental branch, but again, more complicated.</p>

<p>So it’s RI and FI. Aye aye. This arrangement lets changes percolate throughout the branches, while keeping new code out of the main line. Cool, eh?</p>

<p>In reality, there’s many layers of branches and sub-branches, along with quality metrics that determine when you get to RI. But you get the idea: branches help manage complexity. Now you know the basics of how one of the largest software projects is organized.</p>

<h2>Key Takeaways</h2>

<p>My goal was to share high-level thoughts about version control systems. Here are the basics:</p>

<ul>
<li><strong>Use version control.</strong> Seriously, it’s a good thing, even if you’re not writing an OS. It’s worth it for backups alone.</li>
<li><strong>Take it slow.</strong> I’m only now looking into branching and merging for my projects. Just get a handle on using version control and go from there. If you’re a small project, branching/merging may not be an issue. Large projects often have experienced maintainers who keep track of the branches and patches.</li>
<li><strong>Keep Learning.</strong> There’s plenty of guides for <a href="http://svnbook.red-bean.com/">SVN</a>, <a href="http://wwwasd.web.cern.ch/wwwasd/cvs/tutorial/cvs_tutorial_toc.html">CVS</a>, <a href="http://agave.garden.org/~aaronh/rcs/tutorial.html">RCS</a>, <a href="https://www.kernel.org/pub/software/scm/git/docs/">Git</a>, <a href="http://public.perforce.com/public/tutorial.html">Perforce</a> or whatever system you’re using. The important thing is to <strong>know the concepts</strong> and realize every system has its own lingo and philosophy. Eric Sink has a <a href="http://www.ericsink.com/scm/source_control.html">detailed version control guide</a> also.</li>
</ul>

<p>These are the basics — as time goes on I’ll share specific lessons I’ve learned from <a href="http://instacalc.com">my projects</a>. Now that you’ve figured out a regular VCS, <a href="https://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/">try an illustrated guide to distributed version control</a>.</p>

<div class="postad">
<a href="http://gum.co/bex-versioncontrol">Like these diagrams? Buy the original slides for only \$5</a>
</div>

]]></content:encoded>
					
					<wfw:commentRss>https://betterexplained.com/articles/a-visual-guide-to-version-control/feed/</wfw:commentRss>
			<slash:comments>239</slash:comments>
		

			</item>
	</channel>
</rss>
