<?xml version="1.0"?>
<rss version="2.0"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:dcterms="http://purl.org/dc/terms/"
     xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Tyler Cipriani: pages tagged vcs</title>
<link>https://tylercipriani.com/tags/vcs/</link>
<atom:link href="https://tylercipriani.com/tags/vcs/index.rss" rel="self" type="application/rss+xml"/>

<description>Tyler Cipriani</description>
<generator>ikiwiki</generator>
<pubDate>Sat, 01 Jul 2017 00:49:09 +0000</pubDate>
<item>
	<title>Delete Local Git Commits</title>

	<guid isPermaLink="false">https://tylercipriani.com/blog/2016/09/07/delete-local-git-commits/</guid>

	<link>https://tylercipriani.com/blog/2016/09/07/delete-local-git-commits/</link>

	<dc:creator>Tyler Cipriani</dc:creator>



	<category>computing</category>

	<category>git</category>

	<category>vcs</category>


	<pubDate>Wed, 07 Sep 2016 17:48:08 +0000</pubDate>
	<dcterms:modified>2017-07-01T00:49:09Z</dcterms:modified>


	<description>&lt;p&gt;Usually when I need to delete a commit from a local git repo I use:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; rebase -i&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This starts an interactive rebase session for all commits from &lt;code&gt;HEAD..@{u}&lt;/code&gt;. Once I’m in the git rebase editor I put a &lt;code&gt;drop&lt;/code&gt; on the line that has the commit I want to delete and save the file. Magic. Commit gone.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;ex&quot;&gt;drop&lt;/span&gt; c572357 [LOCAL] Change to be removed&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-2&quot; title=&quot;2&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-3&quot; title=&quot;3&quot;&gt;&lt;span class=&quot;co&quot;&gt;# Rebase dbfcb3a..c572357 onto dbfcb3a (1 command(s))&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;co&quot;&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-5&quot; title=&quot;5&quot;&gt;&lt;span class=&quot;co&quot;&gt;# Commands:&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;co&quot;&gt;# p, pick = use commit&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-7&quot; title=&quot;7&quot;&gt;&lt;span class=&quot;co&quot;&gt;# r, reword = use commit, but edit the commit message&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-8&quot; title=&quot;8&quot;&gt;&lt;span class=&quot;co&quot;&gt;# e, edit = use commit, but stop for amending&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-9&quot; title=&quot;9&quot;&gt;&lt;span class=&quot;co&quot;&gt;# s, squash = use commit, but meld into previous commit&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-10&quot; title=&quot;10&quot;&gt;&lt;span class=&quot;co&quot;&gt;# f, fixup = like &amp;quot;squash&amp;quot;, but discard this commit&amp;#39;s log message&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-11&quot; title=&quot;11&quot;&gt;&lt;span class=&quot;co&quot;&gt;# x, exec = run command (the rest of the line) using shell&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-12&quot; title=&quot;12&quot;&gt;&lt;span class=&quot;co&quot;&gt;# d, drop = remove commit&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-13&quot; title=&quot;13&quot;&gt;&lt;span class=&quot;co&quot;&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-14&quot; title=&quot;14&quot;&gt;&lt;span class=&quot;co&quot;&gt;# These lines can be re-ordered; they are executed from top to bottom.&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-15&quot; title=&quot;15&quot;&gt;&lt;span class=&quot;co&quot;&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-16&quot; title=&quot;16&quot;&gt;&lt;span class=&quot;co&quot;&gt;# If you remove a line here THAT COMMIT WILL BE LOST.&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-17&quot; title=&quot;17&quot;&gt;&lt;span class=&quot;co&quot;&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-18&quot; title=&quot;18&quot;&gt;&lt;span class=&quot;co&quot;&gt;# However, if you remove everything, the rebase will be aborted.&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-19&quot; title=&quot;19&quot;&gt;&lt;span class=&quot;co&quot;&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-20&quot; title=&quot;20&quot;&gt;&lt;span class=&quot;co&quot;&gt;# Note that empty commits are commented out&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is fine if you’re there to drive an editor for an interactive rebase.&lt;/p&gt;
&lt;section id=&quot;the-problem-with-interactivity&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;The problem with interactivity &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#the-problem-with-interactivity&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The problem with interactive rebase is you can’t easily script it.&lt;/p&gt;
&lt;p&gt;At work I help to maintain our “beta cluster” which is a bunch of virtual machines that is supposed to mirror the setup of production. The extent to which production is actually mirrored is debatable; however, it is true that we use the same puppet repository as production. Further, this puppet repository resides on a virtual machine within the cluster that acts as the beta cluster’s puppetmaster.&lt;/p&gt;
&lt;p&gt;Often, to test a patch for production puppet, folks will apply patches on top of beta’s local copy of the production puppet repo.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;ex&quot;&gt;root@puppetmaster&lt;/span&gt;# cd /var/lib/git/operations/puppet&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;root@puppetmaster&lt;/span&gt;# git apply --check --3way /home/thcipriani/0001-some.patch&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-3&quot; title=&quot;3&quot;&gt;&lt;span class=&quot;ex&quot;&gt;root@puppetmaster&lt;/span&gt;# git am --3way /home/thcipriani/0001-some.path&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;ex&quot;&gt;root@puppetmaster&lt;/span&gt;# git status&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-5&quot; title=&quot;5&quot;&gt;&lt;span class=&quot;ex&quot;&gt;On&lt;/span&gt; branch production&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;ex&quot;&gt;Your&lt;/span&gt; branch is ahead of &lt;span class=&quot;st&quot;&gt;&amp;#39;origin/production&amp;#39;&lt;/span&gt; by 6 commits.&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-7&quot; title=&quot;7&quot;&gt;  &lt;span class=&quot;kw&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;git push&amp;quot;&lt;/span&gt; to publish your local commits&lt;span class=&quot;kw&quot;&gt;)&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-8&quot; title=&quot;8&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-9&quot; title=&quot;9&quot;&gt;&lt;span class=&quot;ex&quot;&gt;nothing&lt;/span&gt; to commit, working directory clean&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The problem here is that a lot of these commits are old and busted.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;ex&quot;&gt;root@puppetmaster&lt;/span&gt;# git log -6 --format=&lt;span class=&quot;st&quot;&gt;&amp;#39;%h %ai&amp;#39;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;ad4f419&lt;/span&gt; 2016-08-25 20:46:23 +0530&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-3&quot; title=&quot;3&quot;&gt;&lt;span class=&quot;ex&quot;&gt;d3e9ab8&lt;/span&gt; 2016-09-05 15:49:48 +0100&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;ex&quot;&gt;59b7377&lt;/span&gt; 2016-08-30 16:21:39 -0700&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-5&quot; title=&quot;5&quot;&gt;&lt;span class=&quot;ex&quot;&gt;5d2609e&lt;/span&gt; 2016-08-17 14:17:02 +0100&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;ex&quot;&gt;194ee1c&lt;/span&gt; 2016-07-19 13:19:54 -0600&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-7&quot; title=&quot;7&quot;&gt;&lt;span class=&quot;ex&quot;&gt;057c9f7&lt;/span&gt; 2016-01-07 17:11:12 -0800&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It’d be nice to have a script that periodically cleans up these patches based on some criteria. This script would have to potentially be able to remove, say, &lt;code&gt;59b7377&lt;/code&gt; while leaving all the others in-tact, and it would have to do so without any access to &lt;code&gt;git rebase -i&lt;/code&gt; or any user input.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;non-interactive-commit-deletion&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;Non-interactive commit deletion &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#non-interactive-commit-deletion&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The way to do this is with &lt;code&gt;git rebase --onto&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Selective quoting of &lt;code&gt;man git-rebase&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;ex&quot;&gt;SYNOPSIS&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-2&quot; title=&quot;2&quot;&gt;    &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; rebase [--onto &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;newbase&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt;] [&lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;upstream&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt;]&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-3&quot; title=&quot;3&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;ex&quot;&gt;DESCRIPTION&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-5&quot; title=&quot;5&quot;&gt;    &lt;span class=&quot;ex&quot;&gt;All&lt;/span&gt; changes made by commits in the current branch but that are not&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-6&quot; title=&quot;6&quot;&gt;    &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;upstream&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; are saved to a temporary area. This is the same set&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-7&quot; title=&quot;7&quot;&gt;    &lt;span class=&quot;ex&quot;&gt;of&lt;/span&gt; commits that would be shown by git log &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;upstream&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt;..HEAD&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-8&quot; title=&quot;8&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-9&quot; title=&quot;9&quot;&gt;    &lt;span class=&quot;ex&quot;&gt;The&lt;/span&gt; current branch is reset to &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;newbase&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; --onto option was supplied.&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-10&quot; title=&quot;10&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-11&quot; title=&quot;11&quot;&gt;    &lt;span class=&quot;ex&quot;&gt;The&lt;/span&gt; commits that were previously saved into the temporary area are&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-12&quot; title=&quot;12&quot;&gt;    &lt;span class=&quot;kw&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;reapplied&lt;/span&gt; to the current branch, one by one, in order.&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The commits we want are all the commits surrounding &lt;code&gt;59b7377&lt;/code&gt; without &lt;code&gt;59b7377&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb6-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;ex&quot;&gt;root@puppetmaster&lt;/span&gt;# git log --format=&lt;span class=&quot;st&quot;&gt;&amp;#39;%h %ai&amp;#39;&lt;/span&gt; 59b7377..HEAD&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb6-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;ad4f419&lt;/span&gt; 2016-08-25 20:46:23 +0530&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb6-3&quot; title=&quot;3&quot;&gt;&lt;span class=&quot;ex&quot;&gt;d3e9ab8&lt;/span&gt; 2016-09-05 15:49:48 +0100&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb6-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;ex&quot;&gt;root@puppetmaster&lt;/span&gt;# git log --format=&lt;span class=&quot;st&quot;&gt;&amp;#39;%h %ai&amp;#39;&lt;/span&gt; @&lt;span class=&quot;dt&quot;&gt;{u}&lt;/span&gt;..59b7377^&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb6-5&quot; title=&quot;5&quot;&gt;&lt;span class=&quot;ex&quot;&gt;5d2609e&lt;/span&gt; 2016-08-17 14:17:02 +0100&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb6-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;ex&quot;&gt;194ee1c&lt;/span&gt; 2016-07-19 13:19:54 -0600&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb6-7&quot; title=&quot;7&quot;&gt;&lt;span class=&quot;ex&quot;&gt;057c9f7&lt;/span&gt; 2016-01-07 17:11:12 -0800&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So we really want to take the commits &lt;code&gt;59b7377..HEAD&lt;/code&gt; and rebase them onto the commit before &lt;code&gt;59b7377&lt;/code&gt; (which is &lt;code&gt;59b7377^&lt;/code&gt;)&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;ex&quot;&gt;root@puppetmaster&lt;/span&gt;# git rebase --onto 59b7377^ 59b7377&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;root@puppetmaster&lt;/span&gt;# git log -6 --format=&lt;span class=&quot;st&quot;&gt;&amp;#39;%h %ai&amp;#39;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-3&quot; title=&quot;3&quot;&gt;&lt;span class=&quot;ex&quot;&gt;ad4f419&lt;/span&gt; 2016-08-25 20:46:23 +0530&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;ex&quot;&gt;d3e9ab8&lt;/span&gt; 2016-09-05 15:49:48 +0100&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-5&quot; title=&quot;5&quot;&gt;&lt;span class=&quot;ex&quot;&gt;5d2609e&lt;/span&gt; 2016-08-17 14:17:02 +0100&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;ex&quot;&gt;194ee1c&lt;/span&gt; 2016-07-19 13:19:54 -0600&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-7&quot; title=&quot;7&quot;&gt;&lt;span class=&quot;ex&quot;&gt;057c9f7&lt;/span&gt; 2016-01-07 17:11:12 -0800&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-8&quot; title=&quot;8&quot;&gt;&lt;span class=&quot;ex&quot;&gt;d5e1340&lt;/span&gt; 2016-09-07 23:45:25 +0200&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Tada! Commit gone.&lt;/p&gt;
&lt;/section&gt;
</description>


	<comments>//tylercipriani.com/blog/2016/09/07/delete-local-git-commits/#comments</comments>

</item>
<item>
	<title>(ab)Using Git Notes</title>

	<guid isPermaLink="false">https://tylercipriani.com/blog/2016/08/26/abusing-git-notes/</guid>

	<link>https://tylercipriani.com/blog/2016/08/26/abusing-git-notes/</link>

	<dc:creator>Tyler Cipriani</dc:creator>



	<category>computing</category>

	<category>git</category>

	<category>git-abuse</category>

	<category>vcs</category>


	<pubDate>Fri, 26 Aug 2016 22:35:15 +0000</pubDate>
	<dcterms:modified>2017-07-01T00:49:09Z</dcterms:modified>


	<description>&lt;section id=&quot;flickr&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;Flickr &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#flickr&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I like to post my &lt;a href=&quot;http://photos.tylercipriani.com/&quot;&gt;photos on the internet&lt;/a&gt;. I used to post all of my photos on &lt;a href=&quot;https://www.flickr.com/photos/tylercipriani/&quot;&gt;Flickr&lt;/a&gt;, but that site has been getting &lt;a href=&quot;https://github.com/thcipriani/dotfiles/commit/c2ff9eeedb1c6634982efc940e43335264018269&quot;&gt;worse&lt;/a&gt; and &lt;a href=&quot;https://techcrunch.com/2013/05/20/flickr-gets-a-huge-revamp-with-hi-res-image-filled-ui-new-android-app-and-1tb-of-free-storage/&quot;&gt;worse&lt;/a&gt; and &lt;a href=&quot;https://www.theguardian.com/technology/2016/jul/25/yahoo-moves-next-for-flickr&quot;&gt;worse&lt;/a&gt;. More recently, I’ve been using a static photo gallery generator I &lt;strike&gt;wrote&lt;/strike&gt; hacked together that I (perhaps unfortunately) named &lt;a href=&quot;https://github.com/thcipriani/dotfiles/tree/master/bin/hiraeth&quot;&gt;hiraeth&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Hiraeth is, to put it mildly, missing some features. There are a few reasons that I opted to create hiraeth rather than use something that was already built:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;I &lt;em&gt;need&lt;/em&gt; to host my own photos now, evidently. The internet has seemingly decided to sell its user-base to the highest bidder, so hosted services are out.&lt;/li&gt;
&lt;li&gt;I think it makes sense to host my photos statically, since they’re static (mostly).&lt;/li&gt;
&lt;li&gt;I really &lt;em&gt;like&lt;/em&gt; the way my &lt;code&gt;~/Pictures&lt;/code&gt; directory is organized—I can find stuff—and I don’t want to mess all that up to generate a crappy website out of my photos.&lt;/li&gt;
&lt;li&gt;I use git-annex to manage my &lt;code&gt;~/Pictures&lt;/code&gt;, which creates…unique challenges :)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Hiraeth is invoked like: &lt;code&gt;publish [edited-photo-dir] [output-dir]&lt;/code&gt;. Hiraeth looks for a file named &lt;code&gt;_metadata.yaml&lt;/code&gt; inside the directory of edited photos and uses that to map photo files to photo descriptions and add titles and whatnot to the page. It makes a few different sized thumbnails of each photo, grabs the exif info, and generates some html.&lt;/p&gt;
&lt;p&gt;Hiraeth was designed to look and behave like a static version of Flickr circa 2007. There are still features to add, but there is a base that works in place at least.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;home-pictures&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;Home Pictures &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#home-pictures&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I mange my &lt;code&gt;~/Pictures&lt;/code&gt; directory using &lt;a href=&quot;https://git-annex.branchable.com/&quot;&gt;git-annex&lt;/a&gt; (which I’ve wanted to write something about for a long time). This is mostly amazing and great. Git-annex has a lot of cool features. For instance, in git-annex once you’ve copied files to a remote, it will allow you to “&lt;code&gt;drop&lt;/code&gt;” a file locally to save space. You can still get the file back from the remote any time you rootin’ tootin’ feel like, so nbd. Occasionally, when I’m running out of space on one machine or another, I’ll &lt;code&gt;drop&lt;/code&gt; a bunch of photos.&lt;/p&gt;
&lt;p&gt;The ability to drop a bunch of photos means that hiraeth needs to be able to get photo metadata from a picture without having the file &lt;em&gt;actually&lt;/em&gt; be on disk.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;gerrit&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;Gerrit &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#gerrit&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We use gerrit at work and I genuinely like it.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;rant&amp;gt;&lt;/code&gt; The web-UI is one of the worst interfaces I’ve ever used. The web interface is an unfortunate mix of late-90s, designed-by-engineers, impossibly-option-filled interface mashed together in an unholy union with a fancy-schmancy new-fangled javascripty single-page application. It’s basically a mix of two interface paradigms I hate, yet rarely see in concert: back-button breakage + no design aesthetic whatsoever. &lt;code&gt;&amp;lt;/rant&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HOWEVER&lt;/strong&gt;, The workflow gerrit enforces, the git features it uses, and the beautiful repository history that results makes gerrit a really nice code review system.&lt;/p&gt;
&lt;p&gt;Gerrit is the first system I’ve seen use git-notes.&lt;/p&gt;
&lt;p&gt;Gerrit has a cool feature where it keeps all of the patch review in git-notes:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;ex&quot;&gt;tyler@taskmaster&lt;/span&gt;:mediawiki-core$ git fetch origin refs/notes/*:refs/notes/*&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;remote&lt;/span&gt;: Counting objects: 176401, done&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-3&quot; title=&quot;3&quot;&gt;&lt;span class=&quot;ex&quot;&gt;remote&lt;/span&gt;: Finding sources: 100% (147886/147886)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;ex&quot;&gt;remote&lt;/span&gt;: Getting sizes: 100% (1723/1723)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-5&quot; title=&quot;5&quot;&gt;&lt;span class=&quot;ex&quot;&gt;remote&lt;/span&gt;: Compressing objects: 100% (116810/116810)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;ex&quot;&gt;remote&lt;/span&gt;: Total 147886 (delta 120436), &lt;span class=&quot;ex&quot;&gt;reused&lt;/span&gt; 147854 (delta 120434)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-7&quot; title=&quot;7&quot;&gt;&lt;span class=&quot;ex&quot;&gt;Receiving&lt;/span&gt; objects: 100% (147886/147886), &lt;span class=&quot;ex&quot;&gt;14.91&lt;/span&gt; MiB &lt;span class=&quot;kw&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;3.01&lt;/span&gt; MiB/s, done.&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-8&quot; title=&quot;8&quot;&gt;&lt;span class=&quot;ex&quot;&gt;Resolving&lt;/span&gt; deltas: 100% (120449/120449), &lt;span class=&quot;kw&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;.&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-9&quot; title=&quot;9&quot;&gt;&lt;span class=&quot;ex&quot;&gt;From&lt;/span&gt; ssh://gerrit.wikimedia.org:29418/mediawiki/core&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-10&quot; title=&quot;10&quot;&gt; &lt;span class=&quot;ex&quot;&gt;*&lt;/span&gt; [new ref]         refs/notes/commits -&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; refs/notes/commits&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-11&quot; title=&quot;11&quot;&gt; &lt;span class=&quot;ex&quot;&gt;*&lt;/span&gt; [new ref]         refs/notes/review -&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; refs/notes/review&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-12&quot; title=&quot;12&quot;&gt;&lt;span class=&quot;ex&quot;&gt;tyler@taskmaster&lt;/span&gt;:mediawiki-core$ ls -l .git/refs/notes&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-13&quot; title=&quot;13&quot;&gt;&lt;span class=&quot;ex&quot;&gt;total&lt;/span&gt; 8&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-14&quot; title=&quot;14&quot;&gt;&lt;span class=&quot;ex&quot;&gt;-rw-r--r--&lt;/span&gt; 1 tyler tyler 41 Aug 28 16:44 commits&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-15&quot; title=&quot;15&quot;&gt;&lt;span class=&quot;ex&quot;&gt;-rw-r--r--&lt;/span&gt; 1 tyler tyler 41 Aug 28 16:44 review&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-16&quot; title=&quot;16&quot;&gt;&lt;span class=&quot;ex&quot;&gt;tyler@taskmaster&lt;/span&gt;:mediawiki-core$ git log --show-notes=review --author=&lt;span class=&quot;st&quot;&gt;&amp;#39;Tyler Cipriani&amp;#39;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-17&quot; title=&quot;17&quot;&gt; &lt;span class=&quot;ex&quot;&gt;commit&lt;/span&gt; ab131d4be475bf87b0f0a86fa356a2b1a188a673&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-18&quot; title=&quot;18&quot;&gt; &lt;span class=&quot;ex&quot;&gt;Author&lt;/span&gt;: Tyler Cipriani &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;tcipriani@wikimedia.org&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-19&quot; title=&quot;19&quot;&gt; &lt;span class=&quot;ex&quot;&gt;Date&lt;/span&gt;:   Tue Mar 22 09:08:52 2016 -0700&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-20&quot; title=&quot;20&quot;&gt; &lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-21&quot; title=&quot;21&quot;&gt; &lt;span class=&quot;ex&quot;&gt;Revert&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Add link to anon&amp;#39;s user page; remove &amp;quot;&lt;/span&gt;Not logged in&lt;span class=&quot;st&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-22&quot; title=&quot;22&quot;&gt; &lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-23&quot; title=&quot;23&quot;&gt; &lt;span class=&quot;ex&quot;&gt;This&lt;/span&gt; reverts change I049d0671a7050.&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-24&quot; title=&quot;24&quot;&gt; &lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-25&quot; title=&quot;25&quot;&gt; &lt;span class=&quot;ex&quot;&gt;This&lt;/span&gt; change was reverted in the wmf/1.27.0-wmf.17. Since there is no&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-26&quot; title=&quot;26&quot;&gt; &lt;span class=&quot;fu&quot;&gt;clear&lt;/span&gt; consensus, revert in master before branching wmf/1.27.0-wmf.18.&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-27&quot; title=&quot;27&quot;&gt; &lt;span class=&quot;ex&quot;&gt;Bug&lt;/span&gt;: T121793&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-28&quot; title=&quot;28&quot;&gt; &lt;span class=&quot;ex&quot;&gt;Change-Id&lt;/span&gt;: I2dc0f2562c908d4e419d34e80a64065843778f3d&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-29&quot; title=&quot;29&quot;&gt; &lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-30&quot; title=&quot;30&quot;&gt; &lt;span class=&quot;ex&quot;&gt;Notes&lt;/span&gt; (review)&lt;span class=&quot;bu&quot;&gt;:&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-31&quot; title=&quot;31&quot;&gt;     &lt;span class=&quot;ex&quot;&gt;Verified+2&lt;/span&gt;: jenkins-bot&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-32&quot; title=&quot;32&quot;&gt;     &lt;span class=&quot;ex&quot;&gt;Code-Review+2&lt;/span&gt;: Legoktm &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;legoktm.wikipedia@gmail.com&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-33&quot; title=&quot;33&quot;&gt;     &lt;span class=&quot;ex&quot;&gt;Submitted-by&lt;/span&gt;: jenkins-bot&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-34&quot; title=&quot;34&quot;&gt;     &lt;span class=&quot;ex&quot;&gt;Submitted-at&lt;/span&gt;: Tue, 22 Mar 2016 18:08:27 +0000&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-35&quot; title=&quot;35&quot;&gt;     &lt;span class=&quot;ex&quot;&gt;Reviewed-on&lt;/span&gt;: https://gerrit.wikimedia.org/r/278923&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-36&quot; title=&quot;36&quot;&gt;     &lt;span class=&quot;ex&quot;&gt;Project&lt;/span&gt;: mediawiki/core&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-37&quot; title=&quot;37&quot;&gt;     &lt;span class=&quot;ex&quot;&gt;Branch&lt;/span&gt;: refs/heads/master&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is super cool. You can have, effectively, an offline backup of lots of information you’d usually have to brave the gerrit web-ui to find. Plus, you don’t &lt;em&gt;have to&lt;/em&gt; have this information in your local repo taking up space, it’s only there if you fetch it down.&lt;/p&gt;
&lt;p&gt;There is another project from Google that uses git-notes for review called &lt;a href=&quot;https://github.com/google/git-appraise&quot;&gt;git-appraise&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is the stated use of git-notes in the docs: store extra information about a commit, without changing the SHA1 of the commit by modifying its contents.&lt;/p&gt;
&lt;p&gt;It is, however, noteworthy that you can store a note that points to any object in your repository and not just commit objects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;exif-data-without-pictures&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;EXIF data without pictures &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#exif-data-without-pictures&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After some minor testing it seems that I can store all the EXIF info I need about my images in git-notes without &lt;em&gt;actually&lt;/em&gt; having those images on disk; i.e., I can have git-annex drop the actual files and just have broken symlinks that point to where the files live in annex.&lt;/p&gt;
&lt;p&gt;I wrote a &lt;a href=&quot;https://gist.github.com/thcipriani/e56cdef56a98eb0cf7e93dadf94fbdd8&quot;&gt;small bash script&lt;/a&gt; to play with some of these ideas.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;ex&quot;&gt;tyler@taskmaster&lt;/span&gt;:Pictures$ git photo show fish.jpg&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;+&lt;/span&gt; git notes --ref=pictures show d4a9c57715ce63a228577900d1abc027&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-3&quot; title=&quot;3&quot;&gt;&lt;span class=&quot;ex&quot;&gt;error&lt;/span&gt;: No note found for object d4a9c57715ce63a228577900d1abc0273396e8ef.&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;ex&quot;&gt;tyler@taskmaster&lt;/span&gt;:Pictures$ git photo add fish.jpg&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-5&quot; title=&quot;5&quot;&gt;&lt;span class=&quot;ex&quot;&gt;+&lt;/span&gt; git notes --ref=pictures add -m &lt;span class=&quot;st&quot;&gt;&amp;#39;FileName: fish.jpg&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;st&quot;&gt;FileTypeExtension: jpg&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-7&quot; title=&quot;7&quot;&gt;&lt;span class=&quot;st&quot;&gt;Make: NIKON CORPORATION&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-8&quot; title=&quot;8&quot;&gt;&lt;span class=&quot;st&quot;&gt;Model: NIKON D610&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-9&quot; title=&quot;9&quot;&gt;&lt;span class=&quot;st&quot;&gt;LensID: AF-S Zoom-Nikkor 24-70mm f/2.8G ED&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-10&quot; title=&quot;10&quot;&gt;&lt;span class=&quot;st&quot;&gt;FocalLength: 62.0 mm&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-11&quot; title=&quot;11&quot;&gt;&lt;span class=&quot;st&quot;&gt;FNumber: 2.8&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-12&quot; title=&quot;12&quot;&gt;&lt;span class=&quot;st&quot;&gt;ISO: 3200&amp;#39;&lt;/span&gt; d4a9c57715ce63a228577900d1abc027&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-13&quot; title=&quot;13&quot;&gt;&lt;span class=&quot;ex&quot;&gt;+&lt;/span&gt; set +x&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-14&quot; title=&quot;14&quot;&gt;&lt;span class=&quot;ex&quot;&gt;tyler@taskmaster&lt;/span&gt;:Pictures$ git photo show fish.jpg&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-15&quot; title=&quot;15&quot;&gt;&lt;span class=&quot;ex&quot;&gt;+&lt;/span&gt; git notes --ref=pictures show d4a9c57715ce63a228577900d1abc027&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-16&quot; title=&quot;16&quot;&gt;&lt;span class=&quot;ex&quot;&gt;FileName&lt;/span&gt;: fish.jpg&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-17&quot; title=&quot;17&quot;&gt;&lt;span class=&quot;ex&quot;&gt;FileTypeExtension&lt;/span&gt;: jpg&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-18&quot; title=&quot;18&quot;&gt;&lt;span class=&quot;ex&quot;&gt;Make&lt;/span&gt;: NIKON CORPORATION&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-19&quot; title=&quot;19&quot;&gt;&lt;span class=&quot;ex&quot;&gt;Model&lt;/span&gt;: NIKON D610&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-20&quot; title=&quot;20&quot;&gt;&lt;span class=&quot;ex&quot;&gt;LensID&lt;/span&gt;: AF-S Zoom-Nikkor 24-70mm f/2.8G ED&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-21&quot; title=&quot;21&quot;&gt;&lt;span class=&quot;ex&quot;&gt;FocalLength&lt;/span&gt;: 62.0 mm&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-22&quot; title=&quot;22&quot;&gt;&lt;span class=&quot;ex&quot;&gt;FNumber&lt;/span&gt;: 2.8&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-23&quot; title=&quot;23&quot;&gt;&lt;span class=&quot;ex&quot;&gt;ISO&lt;/span&gt;: 3200&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-24&quot; title=&quot;24&quot;&gt;&lt;span class=&quot;ex&quot;&gt;+&lt;/span&gt; set +x&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now it seems like it &lt;em&gt;should be&lt;/em&gt; possible to &lt;code&gt;git push origin refs/notes/pictures&lt;/code&gt;, fetch them on the other side, and modify hiraeth to read EXIF from notes when the symlink target doesn’t exist.&lt;/p&gt;
&lt;p&gt;We’ll see how any of that goes in practice :&lt;br /&gt;
&lt;/p&gt;
&lt;/section&gt;
</description>


	<comments>//tylercipriani.com/blog/2016/08/26/abusing-git-notes/#comments</comments>

</item>
<item>
	<title>Visualizing Git&#x2019;s Merkle DAG with D3.js</title>

	<guid isPermaLink="false">https://tylercipriani.com/blog/2016/03/21/Visualizing-Git-Merkle-DAG-with-D3.js/</guid>

	<link>https://tylercipriani.com/blog/2016/03/21/Visualizing-Git-Merkle-DAG-with-D3.js/</link>

	<dc:creator>Tyler Cipriani</dc:creator>



	<category>computing</category>

	<category>javascript</category>

	<category>vcs</category>


	<pubDate>Mon, 21 Mar 2016 00:00:00 +0000</pubDate>
	<dcterms:modified>2017-07-01T00:49:09Z</dcterms:modified>


	<description>&lt;p&gt;The &lt;a href=&quot;https://en.wikipedia.org/wiki/Directed_acyclic_graph&quot;&gt;Directed Acyclic Graph&lt;/a&gt; (DAG) is a concept I run into over-and-over again; which is, perhaps, somewhat ironic.&lt;/p&gt;
&lt;p&gt;A DAG is a representation of vertices (nodes) that are connected by directional edges (arcs—i.e., lines) in such a way that there are no cycles (e.g., starting at &lt;code&gt;Node A&lt;/code&gt;, you shouldn’t be able to return to &lt;code&gt;Node A&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;DAGs have lots of uses in computer science problems and in discrete mathematics. You’ll find DAGs in build-systems, network problems, and, importantly (for this blog post, if not generally) in Git.&lt;/p&gt;
&lt;p&gt;One way to think of a DAG is as a set of dependencies—each node may have a dependency on one or more other nodes. That is, in order to get to &lt;code&gt;Node B&lt;/code&gt; you must route through &lt;code&gt;Node A&lt;/code&gt;, so &lt;code&gt;Node B&lt;/code&gt; depends on &lt;code&gt;Node A&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode numberSource javascript numberLines&quot;&gt;&lt;code class=&quot;sourceCode javascript&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;co&quot;&gt;// Node → [dependent nodes]&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; dag &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-3&quot; title=&quot;3&quot;&gt;    &lt;span class=&quot;st&quot;&gt;&amp;#39;Node A&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; [&lt;span class=&quot;st&quot;&gt;&amp;#39;Node B&amp;#39;&lt;/span&gt;]&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-4&quot; title=&quot;4&quot;&gt;    &lt;span class=&quot;st&quot;&gt;&amp;#39;Node B&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; []&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-5&quot; title=&quot;5&quot;&gt;&lt;span class=&quot;op&quot;&gt;};&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The visualization of dependencies in a JSON object is (SURPRISE!) different from the input format needed to visualize a DAG using the &lt;a href=&quot;https://github.com/mbostock/d3/wiki/Force-Layout&quot;&gt;D3.js Force layout&lt;/a&gt;. To change the above object into Force’s expected input, I created a little helper function:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode numberSource javascript numberLines&quot;&gt;&lt;code class=&quot;sourceCode javascript&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; forceFormat &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(dag) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-2&quot; title=&quot;2&quot;&gt;    &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; orderedNodes &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; []&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-3&quot; title=&quot;3&quot;&gt;        nodes &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; []&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-4&quot; title=&quot;4&quot;&gt;        links &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; []&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-5&quot; title=&quot;5&quot;&gt;        usesPack &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-6&quot; title=&quot;6&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-7&quot; title=&quot;7&quot;&gt;    &lt;span class=&quot;co&quot;&gt;// Basically a dumb Object.keys&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-8&quot; title=&quot;8&quot;&gt;    &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; (node &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; dag) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-9&quot; title=&quot;9&quot;&gt;        &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; ( &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;dag&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;hasOwnProperty&lt;/span&gt;( node ) ) &lt;span class=&quot;cf&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-10&quot; title=&quot;10&quot;&gt;        &lt;span class=&quot;va&quot;&gt;orderedNodes&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;push&lt;/span&gt;(node)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-11&quot; title=&quot;11&quot;&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-12&quot; title=&quot;12&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-13&quot; title=&quot;13&quot;&gt;    &lt;span class=&quot;va&quot;&gt;orderedNodes&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;forEach&lt;/span&gt;(&lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(node) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-14&quot; title=&quot;14&quot;&gt;        &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; sources &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; dag[node]&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-15&quot; title=&quot;15&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-16&quot; title=&quot;16&quot;&gt;        &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;sources) &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-17&quot; title=&quot;17&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-18&quot; title=&quot;18&quot;&gt;        &lt;span class=&quot;va&quot;&gt;sources&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;forEach&lt;/span&gt;(&lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(source) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-19&quot; title=&quot;19&quot;&gt;            &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; source &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;orderedNodes&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;indexOf&lt;/span&gt;(source)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-20&quot; title=&quot;20&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-21&quot; title=&quot;21&quot;&gt;            &lt;span class=&quot;co&quot;&gt;// If the source isn&amp;#39;t in the Git DAG, it&amp;#39;s in a packfile&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-22&quot; title=&quot;22&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (source &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-23&quot; title=&quot;23&quot;&gt;                &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (usesPack) &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-24&quot; title=&quot;24&quot;&gt;                source &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;orderedNodes&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-25&quot; title=&quot;25&quot;&gt;                usesPack &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-26&quot; title=&quot;26&quot;&gt;            &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-27&quot; title=&quot;27&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-28&quot; title=&quot;28&quot;&gt;            &lt;span class=&quot;va&quot;&gt;links&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;push&lt;/span&gt;(&lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-29&quot; title=&quot;29&quot;&gt;                &lt;span class=&quot;st&quot;&gt;&amp;#39;source&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; source&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-30&quot; title=&quot;30&quot;&gt;                &lt;span class=&quot;st&quot;&gt;&amp;#39;target&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;orderedNodes&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;indexOf&lt;/span&gt;(node)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-31&quot; title=&quot;31&quot;&gt;            &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-32&quot; title=&quot;32&quot;&gt;        &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-33&quot; title=&quot;33&quot;&gt;        &lt;span class=&quot;va&quot;&gt;nodes&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;push&lt;/span&gt;(&lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; node&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-34&quot; title=&quot;34&quot;&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-35&quot; title=&quot;35&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-36&quot; title=&quot;36&quot;&gt;    &lt;span class=&quot;co&quot;&gt;// Add pack file to end of list&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-37&quot; title=&quot;37&quot;&gt;    &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (usesPack) &lt;span class=&quot;va&quot;&gt;nodes&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;push&lt;/span&gt;(&lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;PACK&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-38&quot; title=&quot;38&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-39&quot; title=&quot;39&quot;&gt;    &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;nodes&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; nodes&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;links&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; links &lt;span class=&quot;op&quot;&gt;};&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-40&quot; title=&quot;40&quot;&gt;&lt;span class=&quot;op&quot;&gt;};&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-41&quot; title=&quot;41&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-42&quot; title=&quot;42&quot;&gt;&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; forceInput &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;forceFormat&lt;/span&gt;(dag)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;forceFormat&lt;/code&gt; outputs a JSON object that can be used as input for the Force layout.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode numberSource javascript numberLines&quot;&gt;&lt;code class=&quot;sourceCode javascript&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-2&quot; title=&quot;2&quot;&gt;    &lt;span class=&quot;st&quot;&gt;&amp;quot;links&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; [&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-3&quot; title=&quot;3&quot;&gt;        &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-4&quot; title=&quot;4&quot;&gt;            &lt;span class=&quot;st&quot;&gt;&amp;quot;source&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Node A&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-5&quot; title=&quot;5&quot;&gt;            &lt;span class=&quot;st&quot;&gt;&amp;quot;target&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Node B&amp;quot;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-6&quot; title=&quot;6&quot;&gt;        &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-7&quot; title=&quot;7&quot;&gt;    ]&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-8&quot; title=&quot;8&quot;&gt;    &lt;span class=&quot;st&quot;&gt;&amp;quot;nodes&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; [&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-9&quot; title=&quot;9&quot;&gt;        &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Node A&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;},&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-10&quot; title=&quot;10&quot;&gt;        &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Node B&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-11&quot; title=&quot;11&quot;&gt;    ]&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-12&quot; title=&quot;12&quot;&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I can pass this resulting JSON object off to a function that I created after a long time staring at one of &lt;a href=&quot;https://github.com/mbostock/d3/wiki/Gallery&quot;&gt;mbostock&lt;/a&gt;’s many amazing &lt;a href=&quot;http://bl.ocks.org/mbostock/1138500&quot;&gt;examples&lt;/a&gt; to create a D3 Force graph of verticies and edges:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre class=&quot;sourceCode numberSource javascript numberLines&quot;&gt;&lt;code class=&quot;sourceCode javascript&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;co&quot;&gt;// http://bl.ocks.org/mbostock/1138500&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; makeGraph  &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(target&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; graphData) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-3&quot; title=&quot;3&quot;&gt;    &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; target &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d3&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;select&lt;/span&gt;(target)&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-4&quot; title=&quot;4&quot;&gt;        bounds &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;target&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;node&lt;/span&gt;().&lt;span class=&quot;at&quot;&gt;getBoundingClientRect&lt;/span&gt;()&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-5&quot; title=&quot;5&quot;&gt;        fill   &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d3&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;scale&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;category20&lt;/span&gt;()&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-6&quot; title=&quot;6&quot;&gt;        radius &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-7&quot; title=&quot;7&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-8&quot; title=&quot;8&quot;&gt;    &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; svg &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;target&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;append&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;svg&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-9&quot; title=&quot;9&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;width&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;bounds&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;width&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-10&quot; title=&quot;10&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;height&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;bounds&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;height&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-11&quot; title=&quot;11&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-12&quot; title=&quot;12&quot;&gt;    &lt;span class=&quot;co&quot;&gt;// Arrow marker for end-of-line arrow&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-13&quot; title=&quot;13&quot;&gt;    &lt;span class=&quot;va&quot;&gt;svg&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;append&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;defs&amp;#39;&lt;/span&gt;).&lt;span class=&quot;at&quot;&gt;append&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;marker&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-14&quot; title=&quot;14&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;arrowhead&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-15&quot; title=&quot;15&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;refX&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;fl&quot;&gt;17.5&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-16&quot; title=&quot;16&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;refY&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-17&quot; title=&quot;17&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;markerWidth&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;8&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-18&quot; title=&quot;18&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;markerHeight&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-19&quot; title=&quot;19&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;orient&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;auto&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-20&quot; title=&quot;20&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;fill&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;#ccc&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-21&quot; title=&quot;21&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;append&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;path&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-22&quot; title=&quot;22&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;d&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;M 0,0 V 4 L6,2 Z&amp;#39;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-23&quot; title=&quot;23&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-24&quot; title=&quot;24&quot;&gt;    &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; link &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;svg&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;selectAll&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;line&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-25&quot; title=&quot;25&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;data&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;graphData&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;links&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-26&quot; title=&quot;26&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;enter&lt;/span&gt;()&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-27&quot; title=&quot;27&quot;&gt;            .&lt;span class=&quot;at&quot;&gt;append&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;line&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-28&quot; title=&quot;28&quot;&gt;                .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;class&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;link&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-29&quot; title=&quot;29&quot;&gt;                .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;marker-end&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;url(#arrowhead)&amp;#39;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-30&quot; title=&quot;30&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-31&quot; title=&quot;31&quot;&gt;    &lt;span class=&quot;co&quot;&gt;// Create a group for each node&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-32&quot; title=&quot;32&quot;&gt;    &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; node &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;svg&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;selectAll&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;g&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-33&quot; title=&quot;33&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;data&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;graphData&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;nodes&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-34&quot; title=&quot;34&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;enter&lt;/span&gt;()&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-35&quot; title=&quot;35&quot;&gt;            .&lt;span class=&quot;at&quot;&gt;append&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;g&amp;#39;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-36&quot; title=&quot;36&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-37&quot; title=&quot;37&quot;&gt;    &lt;span class=&quot;co&quot;&gt;// Color the node based on node&amp;#39;s git-type (otherwise, hot pink!)&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-38&quot; title=&quot;38&quot;&gt;    &lt;span class=&quot;va&quot;&gt;node&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;append&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;circle&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-39&quot; title=&quot;39&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; radius)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-40&quot; title=&quot;40&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;class&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;node&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-41&quot; title=&quot;41&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;fill&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(d) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-42&quot; title=&quot;42&quot;&gt;            &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; blue  &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;#1BA1E2&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-43&quot; title=&quot;43&quot;&gt;                red   &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;tomato&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-44&quot; title=&quot;44&quot;&gt;                green &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;#5BB75B&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-45&quot; title=&quot;45&quot;&gt;                pink  &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;#FE57A1&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-46&quot; title=&quot;46&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-47&quot; title=&quot;47&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;name&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;endsWith&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;.b&amp;#39;&lt;/span&gt;)) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; red&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-48&quot; title=&quot;48&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;name&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;endsWith&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;.t&amp;#39;&lt;/span&gt;)) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; blue&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-49&quot; title=&quot;49&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;name&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;endsWith&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;.c&amp;#39;&lt;/span&gt;)) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; green&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-50&quot; title=&quot;50&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; pink&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-51&quot; title=&quot;51&quot;&gt;        &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-52&quot; title=&quot;52&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-53&quot; title=&quot;53&quot;&gt;    &lt;span class=&quot;va&quot;&gt;node&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;append&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;text&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-54&quot; title=&quot;54&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;y&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; radius &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;fl&quot;&gt;1.5&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-55&quot; title=&quot;55&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;text-anchor&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;middle&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-56&quot; title=&quot;56&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;fill&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;#555&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-57&quot; title=&quot;57&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;text&lt;/span&gt;(&lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(d) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-58&quot; title=&quot;58&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;name&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-59&quot; title=&quot;59&quot;&gt;                &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;name&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;substring&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;8&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;...&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-60&quot; title=&quot;60&quot;&gt;            &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-61&quot; title=&quot;61&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-62&quot; title=&quot;62&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-63&quot; title=&quot;63&quot;&gt;         &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-64&quot; title=&quot;64&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-65&quot; title=&quot;65&quot;&gt;    &lt;span class=&quot;co&quot;&gt;// If the node has a type: tag it&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-66&quot; title=&quot;66&quot;&gt;    &lt;span class=&quot;va&quot;&gt;node&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;append&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;text&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-67&quot; title=&quot;67&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;text-anchor&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;middle&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-68&quot; title=&quot;68&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;y&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-69&quot; title=&quot;69&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;fill&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;white&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-70&quot; title=&quot;70&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;class&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;bold-text&amp;#39;&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-71&quot; title=&quot;71&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;text&lt;/span&gt;(&lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(d) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-72&quot; title=&quot;72&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;name&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;endsWith&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;.b&amp;#39;&lt;/span&gt;)) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;BLOB&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-73&quot; title=&quot;73&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;name&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;endsWith&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;.t&amp;#39;&lt;/span&gt;)) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;TREE&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-74&quot; title=&quot;74&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;name&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;endsWith&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;.c&amp;#39;&lt;/span&gt;)) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;COMMIT&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-75&quot; title=&quot;75&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-76&quot; title=&quot;76&quot;&gt;         &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-77&quot; title=&quot;77&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-78&quot; title=&quot;78&quot;&gt;    &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; charge &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;700&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;graphData&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;nodes&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-79&quot; title=&quot;79&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-80&quot; title=&quot;80&quot;&gt;    &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; force &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d3&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;layout&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;force&lt;/span&gt;()&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-81&quot; title=&quot;81&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;size&lt;/span&gt;([&lt;span class=&quot;va&quot;&gt;bounds&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;bounds&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;height&lt;/span&gt;])&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-82&quot; title=&quot;82&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;nodes&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;graphData&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;nodes&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-83&quot; title=&quot;83&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;links&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;graphData&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;links&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-84&quot; title=&quot;84&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;linkDistance&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;150&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-85&quot; title=&quot;85&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;charge&lt;/span&gt;(&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;(charge))&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-86&quot; title=&quot;86&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;gravity&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-87&quot; title=&quot;87&quot;&gt;        .&lt;span class=&quot;at&quot;&gt;on&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;tick&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; tick)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-88&quot; title=&quot;88&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-89&quot; title=&quot;89&quot;&gt;    &lt;span class=&quot;co&quot;&gt;// No fancy animation, tick amount varies based on number of nodes&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-90&quot; title=&quot;90&quot;&gt;    &lt;span class=&quot;va&quot;&gt;force&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;start&lt;/span&gt;()&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-91&quot; title=&quot;91&quot;&gt;    &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;graphData&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;nodes&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;++&lt;/span&gt;i) &lt;span class=&quot;va&quot;&gt;force&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;tick&lt;/span&gt;()&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-92&quot; title=&quot;92&quot;&gt;    &lt;span class=&quot;va&quot;&gt;force&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;stop&lt;/span&gt;()&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-93&quot; title=&quot;93&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-94&quot; title=&quot;94&quot;&gt;    &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;tick&lt;/span&gt;(e) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-95&quot; title=&quot;95&quot;&gt;        &lt;span class=&quot;co&quot;&gt;// Push sources up and targets down to form a weak tree.&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-96&quot; title=&quot;96&quot;&gt;        &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; k &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;-12&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;e&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;alpha&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-97&quot; title=&quot;97&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-98&quot; title=&quot;98&quot;&gt;        link&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-99&quot; title=&quot;99&quot;&gt;            .&lt;span class=&quot;at&quot;&gt;each&lt;/span&gt;(&lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(d) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;source&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;-=&lt;/span&gt; k&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;target&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+=&lt;/span&gt; k&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-100&quot; title=&quot;100&quot;&gt;                .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;x2&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(d) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;source&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-101&quot; title=&quot;101&quot;&gt;                .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;y2&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(d) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;source&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-102&quot; title=&quot;102&quot;&gt;                .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;x1&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(d) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;target&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-103&quot; title=&quot;103&quot;&gt;                .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;y1&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(d) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;target&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-104&quot; title=&quot;104&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-105&quot; title=&quot;105&quot;&gt;        node&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-106&quot; title=&quot;106&quot;&gt;            .&lt;span class=&quot;at&quot;&gt;attr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;transform&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(d) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-107&quot; title=&quot;107&quot;&gt;                &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;translate(&amp;#39;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;,&amp;#39;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;d&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;)&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-108&quot; title=&quot;108&quot;&gt;            &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-109&quot; title=&quot;109&quot;&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-110&quot; title=&quot;110&quot;&gt;&lt;span class=&quot;op&quot;&gt;};&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-111&quot; title=&quot;111&quot;&gt;&lt;span class=&quot;at&quot;&gt;makeGraph&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;.merkle-1&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; forceInput)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;merkle-1&quot;&gt;

&lt;/div&gt;
&lt;p&gt;You’d be forgiven for thinking that is a line.&lt;/p&gt;
&lt;p&gt;This directional line &lt;em&gt;is&lt;/em&gt; a DAG—albeit a simple one. &lt;code&gt;Node B&lt;/code&gt; depends on &lt;code&gt;Node A&lt;/code&gt; and that is the whole graph. If you want to get to &lt;code&gt;Node B&lt;/code&gt; then you have to start at &lt;code&gt;Node A&lt;/code&gt;. Depending on your problem-space, &lt;code&gt;Node B&lt;/code&gt; could be many things: A place in &lt;a href=&quot;https://en.wikipedia.org/wiki/Seven_Bridges_of_K%C3%B6nigsberg&quot;&gt;Königsberg&lt;/a&gt;, a target in a Makefile (or a &lt;a href=&quot;http://martinfowler.com/articles/rake.html&quot;&gt;Rakefile&lt;/a&gt;), or (brace yourself) a &lt;em&gt;Git object&lt;/em&gt;.&lt;/p&gt;
&lt;section id=&quot;git-object-anatomy&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;Git Object Anatomy &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#git-object-anatomy&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In order to understand how Git is a DAG, you need to understand Git “objects”:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;mkdir&lt;/span&gt; merkle&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-2&quot; title=&quot;2&quot;&gt;$ &lt;span class=&quot;bu&quot;&gt;cd&lt;/span&gt; merkle&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-3&quot; title=&quot;3&quot;&gt;$ &lt;span class=&quot;bu&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;This is the beginning&amp;#39;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; README&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-4&quot; title=&quot;4&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; init&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-5&quot; title=&quot;5&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; add .&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-6&quot; title=&quot;6&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; -m &lt;span class=&quot;st&quot;&gt;&amp;#39;Initial Commit&amp;#39;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-7&quot; title=&quot;7&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;find&lt;/span&gt; .git/objects/ -type f&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-8&quot; title=&quot;8&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/1b/9f426a8407ffee551ad2993c5d7d3780296353&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-9&quot; title=&quot;9&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/09/8e6de29daf4e55f83406b49f5768df9bc7d624&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-10&quot; title=&quot;10&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/1a/06ce381ac14f7a5baa1670691c2ff8a73aa6da&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What are Git objects? Because they look like nonsense:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb6-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;cat&lt;/span&gt; .git/objects/1b/9f426a8407ffee551ad2993c5d7d3780296353&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb6-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;xKOR02&lt;/span&gt;,V¢T¤̼¼̼t.&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After a little digging through the &lt;a href=&quot;https://git-scm.com/book/en/v2/Git-Internals-Git-Objects&quot;&gt;Pro Git&lt;/a&gt; book, Git objects are a little less non-sensicle. Git objects are simply &lt;code&gt;zlib&lt;/code&gt; compressed, formatted messages:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;ex&quot;&gt;python2&lt;/span&gt; -c &lt;span class=&quot;st&quot;&gt;&amp;#39;import sys,zlib; \&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;st&quot;&gt;  print zlib.decompress(sys.stdin.read());&amp;#39;&lt;/span&gt; \&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-3&quot; title=&quot;3&quot;&gt;    &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; .git/objects/1a/06ce381ac14f7a5baa1670691c2ff8a73aa6da&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;ex&quot;&gt;commit&lt;/span&gt; 195tree 098e6de29daf4e55f83406b49f5768df9bc7d624&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-5&quot; title=&quot;5&quot;&gt;&lt;span class=&quot;ex&quot;&gt;author&lt;/span&gt; Tyler Cipriani &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;tcipriani@wikimedia.org&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; 1458604120 -0700&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;ex&quot;&gt;committer&lt;/span&gt; Tyler Cipriani &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;tcipriani@wikimedia.org&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; 1458604120 -0700&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-7&quot; title=&quot;7&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb7-8&quot; title=&quot;8&quot;&gt;&lt;span class=&quot;ex&quot;&gt;Initial&lt;/span&gt; Commit&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Parts of that message are obvious: &lt;code&gt;author&lt;/code&gt; and &lt;code&gt;committer&lt;/code&gt; obviously come from my &lt;code&gt;.gitconfig&lt;/code&gt;. There is a Unix epoch timestamp with a timezone offset. &lt;code&gt;commit&lt;/code&gt; is the type of object. &lt;code&gt;195&lt;/code&gt; is the byte-length of the remainder of the message.&lt;/p&gt;
&lt;p&gt;There are a few parts of that message that aren’t immediately obvious. What is &lt;code&gt;tree 098e6de29daf4e55f83406b49f5768df9bc7d624&lt;/code&gt;? And why would we store this message in &lt;code&gt;.git/objects/1a/06ce381ac14f7a5baa1670691c2ff8a73aa6da&lt;/code&gt; and not &lt;code&gt;.git/objects/commit-message&lt;/code&gt;? Is a &lt;em&gt;merkle&lt;/em&gt; what I think it is? The answer to all of these questions and many more is the same: &lt;a href=&quot;https://en.wikipedia.org/wiki/Cryptographic_hash_function&quot;&gt;Cryptographic Hash Functions&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;hash-functions&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;Hash Functions &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#hash-functions&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A cryptographic hash function is a function that when given an input of any length it creates a fixed-length output. Furthermore (and more importantly), the fixed-length output should be unique to a given input; any change in input will likely cause a big change in the output. Git uses a cryptographic hash function called &lt;em&gt;Secure Hash Algorithm 1&lt;/em&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/SHA-1&quot;&gt;SHA-1&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;You can play with the SHA-1 function on the command line:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb8-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;bu&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;message&amp;#39;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;sha1sum&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb8-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;1133e3acf0a4cbb9d8b3bfd3f227731b8cd2650b&lt;/span&gt;  -&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb8-3&quot; title=&quot;3&quot;&gt;$ &lt;span class=&quot;bu&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;message&amp;#39;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;sha1sum&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb8-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;ex&quot;&gt;1133e3acf0a4cbb9d8b3bfd3f227731b8cd2650b&lt;/span&gt;  -&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb8-5&quot; title=&quot;5&quot;&gt;$ &lt;span class=&quot;bu&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;message1&amp;#39;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;sha1sum&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb8-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;ex&quot;&gt;c133514a60a4641b83b365d3dc7b715dc954e010&lt;/span&gt;  -&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note the big change in the output of &lt;code&gt;sha1sum&lt;/code&gt; from a tiny change in input. This is what cryptographic hash functions do.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;hash-that-dag&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;Hash that DAG! &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#hash-that-dag&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that we have some idea of what is inside a commit object, let’s reverse-engineer the commit object from the &lt;code&gt;HEAD&lt;/code&gt; of our &lt;code&gt;merkle&lt;/code&gt; repo:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-1&quot; title=&quot;1&quot;&gt;$  &lt;span class=&quot;ex&quot;&gt;python2&lt;/span&gt; -c &lt;span class=&quot;st&quot;&gt;&amp;#39;import sys,zlib; \&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;st&quot;&gt;print zlib.decompress(sys.stdin.read());&amp;#39;&lt;/span&gt; \&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-3&quot; title=&quot;3&quot;&gt;&lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; .git/objects/1a/06ce381ac14f7a5baa1670691c2ff8a73aa6da &lt;span class=&quot;kw&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;\&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;fu&quot;&gt;od&lt;/span&gt; -c&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-5&quot; title=&quot;5&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000000&lt;/span&gt;   c   o   m   m   i   t       1   9   5  \0   t   r   e   e    &lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-6&quot; title=&quot;6&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000020&lt;/span&gt;   0   9   8   e   6   d   e   2   9   d   a   f   4   e   5   5&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-7&quot; title=&quot;7&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000040&lt;/span&gt;   f   8   3   4   0   6   b   4   9   f   5   7   6   8   d   f&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-8&quot; title=&quot;8&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000060&lt;/span&gt;   9   b   c   7   d   6   2   4  \n   a   u   t   h   o   r    &lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-9&quot; title=&quot;9&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000100&lt;/span&gt;   T   y   l   e   r       C   i   p   r   i   a   n   i       &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-10&quot; title=&quot;10&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000120&lt;/span&gt;   t   c   i   p   r   i   a   n   i   @   w   i   k   i   m   e&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-11&quot; title=&quot;11&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000140&lt;/span&gt;   d   i   a   .   o   r   g   &lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt;       1   4   5   8   6   0   4&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-12&quot; title=&quot;12&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000160&lt;/span&gt;   1   2   0       -   0   7   0   0  \n   c   o   m   m   i   t&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-13&quot; title=&quot;13&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000200&lt;/span&gt;   t   e   r       T   y   l   e   r       C   i   p   r   i   a&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-14&quot; title=&quot;14&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000220&lt;/span&gt;   n   i       &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;   t   c   i   p   r   i   a   n   i   @   w   i&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-15&quot; title=&quot;15&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000240&lt;/span&gt;   k   i   m   e   d   i   a   .   o   r   g   &lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt;       1   4   5&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-16&quot; title=&quot;16&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000260&lt;/span&gt;   8   6   0   4   1   2   0       -   0   7   0   0  \n  \n   I&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-17&quot; title=&quot;17&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000300&lt;/span&gt;   n   i   t   i   a   l       C   o   m   m   i   t  \n  \n&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb9-18&quot; title=&quot;18&quot;&gt; &lt;span class=&quot;ex&quot;&gt;0000317&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb10-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;bu&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;tree 098e6de29daf4e55f83406b49f5768df9bc7d62k4\n&amp;#39;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; commit-msg&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb10-2&quot; title=&quot;2&quot;&gt;$ &lt;span class=&quot;bu&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;author Tyler Cipriani &amp;lt;tcipriani@wikimedia.org&amp;gt; 1458604120 -0700\n&amp;#39;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; commit-msg&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb10-3&quot; title=&quot;3&quot;&gt;$ &lt;span class=&quot;bu&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;committer Tyler Cipriani &amp;lt;tcipriani@wikimedia.org&amp;gt; 1458604120 -0700\n&amp;#39;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; commit-msg&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb10-4&quot; title=&quot;4&quot;&gt;$ &lt;span class=&quot;bu&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;\nInitial Commit\n&amp;#39;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; commit-msg&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb11-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;ex&quot;&gt;sha1sum&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;cat&lt;/span&gt; \&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb11-2&quot; title=&quot;2&quot;&gt;    &lt;span class=&quot;op&quot;&gt;&amp;lt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;commit &amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; \&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb11-3&quot; title=&quot;3&quot;&gt;    &lt;span class=&quot;op&quot;&gt;&amp;lt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;wc&lt;/span&gt; -c &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; commit-msg &lt;span class=&quot;kw&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;tr&lt;/span&gt; -d &lt;span class=&quot;st&quot;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; \&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb11-4&quot; title=&quot;4&quot;&gt;    &lt;span class=&quot;op&quot;&gt;&amp;lt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;%b&amp;#39;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; commit-msg&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb11-5&quot; title=&quot;5&quot;&gt;&lt;span class=&quot;ex&quot;&gt;1a06ce381ac14f7a5baa1670691c2ff8a73aa6da&lt;/span&gt;  /dev/fd/63&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Hmm… that seems familiar&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb12-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;bu&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;COMMIT_HASH=$(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;sha1sum&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;commit &amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;wc&lt;/span&gt; -c &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; commit-msg &lt;span class=&quot;kw&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;tr&lt;/span&gt; -d &lt;span class=&quot;st&quot;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;%b&amp;#39;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; commit-msg&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;cut&lt;/span&gt; -d&lt;span class=&quot;st&quot;&gt;&amp;#39; &amp;#39;&lt;/span&gt; -f1&lt;span class=&quot;va&quot;&gt;)&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb12-2&quot; title=&quot;2&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;.git/objects/&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;${COMMIT_HASH:0:2}&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt; -type f -name &lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;${COMMIT_HASH:&lt;/span&gt;&lt;span class=&quot;er&quot;&gt;(-38)&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb12-3&quot; title=&quot;3&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/1a/06ce381ac14f7a5baa1670691c2ff8a73aa6da&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The commit object is a zlib-compressed, formatted message that is stored in a file named after the SHA-1 hash of the file’s un-&lt;code&gt;zlib&lt;/code&gt; compressed contents.&lt;/p&gt;
&lt;p&gt;(/me wipes brow)&lt;/p&gt;
&lt;p&gt;Let’s use &lt;code&gt;git-cat-file&lt;/code&gt; to see if we can explore the &lt;code&gt;tree 098e6de29daf4e55f83406b49f5768df9bc7d62k4&lt;/code&gt;-part of the commit message object:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb13&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb13-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;cat&lt;/span&gt; .git/HEAD&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb13-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;ref&lt;/span&gt;: refs/heads/master&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb14&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb14-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;cat&lt;/span&gt; .git/refs/heads/master&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb14-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;1a06ce381ac14f7a5baa1670691c2ff8a73aa6da&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb15&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb15-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; cat-file -p 1a06ce381ac14f7a5baa1670691c2ff8a73aa6da&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb15-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;tree&lt;/span&gt; 098e6de29daf4e55f83406b49f5768df9bc7d624&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb15-3&quot; title=&quot;3&quot;&gt;&lt;span class=&quot;ex&quot;&gt;author&lt;/span&gt; Tyler Cipriani &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;tcipriani@wikimedia.org&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; 1458604120 -0700&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb15-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;ex&quot;&gt;committer&lt;/span&gt; Tyler Cipriani &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;tcipriani@wikimedia.org&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; 1458604120 -0700&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb16&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb16-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; cat-file -p 098e6de29daf4e55f83406b49f5768df9bc7d624&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb16-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;100644&lt;/span&gt; blob 1b9f426a8407ffee551ad2993c5d7d3780296353    README&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb17&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb17-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; cat-file -p 1b9f426a8407ffee551ad2993c5d7d3780296353&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb17-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;ex&quot;&gt;This&lt;/span&gt; is the beginning&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Hey that’s the text I put into &lt;code&gt;README&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;So &lt;code&gt;.git/HEAD&lt;/code&gt; refers to &lt;code&gt;.git/refs/heads/master&lt;/code&gt;, calling &lt;code&gt;git-cat-file&lt;/code&gt; on the object found inside that file shows that it’s the commit object we recreated. The commit object points to &lt;code&gt;098e6de29daf4e55f83406b49f5768df9bc7d624&lt;/code&gt;, which is a tree object with the contents: &lt;code&gt;100644 blob 1b9f426a8407ffee551ad2993c5d7d3780296353    README&lt;/code&gt; The &lt;code&gt;blob&lt;/code&gt; object &lt;code&gt;1b9f426a8407ffee551ad2993c5d7d3780296353&lt;/code&gt; is the contents of &lt;code&gt;README&lt;/code&gt;! So it seems each &lt;code&gt;commit&lt;/code&gt; object points to a &lt;code&gt;tree&lt;/code&gt; object that points to other objects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;what-was-i-talking-about-merkle-dags-d3.js&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;What was I talking about? Merkle DAGs? D3.js? &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#what-was-i-talking-about-merkle-dags-d3.js&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let’s see if we can paste together what Git is doing at a low-level when we make a new commit:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Take the contents of &lt;code&gt;README&lt;/code&gt;, hash the contents using SHA-1, and store as a &lt;code&gt;blob&lt;/code&gt; object in &lt;code&gt;.git/objects&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create a directory listing of the git working directory, listing each file, with its directory permissions and its hash value. Hash this directory listing and store as a &lt;code&gt;tree&lt;/code&gt; in &lt;code&gt;.git/objects&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Take the commit message, along with info from &lt;code&gt;.gitconfig&lt;/code&gt; and the hash of the top-level tree. Hash this information and store it as a &lt;code&gt;commit&lt;/code&gt; object in &lt;code&gt;.git/objects&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It seems that there may be a chain of dependencies:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb18&quot;&gt;&lt;pre class=&quot;sourceCode numberSource javascript numberLines&quot;&gt;&lt;code class=&quot;sourceCode javascript&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb18-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; gitDag &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb18-2&quot; title=&quot;2&quot;&gt;    &lt;span class=&quot;co&quot;&gt;// blob (add .b for blob)&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb18-3&quot; title=&quot;3&quot;&gt;    &lt;span class=&quot;st&quot;&gt;&amp;#39;1b9f426a8407ffee551ad2993c5d7d3780296353.b&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; []&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb18-4&quot; title=&quot;4&quot;&gt;    &lt;span class=&quot;co&quot;&gt;// tree (.t == tree) is a hash that includes the hash from blob&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb18-5&quot; title=&quot;5&quot;&gt;    &lt;span class=&quot;st&quot;&gt;&amp;#39;098e6de29daf4e55f83406b49f5768df9bc7d624.t&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; [&lt;span class=&quot;st&quot;&gt;&amp;#39;1b9f426a8407ffee551ad2993c5d7d3780296353.b&amp;#39;&lt;/span&gt;]&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb18-6&quot; title=&quot;6&quot;&gt;    &lt;span class=&quot;co&quot;&gt;// commit (.c == commit) is a hash that includes the hash from tree&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb18-7&quot; title=&quot;7&quot;&gt;    &lt;span class=&quot;st&quot;&gt;&amp;#39;1a06ce381ac14f7a5baa1670691c2ff8a73aa6da.c&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; [&lt;span class=&quot;st&quot;&gt;&amp;#39;098e6de29daf4e55f83406b49f5768df9bc7d624.t&amp;#39;&lt;/span&gt;]&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb18-8&quot; title=&quot;8&quot;&gt;&lt;span class=&quot;op&quot;&gt;};&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb18-9&quot; title=&quot;9&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb18-10&quot; title=&quot;10&quot;&gt;&lt;span class=&quot;at&quot;&gt;makeGraph&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;.merkle-2&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;forceFormat&lt;/span&gt;(gitDag))&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;merkle-2&quot;&gt;

&lt;/div&gt;
&lt;p&gt;You’d be forgiven for thinking that is a line.&lt;/p&gt;
&lt;p&gt;What’s really happening is that there is a &lt;code&gt;commit&lt;/code&gt; object (&lt;code&gt;1a06ce38&lt;/code&gt;) that depends on a &lt;code&gt;tree&lt;/code&gt; object (&lt;code&gt;098e6de2&lt;/code&gt;) that depends on a &lt;code&gt;blob&lt;/code&gt; (&lt;code&gt;1b9f426a&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Since it’s running each of these objects through a hash function and each of them contains a reference up the chain of dependencies, a minor change to either the &lt;code&gt;blob&lt;/code&gt; or the &lt;code&gt;tree&lt;/code&gt; will create a drastically different &lt;code&gt;commit&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;Applying a cryptographic hash function on top of a graph was &lt;a href=&quot;https://en.wikipedia.org/wiki/Ralph_Merkle&quot;&gt;Ralph Merkle&lt;/a&gt;’s big idea. This scheme makes magic possible. Transferring verifiable and trusted information through an untrusted medium is toatz for realz possible with Ralph’s little scheme.&lt;/p&gt;
&lt;p&gt;The idea is that if you have the &lt;em&gt;root-node hash&lt;/em&gt;, that is, the cryptographic hash of the node that depends on all other nodes (the &lt;code&gt;commit&lt;/code&gt; object in Git), and you obtained that root-node hash from a trusted source, you can trust all sub-nodes that stem from that root node &lt;em&gt;if&lt;/em&gt; the hash of all those sub-root-nodes matches the root-node hash!&lt;/p&gt;
&lt;p&gt;This is the mechanism by which things like Git, &lt;a href=&quot;https://github.com/ipfs/specs/blob/master/protocol/README.md#1-ipfs-and-the-merkle-dag&quot;&gt;IPFS&lt;/a&gt;, &lt;a href=&quot;http://chimera.labs.oreilly.com/books/1234000001802/ch07.html#merkle_trees&quot;&gt;Bitcoin&lt;/a&gt;, and &lt;a href=&quot;http://bittorrent.org/beps/bep_0030.html&quot;&gt;BitTorrent&lt;/a&gt; are made possible: changing any one node in the graph changes all nodes that depend on that node all the way to the root-node (the &lt;code&gt;commit&lt;/code&gt; in Git).&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;tales-from-the-merkle-graph&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;Tales from the Merkle Graph &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#tales-from-the-merkle-graph&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I wrote a simple NodeJS script that creates a graph that is suitable for input into the JavaScript that I’ve already written that will create a D3.js force graph with whatever it finds in &lt;code&gt;.git/objects&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb19&quot;&gt;&lt;pre class=&quot;sourceCode numberSource javascript numberLines&quot;&gt;&lt;code class=&quot;sourceCode javascript&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;co&quot;&gt;#!/usr/bin/env nodejs&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;co&quot;&gt;/* makeDag - creates a JSON dependency graph from .git/objects */&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-3&quot; title=&quot;3&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; glob &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;glob&amp;#39;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-5&quot; title=&quot;5&quot;&gt;    fs &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-6&quot; title=&quot;6&quot;&gt;    zlib &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;zlib&amp;#39;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-7&quot; title=&quot;7&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-8&quot; title=&quot;8&quot;&gt;&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; types &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;st&quot;&gt;&amp;#39;tree&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;commit&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;blob&amp;#39;&lt;/span&gt;]&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-9&quot; title=&quot;9&quot;&gt;    treeRegex &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-10&quot; title=&quot;10&quot;&gt;        &lt;span class=&quot;co&quot;&gt;// 100644 README\0[20 byte sha1]&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-11&quot; title=&quot;11&quot;&gt;        &lt;span class=&quot;dt&quot;&gt;regex&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;[0-9]+\s[^\0]+\0((&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;|\n){20})&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;/gm&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-12&quot; title=&quot;12&quot;&gt;        &lt;span class=&quot;dt&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(sha) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-13&quot; title=&quot;13&quot;&gt;            &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; buf &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;Buffer&lt;/span&gt;(sha[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;]&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;binary&amp;#39;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-14&quot; title=&quot;14&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;buf&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;toString&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;hex&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;.b&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-15&quot; title=&quot;15&quot;&gt;        &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-16&quot; title=&quot;16&quot;&gt;    &lt;span class=&quot;op&quot;&gt;},&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-17&quot; title=&quot;17&quot;&gt;    commitRegex &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-18&quot; title=&quot;18&quot;&gt;        &lt;span class=&quot;co&quot;&gt;// tree 098e6de29daf4e55f83406b49f5768df9bc7d624&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-19&quot; title=&quot;19&quot;&gt;        &lt;span class=&quot;dt&quot;&gt;regex&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;tree&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;)\s([a-f0-9]{40})&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;/gm&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-20&quot; title=&quot;20&quot;&gt;        &lt;span class=&quot;dt&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(sha) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-21&quot; title=&quot;21&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (sha[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;op&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;tree&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-22&quot; title=&quot;22&quot;&gt;                &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; sha[&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;] &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;.t&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-23&quot; title=&quot;23&quot;&gt;            &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-24&quot; title=&quot;24&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; sha[&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;] &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;.c&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-25&quot; title=&quot;25&quot;&gt;        &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-26&quot; title=&quot;26&quot;&gt;    &lt;span class=&quot;op&quot;&gt;},&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-27&quot; title=&quot;27&quot;&gt;    total &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-28&quot; title=&quot;28&quot;&gt;    final &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{};&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-29&quot; title=&quot;29&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-30&quot; title=&quot;30&quot;&gt;&lt;span class=&quot;co&quot;&gt;// determine file type, parse out SHA1s&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-31&quot; title=&quot;31&quot;&gt;&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; handleObjects &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(objData&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; name) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-32&quot; title=&quot;32&quot;&gt;    &lt;span class=&quot;va&quot;&gt;types&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;forEach&lt;/span&gt;(&lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(type) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-33&quot; title=&quot;33&quot;&gt;        &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; re&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; regex&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; match&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-34&quot; title=&quot;34&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-35&quot; title=&quot;35&quot;&gt;        &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;objData&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;startsWith&lt;/span&gt;(type)) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-36&quot; title=&quot;36&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-37&quot; title=&quot;37&quot;&gt;        key &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; name &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; type[&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;]&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-38&quot; title=&quot;38&quot;&gt;        final[key] &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; []&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-39&quot; title=&quot;39&quot;&gt;        &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (type &lt;span class=&quot;op&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;tree&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; objType &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; treeRegex&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-40&quot; title=&quot;40&quot;&gt;        &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (type &lt;span class=&quot;op&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;commit&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; objType &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; commitRegex&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-41&quot; title=&quot;41&quot;&gt;        &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (type &lt;span class=&quot;op&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;blob&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-42&quot; title=&quot;42&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-43&quot; title=&quot;43&quot;&gt;        &lt;span class=&quot;co&quot;&gt;// Remove the object-type and size from file&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-44&quot; title=&quot;44&quot;&gt;        objData &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;objData&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;split&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;#39;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-45&quot; title=&quot;45&quot;&gt;        &lt;span class=&quot;va&quot;&gt;objData&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;shift&lt;/span&gt;()&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-46&quot; title=&quot;46&quot;&gt;        objData &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;objData&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;join&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;#39;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-47&quot; title=&quot;47&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-48&quot; title=&quot;48&quot;&gt;        &lt;span class=&quot;co&quot;&gt;// Recursive regex match remainder&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-49&quot; title=&quot;49&quot;&gt;        &lt;span class=&quot;cf&quot;&gt;while&lt;/span&gt; ((match &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;objType&lt;/span&gt;.&lt;span class=&quot;va&quot;&gt;regex&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;exec&lt;/span&gt;(objData)) &lt;span class=&quot;op&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;null&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-50&quot; title=&quot;50&quot;&gt;            final[key].&lt;span class=&quot;at&quot;&gt;push&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;objType&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;fn&lt;/span&gt;(match))&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-51&quot; title=&quot;51&quot;&gt;        &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-52&quot; title=&quot;52&quot;&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-53&quot; title=&quot;53&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-54&quot; title=&quot;54&quot;&gt;    &lt;span class=&quot;co&quot;&gt;// Don&amp;#39;t output until you&amp;#39;ve got it all&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-55&quot; title=&quot;55&quot;&gt;    &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;va&quot;&gt;Object&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;keys&lt;/span&gt;(final).&lt;span class=&quot;at&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!==&lt;/span&gt; total) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-56&quot; title=&quot;56&quot;&gt;        &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-57&quot; title=&quot;57&quot;&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-58&quot; title=&quot;58&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-59&quot; title=&quot;59&quot;&gt;    &lt;span class=&quot;co&quot;&gt;// Output what ya got.&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-60&quot; title=&quot;60&quot;&gt;    &lt;span class=&quot;va&quot;&gt;console&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;log&lt;/span&gt;(final)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-61&quot; title=&quot;61&quot;&gt;&lt;span class=&quot;op&quot;&gt;};&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-62&quot; title=&quot;62&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-63&quot; title=&quot;63&quot;&gt;&lt;span class=&quot;co&quot;&gt;// Readable object names not file names&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-64&quot; title=&quot;64&quot;&gt;&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; getName &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(file) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-65&quot; title=&quot;65&quot;&gt;    &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; fileParts &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;file&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;split&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-66&quot; title=&quot;66&quot;&gt;        len &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;fileParts&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-67&quot; title=&quot;67&quot;&gt;    &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; fileParts[len &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;] &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; fileParts[len &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;]&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-68&quot; title=&quot;68&quot;&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-69&quot; title=&quot;69&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-70&quot; title=&quot;70&quot;&gt;&lt;span class=&quot;co&quot;&gt;// Inflate the deflated git object file&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-71&quot; title=&quot;71&quot;&gt;&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; handleFile &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(file&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; out) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-72&quot; title=&quot;72&quot;&gt;    &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; name &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;getName&lt;/span&gt;(file)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-73&quot; title=&quot;73&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-74&quot; title=&quot;74&quot;&gt;    &lt;span class=&quot;va&quot;&gt;fs&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;readFile&lt;/span&gt;(file&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(e&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; data) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-75&quot; title=&quot;75&quot;&gt;        &lt;span class=&quot;va&quot;&gt;zlib&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;inflate&lt;/span&gt;(data&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(e&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; data) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-76&quot; title=&quot;76&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (e) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;console&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;log&lt;/span&gt;(file&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; e)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-77&quot; title=&quot;77&quot;&gt;            &lt;span class=&quot;at&quot;&gt;handleObjects&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;data&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;toString&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;binary&amp;#39;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; name)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-78&quot; title=&quot;78&quot;&gt;        &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-79&quot; title=&quot;79&quot;&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-80&quot; title=&quot;80&quot;&gt;&lt;span class=&quot;op&quot;&gt;};&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-81&quot; title=&quot;81&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-82&quot; title=&quot;82&quot;&gt;&lt;span class=&quot;co&quot;&gt;// Sort through the gitobjects directory&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-83&quot; title=&quot;83&quot;&gt;&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; handleFiles &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(files) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-84&quot; title=&quot;84&quot;&gt;    &lt;span class=&quot;va&quot;&gt;files&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;forEach&lt;/span&gt;(&lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(file) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-85&quot; title=&quot;85&quot;&gt;        &lt;span class=&quot;va&quot;&gt;fs&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;stat&lt;/span&gt;(file&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(e&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; f) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-86&quot; title=&quot;86&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (e) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-87&quot; title=&quot;87&quot;&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;va&quot;&gt;f&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;isFile&lt;/span&gt;()) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-88&quot; title=&quot;88&quot;&gt;                &lt;span class=&quot;co&quot;&gt;// Don&amp;#39;t worry about pack files for now&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-89&quot; title=&quot;89&quot;&gt;                &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;va&quot;&gt;file&lt;/span&gt;.&lt;span class=&quot;at&quot;&gt;indexOf&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;pack&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;-1&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-90&quot; title=&quot;90&quot;&gt;                total&lt;span class=&quot;op&quot;&gt;++;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-91&quot; title=&quot;91&quot;&gt;                &lt;span class=&quot;at&quot;&gt;handleFile&lt;/span&gt;(file)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-92&quot; title=&quot;92&quot;&gt;            &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-93&quot; title=&quot;93&quot;&gt;        &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-94&quot; title=&quot;94&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-95&quot; title=&quot;95&quot;&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-96&quot; title=&quot;96&quot;&gt;&lt;span class=&quot;op&quot;&gt;};&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-97&quot; title=&quot;97&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-98&quot; title=&quot;98&quot;&gt;(&lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;() &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-99&quot; title=&quot;99&quot;&gt;    &lt;span class=&quot;at&quot;&gt;glob&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;.git/objects/**/*&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(e&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; f) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-100&quot; title=&quot;100&quot;&gt;        &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (e) &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; e&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-101&quot; title=&quot;101&quot;&gt;        &lt;span class=&quot;at&quot;&gt;handleFiles&lt;/span&gt;(f)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-102&quot; title=&quot;102&quot;&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb19-103&quot; title=&quot;103&quot;&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;)()&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Merkle graph transformations are often difficult to describe, but easy to see. Using this last piece of code to create and view graphs for several repositories has been illuminating. The graph visualization both illuminates and challenges my understanding of Git in ways I didn’t anticipate.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;the-tale-of-commit-message-bike-shedding&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;The Tale of Commit Message Bike-shedding &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#the-tale-of-commit-message-bike-shedding&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you change your commit message, what happens to the graph? What depends on a commit? Where is the context for a commit?&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb20&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb20-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; commit --amend -m &lt;span class=&quot;st&quot;&gt;&amp;#39;This is the commit message now&amp;#39;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb20-2&quot; title=&quot;2&quot;&gt;[&lt;span class=&quot;ex&quot;&gt;master&lt;/span&gt; 585448a] This is the commit message now&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb20-3&quot; title=&quot;3&quot;&gt; &lt;span class=&quot;ex&quot;&gt;Date&lt;/span&gt;: Mon Mar 21 16:48:40 2016 -0700&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb20-4&quot; title=&quot;4&quot;&gt;  &lt;span class=&quot;ex&quot;&gt;1&lt;/span&gt; file changed, 1 insertion(+)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb20-5&quot; title=&quot;5&quot;&gt;   &lt;span class=&quot;ex&quot;&gt;create&lt;/span&gt; mode 100644 README&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb20-6&quot; title=&quot;6&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;find&lt;/span&gt; .git/objects -type f&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb20-7&quot; title=&quot;7&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/1b/9f426a8407ffee551ad2993c5d7d3780296353&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb20-8&quot; title=&quot;8&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/09/8e6de29daf4e55f83406b49f5768df9bc7d624&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb20-9&quot; title=&quot;9&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/1a/06ce381ac14f7a5baa1670691c2ff8a73aa6da&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb20-10&quot; title=&quot;10&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/da/94af3a21ac7e0c875bbbe6162aa1d26d699c73&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now the DAG is a bit different:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb21&quot;&gt;&lt;pre class=&quot;sourceCode numberSource javascript numberLines&quot;&gt;&lt;code class=&quot;sourceCode javascript&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb21-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; gitDag &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;098e6de29daf4e55f83406b49f5768df9bc7d624.t&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; [ &lt;span class=&quot;st&quot;&gt;&amp;#39;1b9f426a8407ffee551ad2993c5d7d3780296353.b&amp;#39;&lt;/span&gt; ]&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb21-2&quot; title=&quot;2&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;1a06ce381ac14f7a5baa1670691c2ff8a73aa6da.c&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; [ &lt;span class=&quot;st&quot;&gt;&amp;#39;098e6de29daf4e55f83406b49f5768df9bc7d624.t&amp;#39;&lt;/span&gt; ]&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb21-3&quot; title=&quot;3&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;1b9f426a8407ffee551ad2993c5d7d3780296353.b&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; []&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb21-4&quot; title=&quot;4&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;da94af3a21ac7e0c875bbbe6162aa1d26d699c73.c&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; [ &lt;span class=&quot;st&quot;&gt;&amp;#39;098e6de29daf4e55f83406b49f5768df9bc7d624.t&amp;#39;&lt;/span&gt; ] &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb21-5&quot; title=&quot;5&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb21-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;at&quot;&gt;makeGraph&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;.merkle-3&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;forceFormat&lt;/span&gt;(gitDag))&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;merkle-3&quot;&gt;

&lt;/div&gt;
&lt;p&gt;Here we see that there are now two &lt;code&gt;commit&lt;/code&gt; objects (&lt;code&gt;1a06ce38&lt;/code&gt; and &lt;code&gt;da94af3a&lt;/code&gt;) that both depend on a single &lt;code&gt;tree&lt;/code&gt; object (&lt;code&gt;098e6de2&lt;/code&gt;) that depends on a single &lt;code&gt;blob&lt;/code&gt; (&lt;code&gt;1b9f426a&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;One of these commit objects will never be seen with &lt;code&gt;git log&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;the-orphan-blob-that-dared-to-dream&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;The Orphan Blob That Dared to Dream &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#the-orphan-blob-that-dared-to-dream&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;TIL: Git creates &lt;code&gt;blob&lt;/code&gt; objects as soon as a file is added to the staging area.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb22&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb22-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;bu&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;staged&amp;#39;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; staged&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb22-2&quot; title=&quot;2&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;find&lt;/span&gt; .git/objects -type f&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb22-3&quot; title=&quot;3&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/1b/9f426a8407ffee551ad2993c5d7d3780296353&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb22-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/09/8e6de29daf4e55f83406b49f5768df9bc7d624&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb22-5&quot; title=&quot;5&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/1a/06ce381ac14f7a5baa1670691c2ff8a73aa6da&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb22-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/da/94af3a21ac7e0c875bbbe6162aa1d26d699c73&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice that nothing depends on this object just yet. It’s a lonely orphan &lt;code&gt;blob&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb23&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; add staged&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-2&quot; title=&quot;2&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;find&lt;/span&gt; .git/objects -type f&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-3&quot; title=&quot;3&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/1b/9f426a8407ffee551ad2993c5d7d3780296353&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-4&quot; title=&quot;4&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/09/8e6de29daf4e55f83406b49f5768df9bc7d624&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-5&quot; title=&quot;5&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/1a/06ce381ac14f7a5baa1670691c2ff8a73aa6da&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/da/94af3a21ac7e0c875bbbe6162aa1d26d699c73&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-7&quot; title=&quot;7&quot;&gt;&lt;span class=&quot;ex&quot;&gt;.git/objects/19/d9cc8584ac2c7dcf57d2680375e80f099dc481&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-8&quot; title=&quot;8&quot;&gt;$ &lt;span class=&quot;ex&quot;&gt;makeDag&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-9&quot; title=&quot;9&quot;&gt;&lt;span class=&quot;kw&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;098e6de29daf4e55f83406b49f5768df9bc7d624.t&amp;#39;&lt;/span&gt;:&lt;span class=&quot;bu&quot;&gt; [&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;1b9f426a8407ffee551ad2993c5d7d3780296353.b&amp;#39;&lt;/span&gt; ],&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-10&quot; title=&quot;10&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;19d9cc8584ac2c7dcf57d2680375e80f099dc481.b&amp;#39;&lt;/span&gt;: [],&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-11&quot; title=&quot;11&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;1a06ce381ac14f7a5baa1670691c2ff8a73aa6da.c&amp;#39;&lt;/span&gt;: [ &lt;span class=&quot;st&quot;&gt;&amp;#39;098e6de29daf4e55f83406b49f5768df9bc7d624.t&amp;#39;&lt;/span&gt; ],&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-12&quot; title=&quot;12&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;da94af3a21ac7e0c875bbbe6162aa1d26d699c73.c&amp;#39;&lt;/span&gt;: [ &lt;span class=&quot;st&quot;&gt;&amp;#39;098e6de29daf4e55f83406b49f5768df9bc7d624.t&amp;#39;&lt;/span&gt; ],&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb23-13&quot; title=&quot;13&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;1b9f426a8407ffee551ad2993c5d7d3780296353.b&amp;#39;&lt;/span&gt;: [] }&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;merkle-4&quot;&gt;

&lt;/div&gt;
&lt;p&gt;Even unstaging and deleting the file doesn’t remove the object. Orphan objects in git are only garbage collected as part of &lt;code&gt;git gc --prune&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When this object is committed to the repo, it creates a whole new layer of the graph:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb24&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; commit -m &lt;span class=&quot;st&quot;&gt;&amp;#39;Add staged file&amp;#39;&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-2&quot; title=&quot;2&quot;&gt;[&lt;span class=&quot;ex&quot;&gt;master&lt;/span&gt; 4f407b3] Add staged file&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-3&quot; title=&quot;3&quot;&gt; &lt;span class=&quot;ex&quot;&gt;1&lt;/span&gt; file changed, 1 insertion(+)&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-4&quot; title=&quot;4&quot;&gt; &lt;span class=&quot;ex&quot;&gt;create&lt;/span&gt; mode 100644 staged&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-5&quot; title=&quot;5&quot;&gt;$ &lt;span class=&quot;ex&quot;&gt;makeDag&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-6&quot; title=&quot;6&quot;&gt;&lt;span class=&quot;kw&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;098e6de29daf4e55f83406b49f5768df9bc7d624.t&amp;#39;&lt;/span&gt;:&lt;span class=&quot;bu&quot;&gt; [&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;1b9f426a8407ffee551ad2993c5d7d3780296353.b&amp;#39;&lt;/span&gt; ],&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-7&quot; title=&quot;7&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;19d9cc8584ac2c7dcf57d2680375e80f099dc481.b&amp;#39;&lt;/span&gt;: [],&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-8&quot; title=&quot;8&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;1a06ce381ac14f7a5baa1670691c2ff8a73aa6da.c&amp;#39;&lt;/span&gt;: [ &lt;span class=&quot;st&quot;&gt;&amp;#39;098e6de29daf4e55f83406b49f5768df9bc7d624.t&amp;#39;&lt;/span&gt; ],&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-9&quot; title=&quot;9&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;1b9f426a8407ffee551ad2993c5d7d3780296353.b&amp;#39;&lt;/span&gt;: [],&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-10&quot; title=&quot;10&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;4f407b396e6ecbb65de6cf192259c18ecd4d1e9b.c&amp;#39;&lt;/span&gt;: &lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-11&quot; title=&quot;11&quot;&gt;   [ &lt;span class=&quot;st&quot;&gt;&amp;#39;7ce38101e91de29ee0fee3aa9940cc81159e0f8d.t&amp;#39;&lt;/span&gt;,&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-12&quot; title=&quot;12&quot;&gt;     &lt;span class=&quot;st&quot;&gt;&amp;#39;da94af3a21ac7e0c875bbbe6162aa1d26d699c73.c&amp;#39;&lt;/span&gt; ],&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-13&quot; title=&quot;13&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;7ce38101e91de29ee0fee3aa9940cc81159e0f8d.t&amp;#39;&lt;/span&gt;: &lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-14&quot; title=&quot;14&quot;&gt;   [ &lt;span class=&quot;st&quot;&gt;&amp;#39;1b9f426a8407ffee551ad2993c5d7d3780296353.b&amp;#39;&lt;/span&gt;,&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-15&quot; title=&quot;15&quot;&gt;     &lt;span class=&quot;st&quot;&gt;&amp;#39;19d9cc8584ac2c7dcf57d2680375e80f099dc481.b&amp;#39;&lt;/span&gt; ],&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb24-16&quot; title=&quot;16&quot;&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;da94af3a21ac7e0c875bbbe6162aa1d26d699c73.c&amp;#39;&lt;/span&gt;: [ &lt;span class=&quot;st&quot;&gt;&amp;#39;098e6de29daf4e55f83406b49f5768df9bc7d624.t&amp;#39;&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt; ]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;}&lt;/span&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;merkle-5&quot;&gt;

&lt;/div&gt;
&lt;p&gt;So we’ve created a new commit (&lt;code&gt;4f407b39&lt;/code&gt;) that is the parent of a different commit (&lt;code&gt;da94af3a&lt;/code&gt;) and a new tree (&lt;code&gt;7ce38101&lt;/code&gt;) that contains our old &lt;code&gt;README&lt;/code&gt; blob (&lt;code&gt;1b9f426a&lt;/code&gt;) and our new, previously orphaned, blob (&lt;code&gt;19d9cc85&lt;/code&gt;).&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;the-tale-of-powerful-software&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;The Tale of Powerful Software &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#the-tale-of-powerful-software&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I’ve always enjoyed the idea that software (and computer science more generally) is nothing but an abstraction to manage complexity. Good software— powerful software—like Git—is a software that manages an incredible amount of complexity and hides it completely from the user.&lt;/p&gt;
&lt;p&gt;In recognition of this idea, I’ll leave you with the graph of my local copy of &lt;a href=&quot;https://github.com/thcipriani/clippy&quot;&gt;clippy&lt;/a&gt;—a small command line tool I created that is like &lt;code&gt;man(1)&lt;/code&gt; except it shows &lt;a href=&quot;https://en.wikipedia.org/wiki/Office_Assistant&quot;&gt;Clippy&lt;/a&gt; at the end of the &lt;code&gt;man&lt;/code&gt; output (yes, it’s dumb).&lt;/p&gt;
&lt;p&gt;This should give you an idea of the complexity that is abstracted by the Git merkle graph: this repo contains 5 commits!&lt;/p&gt;
&lt;div class=&quot;merkle-container&quot;&gt;
&lt;div class=&quot;merkle-6&quot;&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
</description>


	<comments>//tylercipriani.com/blog/2016/03/21/Visualizing-Git-Merkle-DAG-with-D3.js/#comments</comments>

</item>
<item>
	<title>Integrating git with your existing website</title>

	<guid isPermaLink="false">https://tylercipriani.com/blog/2012/10/21/move-existing-website-to-git/</guid>

	<link>https://tylercipriani.com/blog/2012/10/21/move-existing-website-to-git/</link>

	<dc:creator>Tyler Cipriani</dc:creator>



	<category>computing</category>

	<category>vcs</category>


	<pubDate>Sun, 21 Oct 2012 00:00:00 +0000</pubDate>
	<dcterms:modified>2017-07-01T00:49:09Z</dcterms:modified>


	<description>&lt;p&gt;Better git it in your soul&lt;a href=&quot;http://www.youtube.com/watch?v=SPoK1lryfh4&quot;&gt;*&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Git has a &lt;a href=&quot;https://bitly.com/bundles/matthewmccullough/1&quot;&gt;lot&lt;/a&gt; of &lt;a href=&quot;http://try.github.com/levels/1/challenges/1&quot;&gt;great&lt;/a&gt; &lt;a href=&quot;https://peepcode.com/products/git&quot;&gt;tutorials&lt;/a&gt; for getting started. There are also a number of great articles on &lt;a href=&quot;http://daneden.github.com/github-workflow/&quot;&gt;how to use git and github&lt;/a&gt; for your workflow.&lt;/p&gt;
&lt;p&gt;What I haven’t seen is an article on how to integrate git with your current site without storing any code on github. I’m writing this blog to create a quick reference for how to get up and running using git on your existing site.&lt;/p&gt;
&lt;section id=&quot;needed&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;Needed &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#needed&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I’m making the assumption that you have the following: &lt;ul&gt; &lt;li&gt;Knowledge of Linux&lt;/li&gt; &lt;li&gt;­&lt;a href=&quot;http://library.linode.com/lamp-guides/ubuntu-12.04-precise-pangolin&quot;&gt; A local development environment &lt;/a&gt;&lt;/li&gt; &lt;li&gt;git-core installed both locally and on your webserver&lt;/li&gt; &lt;li&gt;rsync installed both locally and on your webserver&lt;/li&gt; &lt;li&gt;­&lt;a href=&quot;http://www.commandlinefu.com/commands/view/771/copy-your-ssh-public-key-on-a-remote-machine-for-passwordless-login-the-easy-way&quot;&gt; Keyless SSH access to your webserver &lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/p&gt;
&lt;p&gt;I’m using Ubuntu 12.04 locally, but I’d assume that most of this won’t be too different on a different distribution or on a Mac—but I’m probably totally wrong about that ☺&lt;/p&gt;
&lt;hr /&gt;
&lt;/section&gt;
&lt;section id=&quot;step-one&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;Step One: &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#step-one&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;RSync your site to your local development environment&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In order to begin to develop locally (and break the old &lt;a href=&quot;http://www.bnj.com/cowboy-coding-pink-sombrero/&quot;&gt;cowboy-coding&lt;/a&gt; habits that you’ve undoubtedly developed over the years) you need a local copy of your site.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Open your terminal emulator and &lt;code&gt;cd&lt;/code&gt; to the directory in which you will be storing these files (i.e. &lt;code&gt;cd /srv­/www­/tylercipriani.com­/public_html&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Rsync the &lt;code&gt;htdocs&lt;/code&gt; or &lt;code&gt;public_html&lt;/code&gt; from your webserver into this local directory:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb1-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;rsync&lt;/span&gt; -av -e &lt;span class=&quot;st&quot;&gt;&amp;quot;ssh -p &amp;lt;port&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;rsync-username&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt;@&lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;webserver&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt;:/path/to/public_html/ .&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The command breaks down like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;a&lt;/code&gt; means “Archive”—keeps permissions, mtimes, etc the same&lt;/li&gt;
&lt;li&gt;&lt;code&gt;v&lt;/code&gt; means “Verbose”—increases verbosity of the command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;e&lt;/code&gt; means “RSH”—allows you to use remote shell (same as RSH=command)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:/path/to/htdocs/&lt;/code&gt;—the path to you htdocs folder. The trailing &lt;code&gt;/&lt;/code&gt; is significant—it means copy the content of the htdocs directory rather than the directory by name&lt;/li&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.&lt;/code&gt; is the current directory&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;/section&gt;
&lt;section id=&quot;step-two&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;Step Two: &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#step-two&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Initialize git in local development environment.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This step will create a new git repository on your local machine and add all the code that you’ve rsynced in the previous step to that repo.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;­&lt;code&gt;cd&lt;/code&gt; to the directory to which you previously rsynced your site and initialize a git repository by running &lt;code&gt;git init&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;bu&quot;&gt;cd&lt;/span&gt; /srv/www/tylercipriani.com/public_html/&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb2-2&quot; title=&quot;2&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; init&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Add the contents of the current directory to the git repository by running &lt;code&gt;git add .&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Commit all your newly added files to the repo by running your first commit &lt;code&gt;git commit -m “First Commit”&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;/section&gt;
&lt;section id=&quot;step-three&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;Step Three: &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#step-three&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Setup a bare repo on your web server&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You need a bare repo out on your webserver that will act as a mirror to your local development environment.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;ssh into your webserver and make a new directory, I usually make it above the webroot (i.e. &lt;code&gt;htdocs&lt;/code&gt;)&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb3-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;mkdir&lt;/span&gt; tylercipriani.com.git &lt;span class=&quot;kw&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;cd&lt;/span&gt; tylercipriani.com.git&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once inside the new directory initialize a bare repository by using the &lt;code&gt;--bare&lt;/code&gt; flag:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb4-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; init --bare&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we can define a new post-receive hook that will be triggered whenever an update is pushed to this new bare repository. The post-receive hook can be any type of script you want, the script below is written in bash. &lt;code&gt;cd&lt;/code&gt; into the &lt;code&gt;.git/hooks&lt;/code&gt; directory and create a file called “post-receive”. Copy the code below into the file:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre class=&quot;sourceCode numberSource bash numberLines&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-1&quot; title=&quot;1&quot;&gt;&lt;span class=&quot;co&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb5-2&quot; title=&quot;2&quot;&gt;&lt;span class=&quot;va&quot;&gt;GIT_WORK_TREE=&lt;/span&gt;/path/to/your/htdocs/direcotry &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; checkout -f&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;make sure that this code is executable by running &lt;code&gt;chmod +x .git/hooks/post-receive&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;/section&gt;
&lt;section id=&quot;youre-done&quot; class=&quot;level2&quot;&gt;
&lt;h2&gt;You’re Done! &lt;a href=&quot;https://tylercipriani.com/tags/vcs/#youre-done&quot;&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Push to your new repo, you beautiful command-line ninja, you!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Back on your local machine, in the webroot of your local development environment, add your bare webserver repo as your &lt;code&gt;remote&lt;/code&gt; and push your git repo up to your server. The post-receive hook will take care of the rest!&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;a class=&quot;sourceLine&quot; id=&quot;cb6-1&quot; title=&quot;1&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; remote add web ssh://user@tylercipriani.com/home/user/tylercipriani.com.git&lt;/a&gt;
&lt;a class=&quot;sourceLine&quot; id=&quot;cb6-2&quot; title=&quot;2&quot;&gt;$ &lt;span class=&quot;fu&quot;&gt;git&lt;/span&gt; push -u origin master&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By using the &lt;code&gt;-u&lt;/code&gt; flag you’re setting the upstream which means you can just run &lt;code&gt;git pull&lt;/code&gt; without further arguments to merge origin and master.&lt;/p&gt;
&lt;/section&gt;
</description>


	<comments>//tylercipriani.com/blog/2012/10/21/move-existing-website-to-git/#comments</comments>

</item>

</channel>
</rss>
