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