summaryrefslogtreecommitdiff
path: root/.html/git
diff options
context:
space:
mode:
Diffstat (limited to '.html/git')
-rw-r--r--.html/git/_list.html109
-rw-r--r--.html/git/config.html151
-rw-r--r--.html/git/detached-sigs.html359
-rw-r--r--.html/git/index.html109
-rw-r--r--.html/git/integrate.html118
-rw-r--r--.html/git/pull-request-workflow.html163
-rw-r--r--.html/git/scratch.html134
-rw-r--r--.html/git/stop-using-git-pull-to-deploy.html178
-rw-r--r--.html/git/survival.html174
-rw-r--r--.html/git/theory-and-practice/_list.html96
-rw-r--r--.html/git/theory-and-practice/index.html126
-rw-r--r--.html/git/theory-and-practice/objects.html202
-rw-r--r--.html/git/theory-and-practice/refs-and-names.html199
13 files changed, 2118 insertions, 0 deletions
diff --git a/.html/git/_list.html b/.html/git/_list.html
new file mode 100644
index 0000000..59ee1d4
--- /dev/null
+++ b/.html/git/_list.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ ls /git
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="./">git</a>
+
+ </li>
+
+ <li class="crumb-2 last">
+
+ <span class="list-crumb">list</span>
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="listing">
+ <h1><code>ls /git</code></h1>
+
+
+ <div id="directories">
+ <h2>Directories</h2>
+ <ul>
+
+ <li><a href="theory-and-practice/">theory-and-practice/</a></li>
+
+ </ul>
+ </div>
+
+
+
+ <div id="pages">
+ <h2>Pages</h2>
+ <ul>
+
+ <li><a href="scratch">Git Is Not Magic</a></li>
+
+ <li><a href="survival">Git Survival Guide</a></li>
+
+ <li><a href="integrate">Integrating with Git: A Field Guide</a></li>
+
+ <li><a href="pull-request-workflow">Life With Pull Requests</a></li>
+
+ <li><a href="detached-sigs">Notes Towards Detached Signatures in Git</a></li>
+
+ <li><a href="stop-using-git-pull-to-deploy">Stop Using Git Pull To Deploy</a></li>
+
+ <li><a href="config">git-config Settings You Want</a></li>
+
+ </ul>
+ </div>
+
+
+
+ </div>
+
+
+
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git">See this directory on Bitbucket</a>.
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/.html/git/config.html b/.html/git/config.html
new file mode 100644
index 0000000..c21c4f5
--- /dev/null
+++ b/.html/git/config.html
@@ -0,0 +1,151 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ git-config Settings You Want
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="./">git</a>
+
+ </li>
+
+ <li class="crumb-2 last">
+
+ config
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="article">
+ <h1 id="git-config-settings-you-want">git-config Settings You Want</h1>
+<p>Git comes with some fairly <a href="http://www.tux.org/lkml/">lkml</a>-specific
+configuration defaults. You should fix this. All of the items below can be set
+either for your entire login account (<code>git config --global</code>) or for a specific
+repository (<code>git config</code>).</p>
+<p>Full documentation is under <code>git help config</code>, unless otherwise stated.</p>
+<ul>
+<li>
+<p><code>git config user.name 'Your Full Name'</code> and <code>git config user.email
+ 'your-email@example.com'</code>, obviously.</p>
+</li>
+<li>
+<p><code>git config push.default simple</code> - the default behaviour (called <code>matching</code>)
+ of an unqualified <code>git push</code> is to identify pairs of branches by name and
+ push all matches from your local repository to the remote. Given that
+ branches have explicit “upstream” configuration identifying which, if any,
+ branch in which, if any, remote they're associated with, this is dumb. The
+ <code>simple</code> mode pushes the current branch to its upstream remote, if and only
+ if the local branch name and the remote branch name match <em>and</em> the local
+ branch tracks the remote branch. Requires Git 1.8 or later; will be the
+ default in Git 2.0. (For older versions of Git, use <code>upstream</code> instead,
+ which does not require that branch names match.)</p>
+</li>
+<li>
+<p><code>git config merge.defaultToUpstream true</code> - causes an unqualified <code>git
+ merge</code> to merge the current branch's configured upstream branch, rather than
+ being an error. (<code>git rebase</code> always has this behaviour. Consistent!) You
+ should still merge thoughtfully.</p>
+</li>
+<li>
+<p><code>git config rebase.autosquash true</code> - causes <code>git rebase -i</code> to parse magic
+ comments created by <code>git commit --squash=some-hash</code> and <code>git commit
+ --fixup=some-hash</code> and reorder the commit list before presenting it for
+ further editing. See the descriptions of “squash” and “fixup” in <code>git help
+ rebase</code> for details; autosquash makes amending commits other than the most
+ recent easier and less error-prone.</p>
+</li>
+<li>
+<p><code>git config branch.autosetupmerge always</code> - newly-created branches whose
+ start point is a branch (<code>git checkout master -b some-feature</code>, <code>git branch
+ some-feature origin/develop</code>, and so on) will be configured to have the
+ start point branch as their upstream. By default (with <code>true</code> rather than
+ <code>always</code>) this only happens when the start point is a remote-tracking
+ branch.</p>
+</li>
+<li>
+<p><code>git config rerere.enabled true</code> - enable “reuse recorded resolution.” The
+ <code>git help rerere</code> docs explain it pretty well, but the short version is that
+ git can record how you resolve conflicts during a “test” merge and reuse the
+ same approach when resolving the same conflict later, in a “real” merge.</p>
+</li>
+</ul>
+<h2 id="for-advanced-users">For advanced users</h2>
+<p>A few things are nice when you're getting started, but become annoying when
+you no longer need them.</p>
+<ul>
+<li><code>git config advice.detachedHead</code> - if you already understand the difference
+ between having a branch checked out and having a commit checked out, and
+ already understand what “detatched head” means, the warning on every <code>git
+ checkout ...some detatched thing...</code> isn't helping anyone. This is also
+ useful repositories used for deployment, where specific commits (from tags,
+ for example) are regularly checked out.</li>
+</ul>
+ </div>
+
+
+
+<div id="comments">
+<div id="disqus_thread"></div>
+<script type="text/javascript">
+ /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+ var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname
+
+ /* * * DON'T EDIT BELOW THIS LINE * * */
+ (function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+ })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
+</div>
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git/config.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/git/config.md">history</a>).
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/.html/git/detached-sigs.html b/.html/git/detached-sigs.html
new file mode 100644
index 0000000..a3e439d
--- /dev/null
+++ b/.html/git/detached-sigs.html
@@ -0,0 +1,359 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ Notes Towards Detached Signatures in Git
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="./">git</a>
+
+ </li>
+
+ <li class="crumb-2 last">
+
+ detached-sigs
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="article">
+ <h1 id="notes-towards-detached-signatures-in-git">Notes Towards Detached Signatures in Git</h1>
+<p>Git supports a limited form of object authentication: specific object
+categories in Git's internal model can have <a href="../gpg/terrible">GPG</a> signatures
+embedded in them, allowing the authorship of the objects to be verified using
+<a href="../gpg/cool">GPG</a>'s underlying trust model. Tag signatures can be used to
+verify the authenticity and integrity of the <em>snapshot associated with a
+tag</em>, and the authenticity of the tag itself, filling a niche broadly similar
+to code signing in binary distribution systems. Commit signatures can be used
+to verify the authenticity of the <em>snapshot associated with the commit</em>, and
+the authorship of the commit itself. (Conventionally, commit signatures are
+assumed to also authenticate either the entire line of history leading to a
+commit, or the diff between the commit and its first parent, or both.)</p>
+<p>Git's existing system has some tradeoffs.</p>
+<ul>
+<li>
+<p>Signatures are embedded within the objects they sign. The signature is part
+ of the object's identity; since Git is content-addressed, this means that
+ an object can neither be retroactively signed nor retroactively stripped of
+ its signature without modifying the object's identity. Git's distributed
+ model means that these sorts of identity changes are both complicated and
+ easily detected.</p>
+</li>
+<li>
+<p>Commit signatures are second-class citizens. They're a relatively recent
+ addition to the Git suite, and both the implementation and the social
+ conventions around them continue to evolve.</p>
+</li>
+<li>
+<p>Only some objects can be signed. While Git has relatively weak rules about
+ workflow, the signature system assumes you're using one of Git's more
+ widespread workflows by limiting your options to at most one signature, and
+ by restricting signatures to tags and commits (leaving out blobs, trees,
+ and refs).</p>
+</li>
+</ul>
+<p>I believe it would be useful from an authentication standpoint to add
+"detached" signatures to Git, to allow users to make these tradeoffs
+differently if desired. These signatures would be stored as separate (blob)
+objects in a dedicated <code>refs</code> namespace, supporting retroactive signatures,
+multiple signatures for a given object, "policy" signatures, and
+authentication of arbitrary objects.</p>
+<p>The following notes are partially guided by Git's one existing "detached
+metadata" facility, <code>git notes</code>. Similarities are intentional; divergences
+will be noted where appropriate. Detached signatures are meant to
+interoperate with existing Git workflow as much as possible: in particular,
+they can be fetched and pushed like any other bit of Git metadata.</p>
+<p>A detached signature cryptographically binds three facts together into an
+assertion whose authenticity can be checked by anyone with access to the
+signatory's keys:</p>
+<ol>
+<li>An object (in the Git sense; a commit, tag, tree, or blob),</li>
+<li>A policy label, and</li>
+<li>A signatory (a person or agent making the assertion).</li>
+</ol>
+<p>These assertions can be published separately from or in tandem with the
+objects they apply to.</p>
+<h2 id="policies">Policies</h2>
+<p>Taking a hint from Monotone, every signature includes a "policy" identifying
+how the signature is meant to be interpreted. Policies are arbitrary strings;
+their meaning is entirely defined by tooling and convention, not by this
+draft.</p>
+<p>This draft uses a single policy, <code>author</code>, for its examples. A signature
+under the <code>author</code> policy implies that the signatory had a hand in the
+authorship of the designated object. (This is compatible with existing
+interpretations of signed tags and commits.) (Authorship under this model is
+strictly self-attested: you can claim authorship of anything, and you cannot
+assert anyone else's authorship.)</p>
+<p>The Monotone documentation suggests a number of other useful policies related
+to testing and release status, automated build results, and numerous other
+factors. Use your imagination.</p>
+<h2 id="whats-in-a-signature">What's In A Signature</h2>
+<p>Detached signatures cover the disk representation of an object, as given by</p>
+<pre><code>git cat-file &lt;TYPE&gt; &lt;SHA1&gt;
+</code></pre>
+<p>For most of Git's object types, this means that the signed content is plain
+text. For <code>tree</code> objects, the signed content is the awful binary
+representation of the tree, <em>not</em> the pretty representation given by <code>git
+ls-tree</code> or <code>git show</code>.</p>
+<p>Detached signatures include the "policy" identifier in the signed content, to
+prevent others from tampering with policy choices via <code>refs</code> hackery. (This
+will make more sense momentarily.) The policy identifier is prepended to the
+signed content, terminated by a zero byte (as with Git's own type
+identifiers, but without a length field as length checks are performed by
+signing and again when the signature is stored in Git).</p>
+<p>To generate the <em>complete</em> signable version of an object, use something
+equivalent to the following shell snippet:</p>
+<pre><code># generate-signable POLICY TYPE SHA1
+function generate-signable() {
+ echo -n "$1"
+ SOMETHING OUTPUTTING A NUL HERE
+ git cat-file "$2" "$3"
+}
+</code></pre>
+<p>(In the process of writing this, I discovered how hard it is to get Unix's
+C-derived shell tools to emit a zero byte.)</p>
+<h2 id="signature-storage-and-naming">Signature Storage and Naming</h2>
+<p>We assume that a userid will sign an object at most once.</p>
+<p>Each signature is stored in an independent blob object in the repository it
+applies to. The signature object (described above) is stored in Git, and its
+hash recorded in <code>refs/signatures/&lt;POLICY&gt;/&lt;SUBJECT SHA1&gt;/&lt;SIGNER KEY
+FINGERPRINT&gt;</code>.</p>
+<pre><code># sign POLICY TYPE SHA1 FINGERPRINT
+function sign() {
+ local SIG_HASH=$(
+ generate-signable "$@" |
+ gpg --batch --no-tty --sign -u "$4" |
+ git hash-object --stdin -w -t blob
+ )
+ git update-ref "refs/signatures/$1/$3/$4"
+}
+</code></pre>
+<p>Stored signatures always use the complete fingerprint to identify keys, to
+minimize the risk of colliding key IDs while avoiding the need to store full
+keys in the <code>refs</code> naming hierarchy.</p>
+<p>The policy name can be reliably extracted from the ref, as the trailing part
+has a fixed length (in both path segments and bytes) and each ref begins with
+a fixed, constant prefix <code>refs/signatures/</code>.</p>
+<h2 id="signature-verification">Signature Verification</h2>
+<p>Given a signature ref as described above, we can verify and authenticate the
+signature and bind it to the associated object and policy by performing the
+following check:</p>
+<ol>
+<li>Pick apart the ref into policy, SHA1, and key fingerprint parts.</li>
+<li>Reconstruct the signed body as above, using the policy name extracted from
+ the ref.</li>
+<li>Retrieve the signature from the ref and combine it with the object itself.</li>
+<li>Verify that the policy in the stored signature matches the policy in the
+ ref.</li>
+<li>
+<p>Verify the signature with GPG:</p>
+<pre><code># verify-gpg POLICY TYPE SHA1 FINGERPRINT
+verify-gpg() {
+ {
+ git cat-file "$2" "$3"
+ git cat-file "refs/signatures/$1/$3/$4"
+ } | gpg --batch --no-tty --verify
+}
+</code></pre>
+</li>
+<li>
+<p>Verify the key fingerprint of the signing key matches the key fingerprint
+ in the ref itself.</p>
+</li>
+</ol>
+<p>The specific rules for verifying the signature in GPG are left up to the user
+to define; for example, some sites may want to auto-retrieve keys and use a
+web of trust from some known roots to determine which keys are trusted, while
+others may wish to maintain a specific, known keyring containing all signing
+keys for each policy, and skip the web of trust entirely. This can be
+accomplished via <code>git-config</code>, given some work, and via <code>gpg.conf</code>.</p>
+<h2 id="distributing-signatures">Distributing Signatures</h2>
+<p>Since each signature is stored in a separate ref, and since signatures are
+<em>not</em> expected to be amended once published, the following refspec can be
+used with <code>git fetch</code> and <code>git push</code> to distribute signatures:</p>
+<pre><code>refs/signatures/*:refs/signatures/*
+</code></pre>
+<p>Note the lack of a <code>+</code> decoration; we explicitly do not want to auto-replace
+modified signatures, normally; explicit user action should be required.</p>
+<h2 id="workflow-notes">Workflow Notes</h2>
+<p>There are two verification workflows for signatures: "static" verification,
+where the repository itself already contains all the refs and objects needed
+for signature verification, and "pre-receive" verification, where an object
+and its associated signature may be being uploaded at the same time.</p>
+<p><em>It is impractical to verify signatures on the fly from an <code>update</code> hook</em>.
+Only <code>pre-receive</code> hooks can usefully accept or reject ref changes depending
+on whether the push contains a signature for the pushed objects. (Git does
+not provide a good mechanism for ensuring that signature objects are pushed
+before their subjects.) Correctly verifying object signatures during
+<code>pre-receive</code> regardless of ref order is far too complicated to summarize
+here.</p>
+<h2 id="attacks">Attacks</h2>
+<h3 id="lies-of-omission">Lies of Omission</h3>
+<p>It's trivial to hide signatures by deleting the signature refs. Similarly,
+anyone with access to a repository can delete any or all detached signatures
+from it without otherwise invalidating the signed objects.</p>
+<p>Since signatures are mostly static, sites following the recommended no-force
+policy for signature publication should only be affected if relatively recent
+signatures are deleted. Older signatures should be available in one or more
+of the repository users' loca repositories; once created, a signature can be
+legitimately obtained from anywhere, not only from the original signatory.</p>
+<p>The signature naming protocol is designed to resist most other forms of
+assertion tampering, but straight-up omission is hard to prevent.</p>
+<h3 id="unwarranted-certification">Unwarranted Certification</h3>
+<p>The <code>policy</code> system allows any signatory to assert any policy. While
+centralized signature distribution points such as "release" repositories can
+make meaningful decisions about which signatures they choose to accept,
+publish, and propagate, there's no way to determine after the fact whether a
+policy assertion was obtained from a legitimate source or a malicious one
+with no grounds for asserting the policy.</p>
+<p>For example, I could, right now, sign an <code>all-tests-pass</code> policy assertion
+for the Linux kernel. While there's no chance on Earth that the LKML team
+would propagate that assertion, if I can convince you to fetch signatures
+from my repository, you will fetch my bogus assertion. If <code>all-tests-pass</code> is
+a meaningful policy assertion for the Linux kernel, then you will have very
+few options besides believing that I assert that all tests have passed.</p>
+<h3 id="ambigiuous-policy">Ambigiuous Policy</h3>
+<p>This is an ongoing problem with crypto policy systems and user interfaces
+generally, but this design does <em>nothing</em> to ensure that policies are
+interpreted uniformly by all participants in a repository. In particular,
+there's no mechanism described for distributing either prose or programmatic
+policy definitions and checks. All policy information is out of band.</p>
+<p>Git already has ambiguity problems around commit signing: there are multiple
+ways to interpret a signature on a commit:</p>
+<ol>
+<li>
+<p>I assert that this snapshot and commit message were authored as described
+ in this commit's metadata. (In this interpretation, the signature's
+ authenticity guarantees do <em>not</em> transitively apply to parents.)</p>
+</li>
+<li>
+<p>I assert that this snapshot and commit message were authored as described
+ in this commit's metadata, based on exactly the parent commits described.
+ (In this interpretation, the signature's authenticity guarantees <em>do</em>
+ transitively apply to parents. This is the interpretation favoured by XXX
+ LINK HERE XXX.)</p>
+</li>
+<li>
+<p>I assert that this <em>diff</em> and commit message was authored as described in
+ this commit's metadata. (No assertions about the <em>snapshot</em> are made
+ whatsoever, and assertions about parentage are barely sensical at all.
+ This meshes with widespread, diff-oriented policies.)</p>
+</li>
+</ol>
+<h3 id="grafts-and-replacements">Grafts and Replacements</h3>
+<p>Git permits post-hoc replacement of arbitrary objects via both the grafts
+system (via an untracked, non-distributed file in <code>.git</code>, though some
+repositories distribute graft lists for end-users to manually apply) and the
+replacements system (via <code>refs/replace/&lt;SHA1&gt;</code>, which can optionally be
+fetched or pushed). The interaction between these two systems and signature
+verification needs to be <em>very</em> closely considered; I've not yet done so.</p>
+<p>Cases of note:</p>
+<ul>
+<li>Neither signature nor subject replaced - the "normal" case</li>
+<li>Signature not replaced, subject replaced (by graft, by replacement, by both)</li>
+<li>Signature replaced, subject not replaced</li>
+<li>Both signature and subject replaced</li>
+</ul>
+<p>It's tempting to outright disable <code>git replace</code> during signing and
+verification, but this will have surprising effects when signing a ref-ish
+instead of a bare hash. Since this is the <em>normal</em> case, I think this merits
+more thought. (I'm also not aware of a way to disable grafts without
+modifying <code>.git</code>, and having the two replacement mechanisms treated
+differently may be dangerous.)</p>
+<h3 id="no-signed-refs">No Signed Refs</h3>
+<p>I mentioned early in this draft that Git's existing signing system doesn't
+support signing refs themselves; since refs are an important piece of Git's
+workflow ecosystem, this may be a major omission. Unfortunately, this
+proposal doesn't address that.</p>
+<h2 id="possible-refinements">Possible Refinements</h2>
+<ul>
+<li>Monotone's certificate system is key+value based, rather than label-based.
+ This might be useful; while small pools of related values can be asserted
+ using mutually exclusive policy labels (whose mutual exclusion is a matter
+ of local interpretation), larger pools of related values rapidly become
+ impractical under the proposed system.</li>
+</ul>
+<p>For example, this proposal would be inappropriate for directly asserting
+ third-party authorship; the asserted author would have to appear in the
+ policy name itself, exposing the user to a potentially very large number of
+ similar policy labels.</p>
+<ul>
+<li>
+<p>Ref signing via a manifest (a tree constellation whose paths are ref names
+ and whose blobs sign the refs' values). Consider cribbing DNSSEC here for
+ things like lightweight absence assertions, too.</p>
+</li>
+<li>
+<p>Describe how this should interact with commit-duplicating and
+ commit-rewriting workflows.</p>
+</li>
+</ul>
+ </div>
+
+
+
+<div id="comments">
+<div id="disqus_thread"></div>
+<script type="text/javascript">
+ /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+ var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname
+
+ /* * * DON'T EDIT BELOW THIS LINE * * */
+ (function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+ })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
+</div>
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git/detached-sigs.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/git/detached-sigs.md">history</a>).
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/.html/git/index.html b/.html/git/index.html
new file mode 100644
index 0000000..59ee1d4
--- /dev/null
+++ b/.html/git/index.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ ls /git
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="./">git</a>
+
+ </li>
+
+ <li class="crumb-2 last">
+
+ <span class="list-crumb">list</span>
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="listing">
+ <h1><code>ls /git</code></h1>
+
+
+ <div id="directories">
+ <h2>Directories</h2>
+ <ul>
+
+ <li><a href="theory-and-practice/">theory-and-practice/</a></li>
+
+ </ul>
+ </div>
+
+
+
+ <div id="pages">
+ <h2>Pages</h2>
+ <ul>
+
+ <li><a href="scratch">Git Is Not Magic</a></li>
+
+ <li><a href="survival">Git Survival Guide</a></li>
+
+ <li><a href="integrate">Integrating with Git: A Field Guide</a></li>
+
+ <li><a href="pull-request-workflow">Life With Pull Requests</a></li>
+
+ <li><a href="detached-sigs">Notes Towards Detached Signatures in Git</a></li>
+
+ <li><a href="stop-using-git-pull-to-deploy">Stop Using Git Pull To Deploy</a></li>
+
+ <li><a href="config">git-config Settings You Want</a></li>
+
+ </ul>
+ </div>
+
+
+
+ </div>
+
+
+
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git">See this directory on Bitbucket</a>.
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/.html/git/integrate.html b/.html/git/integrate.html
new file mode 100644
index 0000000..828019f
--- /dev/null
+++ b/.html/git/integrate.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ Integrating with Git: A Field Guide
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="./">git</a>
+
+ </li>
+
+ <li class="crumb-2 last">
+
+ integrate
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="article">
+ <h1 id="integrating-with-git-a-field-guide">Integrating with Git: A Field Guide</h1>
+<p>Pretty much everything you might want to do to a Git repository when writing
+tooling or integrations should be done by shelling out to one <code>git</code> command or
+another.</p>
+<h2 id="finding-gits-trees">Finding Git's trees</h2>
+<p>Git commands can be invoked from locations other than the root of the work
+tree or git directory. You can find either of those by invoking <code>git
+rev-parse</code>.</p>
+<p>To find the absolute path to the root of the work tree:</p>
+<pre><code>git rev-parse --show-toplevel
+</code></pre>
+<p>This will output the absolute path to the root of the work tree on standard
+output, followed by a newline. Since the work tree's absolute path can contain
+whitespace (including newlines), you should assume every byte of output save
+the final newline is part of the path, and if you're using this in a shell
+script, quote defensively.</p>
+<p>To find the relative path from the current working directory:</p>
+<pre><code>git rev-parse --show-cdup
+</code></pre>
+<p>This will output the relative path to the root of the work tree on standard
+output, followed by a newline.</p>
+<p>For bare repositories, both commands will output nothing and exit with a zero
+status. (Surprise!)</p>
+<p>To find <em>a</em> path to the root of the git directory:</p>
+<pre><code>git rev-parse --git-dir
+</code></pre>
+<p>This will output either the relative or the absolute path to the git
+directory, followed by a newline.</p>
+<p>All three of these commands will exit with non-zero status when run outside of
+a work tree or git directory. Check for it.</p>
+ </div>
+
+
+
+<div id="comments">
+<div id="disqus_thread"></div>
+<script type="text/javascript">
+ /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+ var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname
+
+ /* * * DON'T EDIT BELOW THIS LINE * * */
+ (function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+ })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
+</div>
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git/integrate.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/git/integrate.md">history</a>).
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/.html/git/pull-request-workflow.html b/.html/git/pull-request-workflow.html
new file mode 100644
index 0000000..1a15642
--- /dev/null
+++ b/.html/git/pull-request-workflow.html
@@ -0,0 +1,163 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ Life With Pull Requests
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="./">git</a>
+
+ </li>
+
+ <li class="crumb-2 last">
+
+ pull-request-workflow
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="article">
+ <h1 id="life-with-pull-requests">Life With Pull Requests</h1>
+<p>I've been party to a number of discussions with folks contributing to
+pull-request-based projects on Github (and other hosts, but mostly Github).
+Because of Git's innate flexibility, there are lots of ways to work with pull
+requests. Here's mine.</p>
+<p>I use a couple of naming conventions here that are not stock <code>git</code>:</p>
+<dl>
+<dt>origin</dt>
+<dd>The repository to which you <em>publish</em> proposed changes</dd>
+<dt>upstream</dt>
+<dd>The repository from which you receive ongoing development, and which will
+receive your changes.</dd>
+</dl>
+<h2 id="one-time-setup">One-time setup</h2>
+<p>Do these things once, when starting out on a project. Keep the results around
+for later.</p>
+<p>I'll be referring to the original project repository as <code>upstream</code> and
+pretending its push URL is <code>UPSTREAM-URL</code> below. In real life, the URL will
+often be something like <code>git@github.com:someguy/project.git</code>.</p>
+<h3 id="fork-the-project">Fork the project</h3>
+<p>Use the repo manager's forking tool to create a copy of the project in your
+own namespace. This generally creates your copy with a bunch of useless tat;
+feel free to ignore all of this, as the only purpose of this copy is to
+provide somewhere for <em>you</em> to publish <em>your</em> changes.</p>
+<p>We'll be calling this repository <code>origin</code> later. Assume it has a URL, which
+I'll abbreviate <code>ORIGIN-URL</code>, for <code>git push</code> to use.</p>
+<p>(You can leave this step for later, but if you know you're going to do it, why
+not get it out of the way?)</p>
+<h3 id="clone-the-project-and-configure-it">Clone the project and configure it</h3>
+<p>You'll need a clone locally to do work in. Create one from <code>origin</code>:</p>
+<pre><code>git clone ORIGIN-URL some-local-name
+</code></pre>
+<p>While you're here, <code>cd</code> into it and add the original project as a remote:</p>
+<pre><code>cd some-local-name
+git remote add upstream UPSTREAM-URL
+</code></pre>
+<h2 id="feature-process">Feature process</h2>
+<p>Do these things for each feature you work on. To switch features, just use
+<code>git checkout my-feature</code>.</p>
+<h3 id="create-a-new-feature-branch-locally">Create a new feature branch locally</h3>
+<p>We use <code>upstream</code>'s <code>master</code> branch here, so that your feature includes all of
+<code>upstream</code>'s state initially. We also need to make sure our local cache of
+<code>upstream</code>'s state is correct:</p>
+<pre><code>git fetch upstream
+git checkout upstream/master -b my-feature
+</code></pre>
+<h3 id="do-work">Do work</h3>
+<p>If you need my help here, stop now.</p>
+<h3 id="integrate-upstream-changes">Integrate upstream changes</h3>
+<p>If you find yourself needing something that's been added upstream, use
+<em>rebase</em> to integrate it to avoid littering your feature branch with
+“meaningless” merge commits.</p>
+<pre><code>git checkout my-feature
+git fetch upstream
+git rebase upstream/master
+</code></pre>
+<h3 id="publish-your-branch">Publish your branch</h3>
+<p>When you're “done,” publish your branch to your personal repository:</p>
+<pre><code>git push origin my-feature
+</code></pre>
+<p>Then visit your copy in your repo manager's web UI and create a pull request
+for <code>my-feature</code>.</p>
+<h3 id="integrating-feedback">Integrating feedback</h3>
+<p>Very likely, your proposed changes will need work. If you use history-editing
+to integrate feedback, you will need to use <code>--force</code> when updating the
+branch:</p>
+<pre><code>git push --force origin my-feature
+</code></pre>
+<p>This is safe provided two things are true:</p>
+<ol>
+<li><strong>The branch has not yet been merged to the upstream repo.</strong></li>
+<li>You are only force-pushing to your fork, not to the upstream repo.</li>
+</ol>
+<p>Generally, no other users will have work based on your pull request, so
+force-pushing history won't cause problems.</p>
+ </div>
+
+
+
+<div id="comments">
+<div id="disqus_thread"></div>
+<script type="text/javascript">
+ /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+ var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname
+
+ /* * * DON'T EDIT BELOW THIS LINE * * */
+ (function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+ })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
+</div>
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git/pull-request-workflow.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/git/pull-request-workflow.md">history</a>).
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/.html/git/scratch.html b/.html/git/scratch.html
new file mode 100644
index 0000000..ff1bdff
--- /dev/null
+++ b/.html/git/scratch.html
@@ -0,0 +1,134 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ Git Is Not Magic
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="./">git</a>
+
+ </li>
+
+ <li class="crumb-2 last">
+
+ scratch
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="article">
+ <h1 id="git-is-not-magic">Git Is Not Magic</h1>
+<p>I'm bored. Let's make a git repository out of whole cloth.</p>
+<p>Git repos are stored in .git:</p>
+<pre><code>fakegit$ mkdir .git
+</code></pre>
+<p>They have a “symbolic ref” (which are text files, see <a href="http://jk.gs/git-symbolic-ref.html"><code>man
+git-symbolic-ref</code></a>) named <code>HEAD</code>, pointing
+to the currently checked-out branch. Let's use <code>master</code>. Branches are refs
+under <code>refs/heads</code> (see <a href="http://jk.gs/git-branch.html"><code>man git-branch</code></a>):</p>
+<pre><code>fakegit ((unknown))$ echo 'ref: refs/heads/master' &gt; .git/HEAD
+</code></pre>
+<p>The have an object database and a refs database, both of which are simple
+directories (see <a href="http://jk.gs/gitrepository-layout.html"><code>man
+gitrepository-layout</code></a> and <a href="http://jk.gs/gitrevisions.html"><code>man
+gitrevisions</code></a>). Let's also enable the reflog,
+because it's a great safety net if you use history-editing tools in git:</p>
+<pre><code>fakegit ((ref: re...))$ mkdir .git/refs .git/objects .git/logs
+fakegit (master #)$
+</code></pre>
+<p>Now <code>__git_ps1</code>, at least, is convinced that we have a working git repository.
+Does it work?</p>
+<pre><code>fakegit (master #)$ echo 'Hello, world!' &gt; hello.txt
+fakegit (master #)$ git add hello.txt
+fakegit (master #)$ git commit -m 'Initial commit'
+[master (root-commit) 975307b] Initial commit
+1 file changed, 1 insertion(+)
+create mode 100644 hello.txt
+
+fakegit (master)$ git log
+commit 975307ba0485bff92e295e3379a952aff013c688
+Author: Owen Jacobson &lt;owen.jacobson@grimoire.ca&gt;
+Date: Wed Feb 6 10:07:07 2013 -0500
+
+ Initial commit
+</code></pre>
+<p><a href="https://www.youtube.com/watch?v=3VwVpaWUu30">Eeyup</a>.</p>
+<hr>
+<p>Should you do this? <strong>Of course not.</strong> Anywhere you could run these commands,
+you could instead run <code>git init</code> or <code>git clone</code>, which set up a number of
+other structures, including <code>.git/config</code> and any unusual permissions options.
+The key part here is that a directory's identity as “a git repository” is
+entirely a function of its contents, not of having been blessed into being by
+<code>git</code> itself.</p>
+<p>You can infer a lot from this: for example, you can infer that it's “safe” to
+move git repositories around using FS tools, or to back them up with the same
+tools, for example. This is not as obvious to everyone as you might hope; people </p>
+ </div>
+
+
+
+<div id="comments">
+<div id="disqus_thread"></div>
+<script type="text/javascript">
+ /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+ var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname
+
+ /* * * DON'T EDIT BELOW THIS LINE * * */
+ (function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+ })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
+</div>
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git/scratch.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/git/scratch.md">history</a>).
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/.html/git/stop-using-git-pull-to-deploy.html b/.html/git/stop-using-git-pull-to-deploy.html
new file mode 100644
index 0000000..a3736a0
--- /dev/null
+++ b/.html/git/stop-using-git-pull-to-deploy.html
@@ -0,0 +1,178 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ Stop Using Git Pull To Deploy
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="./">git</a>
+
+ </li>
+
+ <li class="crumb-2 last">
+
+ stop-using-git-pull-to-deploy
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="article">
+ <h1 id="stop-using-git-pull-for-deployment">Stop using <code>git pull</code> for deployment!</h1>
+<h2 id="the-problem">The problem</h2>
+<ul>
+<li>You have a Git repository containing your project.</li>
+<li>You want to “deploy” that code when it changes.</li>
+<li>You'd rather not download the entire project from scratch for each
+ deployment.</li>
+</ul>
+<h2 id="the-antipattern">The antipattern</h2>
+<p>“I know, I'll use <code>git pull</code> in my deployment script!”</p>
+<p>Stop doing this. Stop teaching other people to do this. It's wrong, and it
+will eventually lead to deploying something you didn't want.</p>
+<p>Deployment should be based on predictable, known versions of your code.
+Ideally, every deployable version has a tag (and you deploy exactly that tag),
+but even less formal processes, where you deploy a branch tip, should still be
+deploying exactly the code designated for release. <code>git pull</code>, however, can
+introduce new commits.</p>
+<p><code>git pull</code> is a two-step process:</p>
+<ol>
+<li>Fetch the current branch's designated upstream remote, to obtain all of the
+ remote's new commits.</li>
+<li>Merge the current branch's designated upstream branch into the current
+ branch.</li>
+</ol>
+<p>The merge commit means the actual deployed tree might <em>not</em> be identical to
+the intended deployment tree. Local changes (intentional or otherwise) will be
+preserved (and merged) into the deployment, for example; once this happens,
+the actual deployed commit will <em>never</em> match the intended commit.</p>
+<p><code>git pull</code> will approximate the right thing “by accident”: if the current
+local branch (generally <code>master</code>) for people using <code>git pull</code> is always clean,
+and always tracks the desired deployment branch, then <code>git pull</code> will update
+to the intended commit exactly. This is pretty fragile, though; many git
+commands can cause the local branch to diverge from its upstream branch, and
+once that happens, <code>git pull</code> will always create new commits. You can patch
+around the fragility a bit using the <code>--ff-only</code> option, but that only tells
+you when your deployment environment has diverged and doesn't fix it.</p>
+<h2 id="the-right-pattern">The right pattern</h2>
+<p>Quoting <a href="http://gitolite.com/the-list-and-irc/deploy.html">Sitaram Chamarty</a>:</p>
+<blockquote>
+<p>Here's what we expect from a deployment tool. Note the rule numbers --
+we'll be referring to some of them simply by number later.</p>
+<ol>
+<li>
+<p>All files in the branch being deployed should be copied to the
+ deployment directory.</p>
+</li>
+<li>
+<p>Files that were deleted in the git repo since the last deployment
+ should get deleted from the deployment directory.</p>
+</li>
+<li>
+<p>Any changes to tracked files in the deployment directory after the
+ last deployment should be ignored when following rules 1 and 2.</p>
+<p>However, sometimes you might want to detect such changes and abort if
+you found any.</p>
+</li>
+<li>
+<p>Untracked files in the deploy directory should be left alone.</p>
+<p>Again, some people might want to detect this and abort the deployment.</p>
+</li>
+</ol>
+</blockquote>
+<p>Sitaram's own documentation talks about how to accomplish these when
+“deploying” straight out of a bare repository. That's unwise (not to mention
+impractical) in most cases; deployment should use a dedicated clone of the
+canonical repository.</p>
+<p>I also disagree with point 3, preferring to keep deployment-related changes
+outside of tracked files. This makes it much easier to argue that the changes
+introduced to configure the project for deployment do not introduce new bugs
+or other surprise features.</p>
+<p>My deployment process, given a dedicated clone at <code>$DEPLOY_TREE</code>, is as
+follows:</p>
+<pre><code>cd "${DEPLOY_TREE}"
+git fetch --all
+git checkout --force "${TARGET}"
+# Following two lines only required if you use submodules
+git submodule sync
+git submodule update --init --recursive
+# Follow with actual deployment steps (run fabric/capistrano/make/etc)
+</code></pre>
+<p><code>$TARGET</code> is either a tag name (<code>v1.2.1</code>) or a remote branch name
+(<code>origin/master</code>), but could also be a commit hash or anything else Git
+recognizes as a revision. This will detach the head of the <code>$DEPLOY_TREE</code>
+repository, which is fine as no new changes should be authored in this
+repository (so the local branches are irrelevant). The warning Git emits when
+<code>HEAD</code> becomes detached is unimportant in this case.</p>
+<p>The tracked contents of <code>$DEPLOY_TREE</code> will end up identical to the desired
+commit, discarding local changes. The pattern above is very similar to what
+most continuous integration servers use when building from Git repositories,
+for much the same reason.</p>
+ </div>
+
+
+
+<div id="comments">
+<div id="disqus_thread"></div>
+<script type="text/javascript">
+ /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+ var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname
+
+ /* * * DON'T EDIT BELOW THIS LINE * * */
+ (function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+ })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
+</div>
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git/stop-using-git-pull-to-deploy.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/git/stop-using-git-pull-to-deploy.md">history</a>).
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/.html/git/survival.html b/.html/git/survival.html
new file mode 100644
index 0000000..c1d43ac
--- /dev/null
+++ b/.html/git/survival.html
@@ -0,0 +1,174 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ Git Survival Guide
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="./">git</a>
+
+ </li>
+
+ <li class="crumb-2 last">
+
+ survival
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="article">
+ <h1 id="git-survival-guide">Git Survival Guide</h1>
+<p>I think the <code>git</code> UI is pretty awful, and encourages using Git in ways that
+will screw you. Here are a few things I've picked up that have saved my bacon.</p>
+<ul>
+<li>You will inevitably need to understand Git's “internals” to make use of it
+ as an SCM tool. Accept this early. If you think your SCM tool should not
+ expose you to so much plumbing, <a href="http://mercurial.selenic.com">don't</a>
+ <a href="http://bazaar.canonical.com">use</a> <a href="http://subversion.apache.org">Git</a>.<ul>
+<li>Git weenies will claim that this plumbing is what gives Git all of its
+ extra power. This is true; it gives Git the power to get you out of
+ situations you wouldn't be in without Git.</li>
+</ul>
+</li>
+<li><code>git log --graph --decorate --oneline --color --all</code></li>
+<li>Run <code>git fetch</code> habitually. Stale remote-tracking branches lead to sadness.</li>
+<li><code>git push</code> and <code>git pull</code> are <strong>not symmetric</strong>. <code>git push</code>'s
+ opposite operation is <code>git fetch</code>. (<code>git pull</code> is equivalent to <code>git fetch</code>
+ followed by <code>git merge</code>, more or less).</li>
+<li><a href="config">Git configuration values don't always have the best defaults</a>.</li>
+<li>The upstream branch of <code>foo</code> is <code>foo@{u}</code>. The upstream branch of your
+ checked-out branch is <code>HEAD@{u}</code> or <code>@{u}</code>. This is documented in <code>git help
+ revisions</code>.</li>
+<li>You probably don't want to use a merge operation (such as <code>git pull</code>) to
+ integrate upstream changes into topic branches. The resulting history can be
+ very confusing to follow, especially if you integrate upstream changes
+ frequently.<ul>
+<li>You can leave topic branches “real” relatively safely. You can do
+ a test merge to see if they still work cleanly post-integration without
+ actually integrating upstream into the branch permanently.</li>
+<li>You can use <code>git rebase</code> or <code>git pull --rebase</code> to transplant your
+ branch to a new, more recent starting point that includes the changes
+ you want to integrate. This makes the upstream changes a permanent part
+ of your branch, just like <code>git merge</code> or <code>git pull</code> would, but generates
+ an easier-to-follow history. Conflict resolution will happen as normal.</li>
+</ul>
+</li>
+<li>
+<p>Example test merge, using <code>origin/master</code> as the upstream branch and <code>foo</code>
+ as the candidate for integration:</p>
+<pre><code>git fetch origin
+git checkout origin/master -b test-merge-foo
+git merge foo
+# run tests, examine files
+git diff origin/master..HEAD
+</code></pre>
+<p>To discard the test merge, delete the branch after checking out some other
+branch:</p>
+<pre><code>git checkout foo
+git branch -D test-merge-foo
+</code></pre>
+<p>You can combine this with <code>git rerere</code> to save time resolving conflicts in
+a later “real,” permanent merge.</p>
+</li>
+<li>
+<p>You can use <code>git checkout -p</code> to build new, tidy commits out of a branch
+ laden with “wip” commits:</p>
+<pre><code>git fetch
+git checkout $(git merge-base origin/master foo) -b foo-cleaner-history
+git checkout -p foo -- paths/to/files
+# pick out changes from the presented patch that form a coherent commit
+# repeat 'git checkout -p foo --' steps for related files to build up
+# the new commit
+git commit
+# repeat 'git checkout -p foo --' and 'git commit' steps until no diffs remain
+</code></pre>
+<ul>
+<li>Gotcha: <code>git checkout -p</code> will do nothing for files that are being
+ created. Use <code>git checkout</code>, instead, and edit the file if necessary.
+ Thanks, Git.</li>
+<li>Gotcha: The new, clean branch must diverge from its upstream branch
+ (<code>origin/master</code>, in the example above) at exactly the same point, or
+ the diffs presented by <code>git checkout -p foo</code> will include chunks that
+ revert changes on the upstream branch since the “dirty” branch was
+ created. The easiest way to find this point is with <code>git merge-base</code>.</li>
+</ul>
+</li>
+</ul>
+<h2 id="useful-resources">Useful Resources</h2>
+<p>That is, resoures that can help you solve problems or understand things, not
+resources that reiterate the man pages for you.</p>
+<ul>
+<li>Sitaram Chamarty's <a href="http://sitaramc.github.com/gcs/">git concepts
+ simplified</a></li>
+<li>Tv's <a href="http://eagain.net/articles/git-for-computer-scientists">Git for Computer
+ Scientists</a></li>
+</ul>
+ </div>
+
+
+
+<div id="comments">
+<div id="disqus_thread"></div>
+<script type="text/javascript">
+ /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+ var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname
+
+ /* * * DON'T EDIT BELOW THIS LINE * * */
+ (function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+ })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
+</div>
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git/survival.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/git/survival.md">history</a>).
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/.html/git/theory-and-practice/_list.html b/.html/git/theory-and-practice/_list.html
new file mode 100644
index 0000000..feae190
--- /dev/null
+++ b/.html/git/theory-and-practice/_list.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ ls /git/theory-and-practice
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="../">git</a>
+
+ </li>
+
+ <li class="crumb-2 not-last">
+
+ <a href="./">theory-and-practice</a>
+
+ </li>
+
+ <li class="crumb-3 last">
+
+ <span class="list-crumb">list</span>
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="listing">
+ <h1><code>ls /git/theory-and-practice</code></h1>
+
+
+
+
+ <div id="pages">
+ <h2>Pages</h2>
+ <ul>
+
+ <li><a href="objects">Objects</a></li>
+
+ <li><a href="refs-and-names">Refs and Names</a></li>
+
+ </ul>
+ </div>
+
+
+
+ </div>
+
+
+
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git/theory-and-practice">See this directory on Bitbucket</a>.
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/.html/git/theory-and-practice/index.html b/.html/git/theory-and-practice/index.html
new file mode 100644
index 0000000..297cbd9
--- /dev/null
+++ b/.html/git/theory-and-practice/index.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ Git Internals 101
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="../">git</a>
+
+ </li>
+
+ <li class="crumb-2 last">
+
+ theory-and-practice
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="article">
+ <h1 id="git-internals-101">Git Internals 101</h1>
+<p>Yeah, yeah, another article about “how Git works.” There are tons of these
+already. Personally, I'm fond of Sitaram Chamarty's <a href="http://gitolite.com/master-toc.html">fantastic series of
+articles</a> explaining Git from both ends,
+and of <a href="http://eagain.net/articles/git-for-computer-scientists/">Git for Computer
+Scientists</a>. Maybe
+you'd rather read those.</p>
+<p>This page was inspired by very specific, recurring issues I've run into while
+helping people use Git. I think Git's “porcelain” layer -- its user interface
+-- is terrible, and does a bad job of insulating non-expert users from Git's
+internals. While I'd love to fix that (and I do contribute to discussions on
+that front, too), we still have the <code>git(1)</code> UI right now and people still get
+into trouble with it right now.</p>
+<p>Git follows the New Jersey approach laid out in Richard Gabriel's <a href="http://www.dreamsongs.com/RiseOfWorseIsBetter.html">The Rise of
+“Worse is Better”</a>: given
+the choice between a simple implementation and a simple interface, Git chooses
+the simple implementation almost everywhere. This internal simplicity can give
+users the leverage to fix the problems that its horrible user interface leads
+them into, so these pages will focus on explaining the simple parts and giving
+users the tools to examine them.</p>
+<p>Throughout these articles, I've written “Git does X” a lot. Git is
+<em>incredibly</em> configurable; read that as “Git does X <em>by default</em>.” I'll try to
+call out relevant configuration options as I go, where it doesn't interrupt
+the flow of knowledge.</p>
+<ul>
+<li><a href="objects">Objects</a></li>
+<li><a href="refs-and-names">Refs and Names</a></li>
+</ul>
+<p>By the way, if you think you're just going to follow the
+<a href="http://git-scm.com/documentation">many</a>
+<a href="http://www.atlassian.com/git/tutorial">excellent</a>
+<a href="http://try.github.io/levels/1/challenges/1">git</a>
+<a href="https://www.kernel.org/pub/software/scm/git/docs/gittutorial.html">tutorials</a>
+out there and that you won't need this knowledge, well, you will. You can
+either learn it during a quiet time, when you can think and experiment, or you
+can learn it when something's gone wrong, and everyone's shouting at each
+other. Git's high-level interface doesn't do much to keep you on the sensible
+path, and you will eventually need to fix something.</p>
+ </div>
+
+
+
+<div id="comments">
+<div id="disqus_thread"></div>
+<script type="text/javascript">
+ /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+ var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname
+
+ /* * * DON'T EDIT BELOW THIS LINE * * */
+ (function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+ })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
+</div>
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git/theory-and-practice/index.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/git/theory-and-practice/index.md">history</a>).
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/.html/git/theory-and-practice/objects.html b/.html/git/theory-and-practice/objects.html
new file mode 100644
index 0000000..ff6c53b
--- /dev/null
+++ b/.html/git/theory-and-practice/objects.html
@@ -0,0 +1,202 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ Objects
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="../">git</a>
+
+ </li>
+
+ <li class="crumb-2 not-last">
+
+ <a href="./">theory-and-practice</a>
+
+ </li>
+
+ <li class="crumb-3 last">
+
+ objects
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="article">
+ <h1 id="objects">Objects</h1>
+<p>Git's basest level is a storage and naming system for things Git calls
+“objects.” These objects hold the bulk of the data about files and projects
+tracked by Git: file contents, directory trees, commits, and so on. Every
+object is identified by a SHA-1 hash, which is derived from its contents.</p>
+<p>SHA-1 hashes are obnoxiously long, so Git allows you to substitue any unique
+prefix of a SHA-1 hash, so long as it's at least four characters long. If the
+hash <code>0b43b9e3e64793f5a222a644ed5ab074d8fa1024</code> is present in your repository,
+then Git commands will understand <code>0b43</code>, <code>0b43b9</code>, and other patterns to all
+refer to the same object, so long as no other object has the same SHA-1
+prefix.</p>
+<h2 id="blobs">Blobs</h2>
+<p>The contents of every file that's ever been stored in a Git repository are
+stored as <code>blob</code> objects. These objects are very simple: they contain the file
+contents, byte for byte.</p>
+<h2 id="trees">Trees</h2>
+<p>File contents (and trees, and Other Things we'll get to later) are tied
+together into a directory structure by <code>tree</code> objects. These objects contain a
+list of records, with one child per record. Each record contains a permissions
+field corresponding to the POSIX permissions mask of the object, a type, a
+SHA-1 for another object, and a name.</p>
+<p>A directory containing only files might be represented as the tree</p>
+<pre><code>100644 blob 511542ad6c97b28d720c697f7535897195de3318 config.md
+100644 blob 801ddd5ae10d6282bbf36ccefdd0b052972aa8e2 integrate.md
+100644 blob 61d28155862607c3d5d049e18c5a6903dba1f85e scratch.md
+100644 blob d7a79c144c22775239600b332bfa120775bab341 survival.md
+</code></pre>
+<p>while a directory with subdirectories would also have some <code>tree</code> children:</p>
+<pre><code>040000 tree f57ef2457a551b193779e21a50fb380880574f43 12factor
+040000 tree 844697ce99e1ef962657ce7132460ad7a38b7584 authnz
+100644 blob 54795f9b774547d554f5068985bbc6df7b128832 cool-urls-can-change.md
+040000 tree fc3f39eb5d1a655374385870b8be56b202be7dd8 dev
+040000 tree 22cbfb2c1d7b07432ea7706c36b0d6295563c69c devops
+040000 tree 0b3e63b4f32c0c3acfbcf6ba28d54af4c2f0d594 git
+040000 tree 5914fdcbd34e00e23e52ba8e8bdeba0902941d3f java
+040000 tree 346f71a637a4f8933dc754fef02515a8809369c4 mysql
+100644 blob b70520badbb8de6a74b84788a7fefe64a432c56d packaging-ideas.md
+040000 tree 73ed6572345a368d20271ec5a3ffc2464ac8d270 people
+</code></pre>
+<h2 id="commits">Commits</h2>
+<p>Blobs and trees are sufficient to store arbitrary directory trees in Git, and
+you could use them that way, but Git is mostly used as a revision-tracking
+system. Revisions and their history are represented by <code>commit</code> objects, which contain:</p>
+<pre><code>* The SHA-1 hash of the root `tree` object of the commit,
+* Zero or more SHA-1 hashes for parent commits,
+* The name and email address of the commit's “author,”
+* The name and email address of the commit's “committer,”
+* Timestamps representing when the commit was authored and committed, and
+* A commit message.
+</code></pre>
+<p>Commit objects' parent references form a directed acyclic graph; the subgraph
+reachable from a specific commit is that commit's <em>history</em>.</p>
+<p>When working with Git's user interface, commit parents are given in a
+predictable order determined by the <code>git checkout</code> and <code>git merge</code> commands.</p>
+<h2 id="tags">Tags</h2>
+<p>Git's revision-tracking system supports “tags,” which are stable names for
+specific configurations. It also, uniquely, supports a concept called an
+“annotated tag,” represented by the <code>tag</code> object type. These annotated tag
+objects contain</p>
+<pre><code>* The type and SHA-1 hash of another object,
+* The name and email address of the person who created the tag,
+* A timestamp representing the moment the tag was created, and
+* A tag message.
+</code></pre>
+<h2 id="anonymity">Anonymity</h2>
+<p>There's a general theme to Git's object types: no object knows its own name.
+Every object only has a name in the context of some containing object, or in
+the context of <a href="refs-and-names">Git's refs mechanism</a>, which I'll get to
+shortly. This means that the same <code>blob</code> object can be reused for multiple
+files (or, more probably, the same file in multiple commits), if they happen
+to have the same contents.</p>
+<p>This also applies to tag objects, even though their role is part of a system
+for providing stable, meaningful names for commits.</p>
+<h2 id="examining-objects">Examining objects</h2>
+<ul>
+<li>
+<p><code>git cat-file &lt;type&gt; &lt;sha1&gt;</code>: decodes the object <code>&lt;sha1&gt;</code> and prints its
+ contents to stdout. This prints the object's contents in their raw form,
+ which is less than useful for <code>tree</code> objects.</p>
+</li>
+<li>
+<p><code>git cat-file -p &lt;sha1&gt;</code>: decodes the object <code>&lt;sha1&gt;</code> and pretty-prints it.
+ This pretty-printing stays close to the underlying disk format; it's most
+ useful for decoding <code>tree</code> objects.</p>
+</li>
+<li>
+<p><code>git show &lt;sha1&gt;</code>: decodes the object <code>&lt;sha1&gt;</code> and formats its contents to
+ stdout. For blobs, this is identical to what <code>git cat-file blob</code> would do,
+ but for trees, commits, and tags, the output is reformated to be more
+ readable.</p>
+</li>
+</ul>
+<h2 id="storage">Storage</h2>
+<p>Objects are stored in two places in Git: as “loose objects,” and in “pack
+files.” Newly-created objects are initially loose objects, for ease of
+manipulation; transferring objects to another repository or running certain
+administrative commands can cause them to be placed in pack files for faster
+transfer and for smaller storage.</p>
+<p>Loose objects are stored directly on the filesystem, in the Git repository's
+<code>objects</code> directory. Git takes a two-character prefix off of each object's
+SHA-1 hash, and uses that to pick a subdirectory of <code>objects</code> to store the
+object in. The remainder of the hash forms the filename. Loose objects are
+compressed with zlib, to conserve space, but the resulting directory tree can
+still be quite large.</p>
+<p>Packed objects are stored together in packed files, which live in the
+repository's <code>objects/pack</code> directory. These packed files are both compressed
+and delta-encoded, allowing groups of similar objects to be stored very
+compactly.</p>
+ </div>
+
+
+
+<div id="comments">
+<div id="disqus_thread"></div>
+<script type="text/javascript">
+ /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+ var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname
+
+ /* * * DON'T EDIT BELOW THIS LINE * * */
+ (function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+ })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
+</div>
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git/theory-and-practice/objects.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/git/theory-and-practice/objects.md">history</a>).
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/.html/git/theory-and-practice/refs-and-names.html b/.html/git/theory-and-practice/refs-and-names.html
new file mode 100644
index 0000000..fdc56a4
--- /dev/null
+++ b/.html/git/theory-and-practice/refs-and-names.html
@@ -0,0 +1,199 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ The Codex »
+ Refs and Names
+ </title>
+
+ <link
+ rel='stylesheet'
+ type='text/css'
+ href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../../media/css/reset.css">
+ <link
+ rel="stylesheet"
+ type="text/css"
+ href="../../media/css/grimoire.css">
+</head>
+<body>
+
+<div id="shell">
+
+ <ol id="breadcrumbs">
+
+ <li class="crumb-0 not-last">
+
+ <a href="../../">index</a>
+
+ </li>
+
+ <li class="crumb-1 not-last">
+
+ <a href="../">git</a>
+
+ </li>
+
+ <li class="crumb-2 not-last">
+
+ <a href="./">theory-and-practice</a>
+
+ </li>
+
+ <li class="crumb-3 last">
+
+ refs-and-names
+
+ </li>
+
+ </ol>
+
+
+
+ <div id="article">
+ <h1 id="refs-and-names">Refs and Names</h1>
+<p>Git's <a href="objects">object system</a> stores most of the data for projects tracked in
+Git, but only provides SHA-1 hashes. This is basically useless if you want to
+make practical use of Git, so Git also has a naming mechanism called “refs”
+that provide human-meaningful names for objects.</p>
+<p>There are two kinds of refs:</p>
+<ul>
+<li>
+<p>“Normal” refs, which are names that resolve directly to SHA-1 hashes. These
+ are the vast majority of refs in most repositories.</p>
+</li>
+<li>
+<p>“Symbolic” refs, which are names that resolve to other refs. In most
+ repositories, only a few of these appear. (Circular references are possible
+ with symbolic refs. Git will refuse to resolve these.)</p>
+</li>
+</ul>
+<p>Anywhere you could use a SHA-1, you can use a ref instead. Git interprets them
+identically, after resolving the ref down to the SHA-1.</p>
+<h2 id="namespaces">Namespaces</h2>
+<p>Every operation in Git that uses a name of some sort, including branching
+(branch names), tagging (tag names), fetching (remote-tracking branch names),
+and pushing (many kinds of name), expands those names to refs, using a
+namespace convention. The following namespaces are common:</p>
+<ul>
+<li>
+<p><code>refs/heads/NAME</code>: branches. The branch name is the ref name with
+ <code>refs/heads/</code> removed. Names generally point to commits.</p>
+</li>
+<li>
+<p><code>refs/remotes/REMOTE/NAME</code>: “remote-tracking” branches. These are maintained
+ in tandem by <code>git remote</code> and <code>git fetch</code>, to cache the state of other
+ repositories. Names generally point to commits.</p>
+</li>
+<li>
+<p><code>refs/tags/NAME</code>: tags. The tag name is the ref name with <code>refs/heads/</code>
+ removed. Names generally point to commits or tag objects.</p>
+</li>
+<li>
+<p><code>refs/bisect/STATE</code>: <code>git bisect</code> markers for known-good and known-bad
+ revisions, from which the rest of the bisect state can be derived.</p>
+</li>
+</ul>
+<p>There are also a few special refs directly in the <code>refs/</code> namespace, most
+notably:</p>
+<ul>
+<li><code>refs/stash</code>: The most recent stash entry, as maintained by <code>git stash</code>.
+ (Other stash entries are maintained by a separate system.) Names generally
+ point to commits.</li>
+</ul>
+<p>Tools can invent new refs for their own purposes, or manipulate existing refs;
+the convention is that tools that use refs (which is, as I said, most of them)
+respect the state of the ref as if they'd created that state themselves,
+rather than sanity-checking the ref before using it.</p>
+<h2 id="special-refs">Special refs</h2>
+<p>There are a handful of special refs used by Git commands for their own
+operation. These refs do <em>not</em> begin with <code>refs/</code>:</p>
+<ul>
+<li>
+<p><code>HEAD</code>: the “current” commit for most operations. This is set when checking
+ out a commit, and many revision-related commands default to <code>HEAD</code> if not
+ given a revision to operate on. <code>HEAD</code> can either be a symbolic ref
+ (pointing to a branch ref) or a normal ref (pointing directly to a commit),
+ and is very frequently a symbolic ref.</p>
+</li>
+<li>
+<p><code>MERGE_HEAD</code>: during a merge, <code>MERGE_HEAD</code> resolves to the commit whose
+ history is being merged.</p>
+</li>
+<li>
+<p><code>ORIG_HEAD</code>: set by operations that change <code>HEAD</code> in potentially destructive
+ ways by resolving <code>HEAD</code> before making the change.</p>
+</li>
+<li>
+<p><code>CHERRY_PICK_HEAD</code> is set during <code>git cherry-pick</code> to the commit whose
+ changes are being copied.</p>
+</li>
+<li>
+<p><code>FETCH_HEAD</code> is set by the forms of <code>git fetch</code> that fetch a single ref, and
+ points to the commit the fetched ref pointed to.</p>
+</li>
+</ul>
+<h2 id="examining-and-manipulating-refs">Examining and manipulating refs</h2>
+<p>The <code>git show-ref</code> command will list the refs in namespaces under <code>refs</code> in
+your repository, printing the SHA-1 hashes they resolve to. Pass <code>--head</code> to
+also include <code>HEAD</code>.</p>
+<p>The following commands can be used to manipulate refs directly:</p>
+<ul>
+<li>
+<p><code>git update-ref &lt;ref&gt; &lt;sha1&gt;</code> forcibly sets <code>&lt;ref&gt;</code> to the passed <code>&lt;sha1&gt;</code>.</p>
+</li>
+<li>
+<p><code>git update-ref -d &lt;ref&gt;</code> deletes a ref.</p>
+</li>
+<li>
+<p><code>git symbolic-ref &lt;ref&gt;</code> prints the target of <code>&lt;ref&gt;</code>, if <code>&lt;ref&gt;</code> is a
+ symbolic ref. (It will fail with an error message for normal refs.)</p>
+</li>
+<li>
+<p><code>git symbolic-ref &lt;ref&gt; &lt;target&gt;</code> forcibly makes <code>&lt;ref&gt;</code> a symbolic ref
+ pointing to <code>&lt;target&gt;</code>.</p>
+</li>
+</ul>
+<p>Additionally, you can see what ref a given name resolves to using <code>git
+rev-parse --symbolic-full-name &lt;name&gt;</code> or <code>git show-ref &lt;name&gt;</code>.</p>
+ </div>
+
+
+
+<div id="comments">
+<div id="disqus_thread"></div>
+<script type="text/javascript">
+ /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+ var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname
+
+ /* * * DON'T EDIT BELOW THIS LINE * * */
+ (function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+ })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
+</div>
+
+
+
+ <div id="footer">
+ <p>
+
+ The Codex —
+
+ Powered by <a href="http://markdoc.org/">Markdoc</a>.
+
+<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/git/theory-and-practice/refs-and-names.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/git/theory-and-practice/refs-and-names.md">history</a>).
+
+ </p>
+ </div>
+
+</div>
+</body>
+</html> \ No newline at end of file