简体   繁体   English

如何在git中分离HEAD

[英]How to make HEAD detached in git

While trying to pull code from a different machine I got a detached HEAD message(with no branch connected) with red color in command window. 在尝试从不同的机器中提取代码时,我在命令窗口中获得了一个分离的HEAD消息(没有连接分支)和红色。

I would like to analyze what I did to make it detached. 我想分析一下我做了什么让它脱离了。

  1. What is meant by 'detached HEAD'? 什么是'独立的HEAD'的意思?
  2. How can one purposefully make the current branch in git detached from its HEAD? 如何有目的地使git中的当前分支与其HEAD分离?
  3. And once detached, how to attach it? 一旦分离,如何附加它?

EDIT:--------------------------------------------------------------------------- 编辑: - - - - - - - - - - - - - - - - - - - - - - - - ---------------------------

Mistake I made was: git checkout origin/test //checking out remote branch 我犯的错误是:git checkout origin / test //检查远程分支

  1. What is meant by 'detached HEAD'? 什么是'独立的HEAD'的意思?

"detached HEAD" means : if you add a new git commit while detached, it will not be tracked by any named branch. “分离的HEAD”意味着:如果在分离时添加新的git commit ,则任何已命名的分支都不会跟踪它。

HEAD is actually described by a file on your disk : .git/HEAD HEAD实际上是由磁盘上的文件描述的: .git/HEAD
If you look at the content of this file, you can see two formats : 如果查看此文件的内容,可以看到两种格式:

# this means : attached HEAD, "master" is the current active branch
$ cat .git/HEAD 
ref: refs/heads/master

# this means : detached HEAD, current active commit is 140a4c
$ cat .git/HEAD
140a4ceae12c237f9f23321aa5e29d8d14852f6f
  1. How can one purposefully make the current branch in git detached from its HEAD? 如何有目的地使git中的当前分支与其HEAD分离?

If you run git checkout <something> and <something> is anything else than a local branch name (any of : a raw commit id, a tag name or the name of a remote branch), you will be in a "detached HEAD" state. 如果您运行git checkout <something><something>不是本地分支名称(任何:原始提交ID,标记名称或远程分支的名称),您将处于“分离的HEAD”中州。

# this will lead to an attached HEAD :
git checkout master
git checkout develop
git checkout bob/s/feature

# this will lead to a detached HEAD :
git checkout 140a4ce         # raw commit
git checkout 1.1.2           # tag
git checkout origin/develop  # remote branch
  1. And once detached, how to attach it? 一旦分离,如何附加它?

Depending on what you want : 根据您的需要:

  • use git log --decorate -1 or gitk or gitg or any git viewer which will show you the names of branches pointing at your current HEAD commit ; 使用git log --decorate -1gitkgitg或任何git viewer,它将显示指向当前HEAD提交的分支的名称;
    if one of these branches is the one you want to work on, just run git checkout <this branch> 如果其中一个分支是您想要处理的git checkout <this branch> ,只需运行git checkout <this branch>

  • if you know you want to work on a new branch : 如果你知道你想在一个新的分支上工作:

     # create a new branch on your current commit : $ git branch new_branch # checkout this branch to use it as your active branch : $ git checkout new_branch 

    note : git branch new_branch && git checkout new_branch is exactly equivalent to : 注意: git branch new_branch && git checkout new_branch完全相同于:

     # same action in one single command : $ git checkout -b new_branch 

With the " git checkout" command, you determine which revision of your project you want to work on. 使用“ git checkout"命令,可以确定要处理的项目的哪个版本。 Git then places all of that revision's files in your working copy folder. 然后Git将所有修订版的文件放在工作副本文件夹中。

Normally, you use a branch name to communicate with "git checkout": 通常,您使用分支名称与“git checkout”通信:

git checkout development

However, you can also provide the SHA1 hash of a specific commit instead: 但是,您也可以提供特定提交的SHA1哈希:

git checkout 56a4e5c08
Note: checking out '56a4e5c08'.

You are in 'detached HEAD' state...

This exact state - when a specific commit is checked out instead of a branch - is what's called a "detached HEAD". 这个确切的状态 - 当检出特定提交而不是分支时 - 就是所谓的“分离的HEAD”。

The problem with a detached HEAD: 分离HEAD的问题:

The HEAD pointer in Git determines your current working revision (and thereby the files that are placed in your project's working directory). Git中的HEAD指针确定您当前的工作版本(以及放置在项目工作目录中的文件)。 Normally, when checking out a proper branch name, Git automatically moves the HEAD pointer along when you create a new commit. 通常,当检出正确的分支名称时,Git会在您创建新提交时自动移动HEAD指针。 You are automatically on the newest commit of the chosen branch. 您将自动进入所选分支的最新提交。

When you instead choose to check out a commit hash, Git won't do this for you. 当您选择签出提交哈希时,Git将不会为您执行此操作。 The consequence is that when you make changes and commit them, these changes do NOT belong to any branch. 结果是,当您进行更改并提交它们时,这些更改不属于任何分支。 This means they can easily get lost once you check out a different revision or branch: not being recorded in the context of a branch, you lack the possibility to access that state easily (unless you have a brilliant memory and can remember the commit hash of that new commit...). 这意味着一旦你签出一个不同的版本或分支,他们很容易迷路:没有被记录在分支的上下文中,你很难轻易访问该状态(除非你有一个精彩的记忆,并且能记住提交的哈希值那个新的提交......)。

How can one purposefully make the current branch in git detached from its HEAD? 如何有目的地使git中的当前分支与其HEAD分离?

There are a handful of situations where detached HEAD states are common: For example, if you checkout a "remote branch" without tracking it first, you can end up with a detached HEAD. 有一些情况下,分离的HEAD状态很常见:例如,如果您先检查“远程分支”而不先跟踪它,您最终可能会得到一个分离的HEAD。

And once detached, how to attach it? 一旦分离,如何附加它? You only need to checkout the branch you were on, eg 你只需要检查你所在的分支,例如

git checkout master

"Normally", the HEAD points to a branch and the branch points to a commit: “通常”,HEAD指向分支,分支指向提交:

commit1 <-- commit2 <-- commit3
                           ^
                           |
                         master
                           ^
                           |
                          HEAD (attached)

# state after 'git checkout master'

In detached head state, the HEAD points to a commit which is not a tip of a branch: 在分离头状态中,HEAD指向不是分支尖端的提交:

commit1 <-- commit2 <-- commit3
               ^           ^
               |           |
               |         master
               |
               |
              HEAD (detached)

# state after 'git checkout <commit2 SHA>'

I'd recommend reading Pro Git book section Reset Demystified . 我建议阅读Pro Git书籍部分Reset Demystified

.. reset and checkout commands ... are two of the most confusing parts of Git when you first encounter them. .. resetcheckout命令......是你第一次遇到它们时Git中最令人困惑的两个部分。 They do so many things that it seems hopeless to actually understand them and employ them properly. 他们做了很多事情,实际上理解它们并正确使用它们似乎没有用。

Short answer : 简短回答:

1) 'detached' means 'not pointing on any specific branch' 1)'分离'意味着'不指向任何特定分支'

2) git checkout <any commit-id> (to detach HEAD on purpose) 2) git checkout <any commit-id> (故意分离HEAD)

3) git checkout <any branch> (to reattach HEAD) 3) git checkout <any branch> (重新连接HEAD)

  1. It's detached from a branch and now points to a commit. 它与分支分离,现在指向提交。 A non-detached HEAD points to a branch. 未分离的HEAD指向分支。

  2. git checkout foo , where foo is a revision , leads to a detached HEAD. git checkout foo ,其中foo是一个修订版 ,导致一个独立的HEAD。 The revision does not include a local branch without refs/heads/ and heads/ . 修订版不包括没有refs/heads/heads/的本地分支。 So, git checkout refs/heads/master , git checkout origin/master , git checkout HEAD^ , git checkout stash@{0} , git checkout 6184fd3d148b8e330ae4ebbb05c51b88b4b1e0f2 all result in a detached HEAD, while git checkout master doesn't. 所以, git checkout refs/heads/mastergit checkout origin/mastergit checkout HEAD^git checkout stash@{0}git checkout 6184fd3d148b8e330ae4ebbb05c51b88b4b1e0f2都会导致分离的HEAD,而git checkout master则不会。 git checkout HEAD doesn't either. git checkout HEAD也没有。

  3. If you need to work on with the detached HEAD's commit, you can create a branch to track it, by git checkout -b <branch> . 如果你需要处理分离的HEAD提交,你可以通过git checkout -b <branch>创建一个分支来跟踪它。 If the current detached HEAD can be dropped, you can simply switch to another local branch or to another detached HEAD. 如果可以删除当前分离的HEAD,则可以简单地切换到另一个本地分支或另一个分离的HEAD。

HEAD is a ref (a pointer to a commit) which determines what you have checked out. HEAD是一个ref(指向提交的指针),它决定了你检查的内容。 Many commands' default to working on the commit pointed to by HEAD . 许多命令默认使用HEAD指向的提交。 When you make a new commit, its parent (or in the case of merges, first parent) will be the commit pointed to by HEAD (unless you do something relatively obscure). 当你进行新的提交时,它的父级(或者在合并的情况下,第一个父级)将是HEAD指向的提交(除非你做了相对模糊的事情)。

That said, HEAD is a symbolic ref, meaning it can point to a branch instead of pointing directly to a commit. 也就是说, HEAD是一个符号引用,意味着它可以指向一个分支而不是直接指向一个提交。 It is considered normal for HEAD to point to a branch. HEAD指向分支被认为是正常的。 When this is the case, instead of moving HEAD when you add commits, git moves the branch that HEAD points to - and HEAD , being pointed at that branch, implicitly moves along as well. 如果是这样的话,而不是移动HEAD当您添加提交,Git移动该分支HEAD点-和HEAD正指向分支,隐含一起运动为好。

But you can make HEAD point directly to a commit, and that is called "detached head state", meaning the HEAD ref is not attached to any branch. 但是你可以让HEAD直接指向一个提交,这称为“分离头状态”,这意味着HEAD引用不会附加到任何分支。

You can do this in a number of ways. 您可以通过多种方式执行此操作。 Others have pointed out you could check out a commit using its ID (hash value). 其他人指出你可以使用它的ID(哈希值)来检查提交。 You could also check out a specific commit using an expression like master^ . 您还可以使用像master^这样的表达式检出特定的提交。 You could check out any ref that isn't a branch - such as a remote tracking ref, or a tag. 您可以检查任何不是分支的引用 - 例如远程跟踪引用或标记。 You could say git checkout --detach . 你可以说git checkout --detach

You can get out of detached HEAD state just by checking out a branch (without the --detach option). 你可以通过检查一个分支(没有--detach选项)来摆脱分离的HEAD状态。

However, if you made any commits while in detached head state, they may be unreachable. 但是,如果您在处于分离头状态时进行了任何提交,则它们可能无法访问。 In that case, if you don't want to lose them, you'll want to either incorporate them into some branch, create a new branch, or otherwise point some ref at them (eg by tagging them). 在这种情况下,如果您不想丢失它们,您将要么将它们合并到某个分支中,创建一个新分支,或者在其他方面指向一些引用(例如通过标记它们)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM