git-checkout.txt: improve detached HEAD documentation
The detached HEAD state is a source of much confusion for users new to git. Here we try to document it better. Reworked from http://article.gmane.org/gmane.comp.version-control.git/138440 Requested-by: Nicolas Pitre <nico@fluxnic.net> Signed-off-by: Jay Soffian <jaysoffian@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jay Soffian committed
Feb 20, 2011 at 00:21 UTC
be8ef33c1deabf34a82e4af98bd35243939ed9a5
1 file changed
+121
-23
Documentation/git-checkout.txt
+121
-23
@@ -206,40 +206,138 @@ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.
206
207
Detached HEAD
208
-------------
209
+HEAD normally refers to a named branch (e.g. 'master'). Meanwhile, each
210
+branch refers to a specific commit. Let's look at a repo with three
211
+commits, one of them tagged, and with branch 'master' checked out:
212
210
-It is sometimes useful to be able to 'checkout' a commit that is
211
-not at the tip of one of your branches. The most obvious
212
-example is to check out the commit at a tagged official release
213
-point, like this:
213
+------------
214
+ HEAD (refers to branch 'master')
215
+ |
216
+ v
217
+a---b---c branch 'master' (refers to commit 'c')
218
+ ^
219
+ |
220
+ tag 'v2.0' (refers to commit 'b')
221
+------------
222
+
223
+When a commit is created in this state, the branch is updated to refer to
224
+the new commit. Specifically, 'git commit' creates a new commit 'd', whose
225
+parent is commit 'c', and then updates branch 'master' to refer to new
226
+commit 'd'. HEAD still refers to branch 'master' and so indirectly now refers
227
+to commit 'd':
228
229
------------
216
-$ git checkout v2.6.18
230
+$ edit; git add; git commit
231
+
232
+ HEAD (refers to branch 'master')
233
+ |
234
+ v
235
+a---b---c---d branch 'master' (refers to commit 'd')
236
+ ^
237
+ |
238
+ tag 'v2.0' (refers to commit 'b')
239
------------
240
219
-Earlier versions of git did not allow this and asked you to
220
-create a temporary branch using the `-b` option, but starting from
221
-version 1.5.0, the above command 'detaches' your HEAD from the
222
-current branch and directly points at the commit named by the tag
223
-(`v2.6.18` in the example above).
241
+It is sometimes useful to be able to checkout a commit that is not at
242
+the tip of any named branch, or even to create a new commit that is not
243
+referenced by a named branch. Let's look at what happens when we
244
+checkout commit 'b' (here we show two ways this may be done):
245
225
-You can use all git commands while in this state. You can use
226
-`git reset --hard $othercommit` to further move around, for
227
-example. You can make changes and create a new commit on top of
228
-a detached HEAD. You can even create a merge by using `git
229
-merge $othercommit`.
246
+------------
247
+$ git checkout v2.0 # or
248
+$ git checkout master^^
249
+
250
+ HEAD (refers to commit 'b')
251
+ |
252
+ v
253
+a---b---c---d branch 'master' (refers to commit 'd')
254
+ ^
255
+ |
256
+ tag 'v2.0' (refers to commit 'b')
257
+------------
258
231
-The state you are in while your HEAD is detached is not recorded
232
-by any branch (which is natural --- you are not on any branch).
233
-What this means is that you can discard your temporary commits
234
-and merges by switching back to an existing branch (e.g. `git
235
-checkout master`), and a later `git prune` or `git gc` would
236
-garbage-collect them. If you did this by mistake, you can ask
237
-the reflog for HEAD where you were, e.g.
259
+Notice that regardless of which checkout command we use, HEAD now refers
260
+directly to commit 'b'. This is known as being in detached HEAD state.
261
+It means simply that HEAD refers to a specific commit, as opposed to
262
+referring to a named branch. Let's see what happens when we create a commit:
263
264
------------
240
-$ git log -g -2 HEAD
265
+$ edit; git add; git commit
266
+
267
+ HEAD (refers to commit 'e')
268
+ |
269
+ v
270
+ e
271
+ /
272
+a---b---c---d branch 'master' (refers to commit 'd')
273
+ ^
274
+ |
275
+ tag 'v2.0' (refers to commit 'b')
276
------------
277
278
+There is now a new commit 'e', but it is referenced only by HEAD. We can
279
+of course add yet another commit in this state:
280
+
281
+------------
282
+$ edit; git add; git commit
283
+
284
+ HEAD (refers to commit 'f')
285
+ |
286
+ v
287
+ e---f
288
+ /
289
+a---b---c---d branch 'master' (refers to commit 'd')
290
+ ^
291
+ |
292
+ tag 'v2.0' (refers to commit 'b')
293
+------------
294
+
295
+In fact, we can perform all the normal git operations. But, let's look
296
+at what happens when we then checkout master:
297
+
298
+------------
299
+$ git checkout master
300
+
301
+ HEAD (refers to branch 'master')
302
+ e---f |
303
+ / v
304
+a---b---c---d branch 'master' (refers to commit 'd')
305
+ ^
306
+ |
307
+ tag 'v2.0' (refers to commit 'b')
308
+------------
309
+
310
+It is important to realize that at this point nothing refers to commit
311
+'f'. Eventually commit 'f' (and by extension commit 'e') will be deleted
312
+by the routine git garbage collection process, unless we create a reference
313
+before that happens. If we have not yet moved away from commit 'f',
314
+any of these will create a reference to it:
315
+
316
+------------
317
+$ git checkout -b foo <1>
318
+$ git branch foo <2>
319
+$ git tag foo <3>
320
+------------
321
+
322
+<1> creates a new branch 'foo', which refers to commit 'f', and then
323
+updates HEAD to refer to branch 'foo'. In other words, we'll no longer
324
+be in detached HEAD state after this command.
325
+
326
+<2> similarly creates a new branch 'foo', which refers to commit 'f',
327
+but leaves HEAD detached.
328
+
329
+<3> creates a new tag 'foo', which refers to commit 'f',
330
+leaving HEAD detached.
331
+
332
+If we have moved away from commit 'f', then we must first recover its object
333
+name (typically by using git reflog), and then we can create a reference to
334
+it. For example, to see the last two commits to which HEAD referred, we
335
+can use either of these commands:
336
+
337
+------------
338
+$ git reflog -2 HEAD # or
339
+$ git log -g -2 HEAD
340
+------------
341
342
EXAMPLES
343
--------