forked from swcarpentry/git-novice
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdiscussion.html
238 lines (227 loc) · 18.3 KB
/
discussion.html
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<title>Software Carpentry: Version Control with Git</title>
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap-theme.css" />
<link rel="stylesheet" type="text/css" href="css/swc.css" />
<link rel="alternate" type="application/rss+xml" title="Software Carpentry Blog" href="http://software-carpentry.org/feed.xml"/>
<meta charset="UTF-8" />
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body class="lesson">
<div class="container card">
<div class="banner">
<a href="http://software-carpentry.org" title="Software Carpentry">
<img alt="Software Carpentry banner" src="img/software-carpentry-banner.png" />
</a>
</div>
<article>
<div class="row">
<div class="col-md-10 col-md-offset-1">
<a href="index.html"><h1 class="title">Version Control with Git</h1></a>
<h2 class="subtitle">Discussion</h2>
<h2 id="frequently-asked-questions">Frequently Asked Questions</h2>
<p>People often have questions about Git beyond the scope of the core material. Students who have completed the rest of the lessons might find value in looking through the following topics.</p>
<p>Note that since this material isn’t essential for basic Git usage, it won’t be covered by the instructor.</p>
<h2 id="more-advanced-git-configuration">More Advanced Git Configuration</h2>
<p>In <a href="02-setup.html">Setting Up Git</a>, we used <code>git config --global</code> to set some default options for Git. It turns out that these configuration options get stored in your home directory in a plain text file called <code>.gitconfig</code>.</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">cat</span> ~/.gitconfig</code></pre>
<pre class="output"><code>[user]
name = Vlad Dracula
email = vlad@tran.sylvan.ia
[color]
ui = true
[core]
editor = nano</code></pre>
<p>This file can be opened in your preferred text editor. (Note that it is recommended to continue using the <code>git config</code> command, as this helps avoid introducing syntax errors.)</p>
<p>Eventually, you will want to start customizing Git’s behaviour. This can be done by adding more entries to your <code>.gitconfig</code>. The available options are described in the manual:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> config --help</code></pre>
<p>In particular, you might find it useful to add aliases. These are like shortcuts for longer git commands. For example, if you get sick of typing <code>git checkout</code> all the time, you could run the command:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> config --global alias.co checkout</code></pre>
<p>Now if we return to the example from <a href="05-history.html">Exploring History</a> where we ran:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> checkout f22b25e mars.txt</code></pre>
<p>we could now instead type:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> co f22b25e mars.txt</code></pre>
<h2 id="styling-gits-log">Styling Git’s Log</h2>
<p>A good target for customization is output from the log. The default log is quite verbose but gives no graphical hints such as information about which commits were done locally and which were pulled from remotes.</p>
<p>You can use <code>git log --help</code> and <code>git config --help</code> to look for different ways to change the log output. Try the following commands and see what effect they have:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> config --global alias.lg <span class="st">"log --graph"</span>
$ <span class="kw">git</span> config --global log.abbrevCommit true
$ <span class="kw">git</span> config --global format.pretty oneline
$ <span class="kw">git</span> lg</code></pre>
<p>If you don’t like the effects, you can undo them with:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> config --global --unset alias.lg
$ <span class="kw">git</span> config --global --unset log.abbrevCommit
$ <span class="kw">git</span> config --global --unset format.pretty</code></pre>
<aside class="callout panel panel-info">
<div class="panel-heading">
<h2><span class="glyphicon glyphicon-pushpin"></span>Undoing Git Configuration Changes</h2>
</div>
<div class="panel-body">
<p>You can use the <code>--unset</code> flag to delete unwanted options from <code>.gitconfig</code>. Another way to roll back changes is to store your <code>.gitconfig</code> using Git.</p>
<p>For hints on what you might want to configure, go to GitHub and search for “gitconfig”. You will find hundreds of repositories in which people have stored their own Git configuration files. Sort them by the number of stars and have a look at the top few. If you find some you like, please check that they’re covered by an open source license before you clone them.</p>
</div>
</aside>
<h2 id="non-text-files">Non-text Files</h2>
<p>Recall when we discussed <a href="09-conflict.html">Conflicts</a> there was a challenge that asked:</p>
<blockquote>
<p>What does Git do when there is a conflict in an image or some other non-textual file that is stored in version control?</p>
</blockquote>
<p>We will now revisit this in more detail.</p>
<p>Many people want to version control non-text files, such as images, PDFs and Microsoft Office or LibreOffice documents. It is true that Git can handle these filetypes (which fall under the banner of “binary” file types). However, just because it <em>can</em> be done doesn’t mean it <em>should</em> be done.</p>
<p>Much of Git’s magic comes from being able to do line-by-line comparisons (“diffs”) between files. This is generally easy for programming source code and marked up text. For non-text files, a diff can usually only detect that the files have changed but can’t say how or where.</p>
<p>This has various impacts on Git’s performance and will make it difficult to compare different versions of your project.</p>
<p>For a basic example to show the difference it makes, we’re going to go see what would have happened if Dracula had tried using outputs from a word processor instead of plain text.</p>
<p>Create a new directory and go into it:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">mkdir</span> planets-nontext
$ <span class="kw">cd</span> planets-nontext</code></pre>
<p>Use a program such as Microsoft Word or LibreOffice Writer to create a new document. Enter the same text that we began with before:</p>
<pre class="output"><code>Cold and dry, but everything is my favorite color</code></pre>
<p>Save the document into the <code>planets-nontext</code> directory with the name of <code>mars.doc</code>. Back in the terminal, run the usual commands for setting up a new Git repository:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> init
$ <span class="kw">git</span> add mars.doc
$ <span class="kw">git</span> commit -m <span class="st">"Starting to think about Mars"</span></code></pre>
<p>Then make the same changes to <code>mars.doc</code> that we (or Vlad) previously made to <code>mars.txt</code>.</p>
<pre class="output"><code>Cold and dry, but everything is my favorite color
The two moons may be a problem for Wolfman</code></pre>
<p>Save and close the word processor. Now see what Git thinks of your changes:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> diff</code></pre>
<pre class="output"><code>diff --git a/mars.doc b/mars.doc
index 53a66fd..6e988e9 100644
Binary files a/mars.doc and b/mars.doc differ</code></pre>
<p>Compare this to the earlier <code>git diff</code> obtained when using text files:</p>
<pre class="output"><code>diff --git a/mars.txt b/mars.txt
index df0654a..315bf3a 100644
--- a/mars.txt
+++ b/mars.txt
@@ -1 +1,2 @@
Cold and dry, but everything is my favorite color
+The two moons may be a problem for Wolfman</code></pre>
<p>Notice how plain text files give a much more informative diff. You can see exactly which lines changed and what the changes were.</p>
<p>An uninformative <code>git diff</code> is not the only consequence of using Git on binary files. However, most of the other problems boil down to whether or not a good diff is possible.</p>
<p>This isn’t to say you should <em>never</em> use Git on binary files. A rule of thumb is that it’s okay if the binary file won’t change very often, and if it does change, you don’t care about merging in small differences between versions.</p>
<p>We’ve already seen how a word processed report will fail this test. An example that passes the test is a logo for your organization or project. Even though a logo will be stored in a binary format such as <code>jpg</code> or <code>png</code>, you can expect it will remain fairly static through the lifetime of your repository. On the rare occasion that branding does change, you will probably just want to replace the logo completely rather than merge little differences in.</p>
<h2 id="removing-a-file">Removing a file</h2>
<p>Adding and modifying files are not the only actions one might take when working on a project. It might be required to remove a file from the repository.</p>
<p>Create a new file for the planet Nibiru:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">echo</span> <span class="st">"This is another name for fake planet X"</span> <span class="kw">></span> nibiru.txt</code></pre>
<p>Now add to the repository like you have learned earlier:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> add nibiru.txt
$ <span class="kw">git</span> commit -m <span class="st">'adding info on nibiru'</span>
$ <span class="kw">git</span> status</code></pre>
<pre class="output"><code>On branch master
nothing to commit, working directory clean</code></pre>
<p>Nibiru is not a real planet. That was a silly idea. Let us remove it from the disk and let Git know about it:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> rm nibiru.txt
$ <span class="kw">git</span> status</code></pre>
<pre class="output"><code>On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: nibiru.txt
</code></pre>
<p>The change has been staged. Now commit the removal, and remove the file from the repository itself. Note that the file will be removed in the new commit. The previous commit will still have the file, if you were to retrieve that specific commit.</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> commit -m <span class="st">'Removing info on Nibiru. It is not a real planet!'</span></code></pre>
<h2 id="removing-a-file-with-unix">Removing a File with Unix</h2>
<p>Sometimes we migth forget to remove the file through Git. If you removed the file with Unix <code>rm</code> instead of using <code>git rm</code>, no worries, Git is smart enough to notice the missing file. Let us recreate the file and commit it again.</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">echo</span> <span class="st">"This is another name for fake planet X"</span> <span class="kw">></span> nibiru.txt
$ <span class="kw">git</span> add nibiru.txt
$ <span class="kw">git</span> commit -m <span class="st">'adding nibiru again'</span></code></pre>
<p>Now we remove the file with Unix <code>rm</code>:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">rm</span> nibiru.txt
$ <span class="kw">git</span> status</code></pre>
<pre class="output"><code>On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: nibiru.txt
no changes added to commit (use "git add" and/or "git commit -a")</code></pre>
<p>See how Git has noticed that the file <code>nibiru.txt</code> has been removed from the disk. The next step is to “stage” the removal of the file from the repository. This is done with the command <code>git rm</code> just as before.</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> rm nibiru.txt
$ <span class="kw">git</span> status</code></pre>
<pre class="output"><code>On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: nibiru.txt
</code></pre>
<p>The change that was made in Unix has now been staged and needs to be committed.</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> commit -m <span class="st">'Removing info on Nibiru, again!'</span></code></pre>
<h2 id="renaming-a-file">Renaming a File</h2>
<p>Another common change when working on a project is to rename a file.</p>
<p>Create a file for the planet Krypton:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">echo</span> <span class="st">"Superman's home planet"</span> <span class="kw">></span> krypton.txt</code></pre>
<p>Add it to the repository:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> add krypton.txt
$ <span class="kw">git</span> commit -m <span class="st">'Adding planet Krypton'</span></code></pre>
<p>We all know that Superman moved to Earth. Not that he had much choice. Now his home planet is Earth.</p>
<p>Rename the file <code>krypton.txt</code> to <code>earth.txt</code> with Git:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> mv krypton.txt earth.txt
$ <span class="kw">git</span> status</code></pre>
<pre class="output"><code># On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: krypton.txt -> earth.txt
#</code></pre>
<p>The final step is commit our change to the repository:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> commit -m <span class="st">'Superman'</span>s home is now Earth<span class="st">'</span></code></pre>
<h2 id="renaming-a-file-with-unix">Renaming a File with Unix</h2>
<p>If you forgot to use Git and you used Unix <code>mv</code> instead of <code>git mv</code>, you will have a touch more work to do but Git will be able to deal with it. Let’s try again renaming the file, this time with Unix <code>mv</code>. First, we need to recreate the <code>krypton.txt</code> file:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">echo</span> <span class="st">"Superman's home planet"</span> <span class="kw">></span> krypton.txt
$ <span class="kw">git</span> add krypton.txt
$ <span class="kw">git</span> commit -m <span class="st">'Adding planet Krypton again.'</span></code></pre>
<p>Let us rename the file and see what Git can figured out by itself:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">mv</span> krypton.txt earth.txt
$ <span class="kw">git</span> status</code></pre>
<pre class="output"><code>On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: krypton.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
earth.txt
no changes added to commit (use "git add" and/or "git commit -a")</code></pre>
<p>Git has noticed that the file <code>krypton.txt</code> has disappeared from the file system and a new file <code>earth.txt</code> has showed up.</p>
<p>Add those changes to the staging area:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> add krypton.txt earth.txt
$ <span class="kw">git</span> status</code></pre>
<pre class="output"><code>On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: krypton.txt -> earth.txt
</code></pre>
<p>Notice how Git has now figure out that the <code>krypton.txt</code> has not disappeared it has simply been renamed.</p>
<p>The final step, as before, is to commit our change to the repository:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> commit -m <span class="st">'Superman'</span>s home is Earth, told you before.<span class="st">'</span></code></pre>
</div>
</div>
</article>
<div class="footer">
<a class="label swc-blue-bg" href="http://software-carpentry.org">Software Carpentry</a>
<a class="label swc-blue-bg" href="https://github.com/swcarpentry/git-novice">Source</a>
<a class="label swc-blue-bg" href="mailto:admin@software-carpentry.org">Contact</a>
<a class="label swc-blue-bg" href="LICENSE.html">License</a>
</div>
</div>
<!-- Javascript placed at the end of the document so the pages load faster -->
<script src="http://software-carpentry.org/v5/js/jquery-1.9.1.min.js"></script>
<script src="css/bootstrap/bootstrap-js/bootstrap.js"></script>
<script src='https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-37305346-2', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>