summaryrefslogtreecommitdiff
path: root/.html/git/survival.html
blob: c1d43ac8d8db94dcab40cf8babe64cc578217d3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
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>