@matheusbsbs / matheus-bagliano / commits / be8ef33c1d
Fork 0

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 --------