Merge branch 'sb/unpack-trees-grammofix'
[git] / Documentation / gittutorial-2.txt
1 gittutorial-2(7)
2 ================
3
4 NAME
5 ----
6 gittutorial-2 - A tutorial introduction to Git: part two
7
8 SYNOPSIS
9 --------
10 [verse]
11 git *
12
13 DESCRIPTION
14 -----------
15
16 You should work through linkgit:gittutorial[7] before reading this tutorial.
17
18 The goal of this tutorial is to introduce two fundamental pieces of
19 Git's architecture--the object database and the index file--and to
20 provide the reader with everything necessary to understand the rest
21 of the Git documentation.
22
23 The Git object database
24 -----------------------
25
26 Let's start a new project and create a small amount of history:
27
28 ------------------------------------------------
29 $ mkdir test-project
30 $ cd test-project
31 $ git init
32 Initialized empty Git repository in .git/
33 $ echo 'hello world' > file.txt
34 $ git add .
35 $ git commit -a -m "initial commit"
36 [master (root-commit) 54196cc] initial commit
37  1 file changed, 1 insertion(+)
38  create mode 100644 file.txt
39 $ echo 'hello world!' >file.txt
40 $ git commit -a -m "add emphasis"
41 [master c4d59f3] add emphasis
42  1 file changed, 1 insertion(+), 1 deletion(-)
43 ------------------------------------------------
44
45 What are the 7 digits of hex that Git responded to the commit with?
46
47 We saw in part one of the tutorial that commits have names like this.
48 It turns out that every object in the Git history is stored under
49 a 40-digit hex name.  That name is the SHA-1 hash of the object's
50 contents; among other things, this ensures that Git will never store
51 the same data twice (since identical data is given an identical SHA-1
52 name), and that the contents of a Git object will never change (since
53 that would change the object's name as well). The 7 char hex strings
54 here are simply the abbreviation of such 40 character long strings.
55 Abbreviations can be used everywhere where the 40 character strings
56 can be used, so long as they are unambiguous.
57
58 It is expected that the content of the commit object you created while
59 following the example above generates a different SHA-1 hash than
60 the one shown above because the commit object records the time when
61 it was created and the name of the person performing the commit.
62
63 We can ask Git about this particular object with the `cat-file`
64 command. Don't copy the 40 hex digits from this example but use those
65 from your own version. Note that you can shorten it to only a few
66 characters to save yourself typing all 40 hex digits:
67
68 ------------------------------------------------
69 $ git cat-file -t 54196cc2
70 commit
71 $ git cat-file commit 54196cc2
72 tree 92b8b694ffb1675e5975148e1121810081dbdffe
73 author J. Bruce Fields <bfields@puzzle.fieldses.org> 1143414668 -0500
74 committer J. Bruce Fields <bfields@puzzle.fieldses.org> 1143414668 -0500
75
76 initial commit
77 ------------------------------------------------
78
79 A tree can refer to one or more "blob" objects, each corresponding to
80 a file.  In addition, a tree can also refer to other tree objects,
81 thus creating a directory hierarchy.  You can examine the contents of
82 any tree using ls-tree (remember that a long enough initial portion
83 of the SHA-1 will also work):
84
85 ------------------------------------------------
86 $ git ls-tree 92b8b694
87 100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad    file.txt
88 ------------------------------------------------
89
90 Thus we see that this tree has one file in it.  The SHA-1 hash is a
91 reference to that file's data:
92
93 ------------------------------------------------
94 $ git cat-file -t 3b18e512
95 blob
96 ------------------------------------------------
97
98 A "blob" is just file data, which we can also examine with cat-file:
99
100 ------------------------------------------------
101 $ git cat-file blob 3b18e512
102 hello world
103 ------------------------------------------------
104
105 Note that this is the old file data; so the object that Git named in
106 its response to the initial tree was a tree with a snapshot of the
107 directory state that was recorded by the first commit.
108
109 All of these objects are stored under their SHA-1 names inside the Git
110 directory:
111
112 ------------------------------------------------
113 $ find .git/objects/
114 .git/objects/
115 .git/objects/pack
116 .git/objects/info
117 .git/objects/3b
118 .git/objects/3b/18e512dba79e4c8300dd08aeb37f8e728b8dad
119 .git/objects/92
120 .git/objects/92/b8b694ffb1675e5975148e1121810081dbdffe
121 .git/objects/54
122 .git/objects/54/196cc2703dc165cbd373a65a4dcf22d50ae7f7
123 .git/objects/a0
124 .git/objects/a0/423896973644771497bdc03eb99d5281615b51
125 .git/objects/d0
126 .git/objects/d0/492b368b66bdabf2ac1fd8c92b39d3db916e59
127 .git/objects/c4
128 .git/objects/c4/d59f390b9cfd4318117afde11d601c1085f241
129 ------------------------------------------------
130
131 and the contents of these files is just the compressed data plus a
132 header identifying their length and their type.  The type is either a
133 blob, a tree, a commit, or a tag.
134
135 The simplest commit to find is the HEAD commit, which we can find
136 from .git/HEAD:
137
138 ------------------------------------------------
139 $ cat .git/HEAD
140 ref: refs/heads/master
141 ------------------------------------------------
142
143 As you can see, this tells us which branch we're currently on, and it
144 tells us this by naming a file under the .git directory, which itself
145 contains a SHA-1 name referring to a commit object, which we can
146 examine with cat-file:
147
148 ------------------------------------------------
149 $ cat .git/refs/heads/master
150 c4d59f390b9cfd4318117afde11d601c1085f241
151 $ git cat-file -t c4d59f39
152 commit
153 $ git cat-file commit c4d59f39
154 tree d0492b368b66bdabf2ac1fd8c92b39d3db916e59
155 parent 54196cc2703dc165cbd373a65a4dcf22d50ae7f7
156 author J. Bruce Fields <bfields@puzzle.fieldses.org> 1143418702 -0500
157 committer J. Bruce Fields <bfields@puzzle.fieldses.org> 1143418702 -0500
158
159 add emphasis
160 ------------------------------------------------
161
162 The "tree" object here refers to the new state of the tree:
163
164 ------------------------------------------------
165 $ git ls-tree d0492b36
166 100644 blob a0423896973644771497bdc03eb99d5281615b51    file.txt
167 $ git cat-file blob a0423896
168 hello world!
169 ------------------------------------------------
170
171 and the "parent" object refers to the previous commit:
172
173 ------------------------------------------------
174 $ git cat-file commit 54196cc2
175 tree 92b8b694ffb1675e5975148e1121810081dbdffe
176 author J. Bruce Fields <bfields@puzzle.fieldses.org> 1143414668 -0500
177 committer J. Bruce Fields <bfields@puzzle.fieldses.org> 1143414668 -0500
178
179 initial commit
180 ------------------------------------------------
181
182 The tree object is the tree we examined first, and this commit is
183 unusual in that it lacks any parent.
184
185 Most commits have only one parent, but it is also common for a commit
186 to have multiple parents.   In that case the commit represents a
187 merge, with the parent references pointing to the heads of the merged
188 branches.
189
190 Besides blobs, trees, and commits, the only remaining type of object
191 is a "tag", which we won't discuss here; refer to linkgit:git-tag[1]
192 for details.
193
194 So now we know how Git uses the object database to represent a
195 project's history:
196
197   * "commit" objects refer to "tree" objects representing the
198     snapshot of a directory tree at a particular point in the
199     history, and refer to "parent" commits to show how they're
200     connected into the project history.
201   * "tree" objects represent the state of a single directory,
202     associating directory names to "blob" objects containing file
203     data and "tree" objects containing subdirectory information.
204   * "blob" objects contain file data without any other structure.
205   * References to commit objects at the head of each branch are
206     stored in files under .git/refs/heads/.
207   * The name of the current branch is stored in .git/HEAD.
208
209 Note, by the way, that lots of commands take a tree as an argument.
210 But as we can see above, a tree can be referred to in many different
211 ways--by the SHA-1 name for that tree, by the name of a commit that
212 refers to the tree, by the name of a branch whose head refers to that
213 tree, etc.--and most such commands can accept any of these names.
214
215 In command synopses, the word "tree-ish" is sometimes used to
216 designate such an argument.
217
218 The index file
219 --------------
220
221 The primary tool we've been using to create commits is `git-commit
222 -a`, which creates a commit including every change you've made to
223 your working tree.  But what if you want to commit changes only to
224 certain files?  Or only certain changes to certain files?
225
226 If we look at the way commits are created under the cover, we'll see
227 that there are more flexible ways creating commits.
228
229 Continuing with our test-project, let's modify file.txt again:
230
231 ------------------------------------------------
232 $ echo "hello world, again" >>file.txt
233 ------------------------------------------------
234
235 but this time instead of immediately making the commit, let's take an
236 intermediate step, and ask for diffs along the way to keep track of
237 what's happening:
238
239 ------------------------------------------------
240 $ git diff
241 --- a/file.txt
242 +++ b/file.txt
243 @@ -1 +1,2 @@
244  hello world!
245 +hello world, again
246 $ git add file.txt
247 $ git diff
248 ------------------------------------------------
249
250 The last diff is empty, but no new commits have been made, and the
251 head still doesn't contain the new line:
252
253 ------------------------------------------------
254 $ git diff HEAD
255 diff --git a/file.txt b/file.txt
256 index a042389..513feba 100644
257 --- a/file.txt
258 +++ b/file.txt
259 @@ -1 +1,2 @@
260  hello world!
261 +hello world, again
262 ------------------------------------------------
263
264 So 'git diff' is comparing against something other than the head.
265 The thing that it's comparing against is actually the index file,
266 which is stored in .git/index in a binary format, but whose contents
267 we can examine with ls-files:
268
269 ------------------------------------------------
270 $ git ls-files --stage
271 100644 513feba2e53ebbd2532419ded848ba19de88ba00 0       file.txt
272 $ git cat-file -t 513feba2
273 blob
274 $ git cat-file blob 513feba2
275 hello world!
276 hello world, again
277 ------------------------------------------------
278
279 So what our 'git add' did was store a new blob and then put
280 a reference to it in the index file.  If we modify the file again,
281 we'll see that the new modifications are reflected in the 'git diff'
282 output:
283
284 ------------------------------------------------
285 $ echo 'again?' >>file.txt
286 $ git diff
287 index 513feba..ba3da7b 100644
288 --- a/file.txt
289 +++ b/file.txt
290 @@ -1,2 +1,3 @@
291  hello world!
292  hello world, again
293 +again?
294 ------------------------------------------------
295
296 With the right arguments, 'git diff' can also show us the difference
297 between the working directory and the last commit, or between the
298 index and the last commit:
299
300 ------------------------------------------------
301 $ git diff HEAD
302 diff --git a/file.txt b/file.txt
303 index a042389..ba3da7b 100644
304 --- a/file.txt
305 +++ b/file.txt
306 @@ -1 +1,3 @@
307  hello world!
308 +hello world, again
309 +again?
310 $ git diff --cached
311 diff --git a/file.txt b/file.txt
312 index a042389..513feba 100644
313 --- a/file.txt
314 +++ b/file.txt
315 @@ -1 +1,2 @@
316  hello world!
317 +hello world, again
318 ------------------------------------------------
319
320 At any time, we can create a new commit using 'git commit' (without
321 the "-a" option), and verify that the state committed only includes the
322 changes stored in the index file, not the additional change that is
323 still only in our working tree:
324
325 ------------------------------------------------
326 $ git commit -m "repeat"
327 $ git diff HEAD
328 diff --git a/file.txt b/file.txt
329 index 513feba..ba3da7b 100644
330 --- a/file.txt
331 +++ b/file.txt
332 @@ -1,2 +1,3 @@
333  hello world!
334  hello world, again
335 +again?
336 ------------------------------------------------
337
338 So by default 'git commit' uses the index to create the commit, not
339 the working tree; the "-a" option to commit tells it to first update
340 the index with all changes in the working tree.
341
342 Finally, it's worth looking at the effect of 'git add' on the index
343 file:
344
345 ------------------------------------------------
346 $ echo "goodbye, world" >closing.txt
347 $ git add closing.txt
348 ------------------------------------------------
349
350 The effect of the 'git add' was to add one entry to the index file:
351
352 ------------------------------------------------
353 $ git ls-files --stage
354 100644 8b9743b20d4b15be3955fc8d5cd2b09cd2336138 0       closing.txt
355 100644 513feba2e53ebbd2532419ded848ba19de88ba00 0       file.txt
356 ------------------------------------------------
357
358 And, as you can see with cat-file, this new entry refers to the
359 current contents of the file:
360
361 ------------------------------------------------
362 $ git cat-file blob 8b9743b2
363 goodbye, world
364 ------------------------------------------------
365
366 The "status" command is a useful way to get a quick summary of the
367 situation:
368
369 ------------------------------------------------
370 $ git status
371 On branch master
372 Changes to be committed:
373   (use "git reset HEAD <file>..." to unstage)
374
375         new file:   closing.txt
376
377 Changes not staged for commit:
378   (use "git add <file>..." to update what will be committed)
379   (use "git checkout -- <file>..." to discard changes in working directory)
380
381         modified:   file.txt
382
383 ------------------------------------------------
384
385 Since the current state of closing.txt is cached in the index file,
386 it is listed as "Changes to be committed".  Since file.txt has
387 changes in the working directory that aren't reflected in the index,
388 it is marked "changed but not updated".  At this point, running "git
389 commit" would create a commit that added closing.txt (with its new
390 contents), but that didn't modify file.txt.
391
392 Also, note that a bare `git diff` shows the changes to file.txt, but
393 not the addition of closing.txt, because the version of closing.txt
394 in the index file is identical to the one in the working directory.
395
396 In addition to being the staging area for new commits, the index file
397 is also populated from the object database when checking out a
398 branch, and is used to hold the trees involved in a merge operation.
399 See linkgit:gitcore-tutorial[7] and the relevant man
400 pages for details.
401
402 What next?
403 ----------
404
405 At this point you should know everything necessary to read the man
406 pages for any of the git commands; one good place to start would be
407 with the commands mentioned in linkgit:giteveryday[7].  You
408 should be able to find any unknown jargon in linkgit:gitglossary[7].
409
410 The link:user-manual.html[Git User's Manual] provides a more
411 comprehensive introduction to Git.
412
413 linkgit:gitcvs-migration[7] explains how to
414 import a CVS repository into Git, and shows how to use Git in a
415 CVS-like way.
416
417 For some interesting examples of Git use, see the
418 link:howto-index.html[howtos].
419
420 For Git developers, linkgit:gitcore-tutorial[7] goes
421 into detail on the lower-level Git mechanisms involved in, for
422 example, creating a new commit.
423
424 SEE ALSO
425 --------
426 linkgit:gittutorial[7],
427 linkgit:gitcvs-migration[7],
428 linkgit:gitcore-tutorial[7],
429 linkgit:gitglossary[7],
430 linkgit:git-help[1],
431 linkgit:giteveryday[7],
432 link:user-manual.html[The Git User's Manual]
433
434 GIT
435 ---
436 Part of the linkgit:git[1] suite.