简体   繁体   English

Git签出提交

[英]Git Checking out a Commit

When I switch branches in git I use the checkout command. 当我在git中切换分支时,我使用checkout命令。 There often arises a situation in which I want to simply go back and view the state of a project at a certain commit. 经常出现这样的情况,我只想回过头来查看某个提交时项目的状态。 I've been using the git checkout <commit hash> . 我一直在使用git checkout <commit hash> This almost always leaves me in a state with a detached HEAD. 这几乎总是使我处于与HEAD分离的状态。

I was wondering if someone might be able to explain to me why we can checkout branches without detaching the head, but cannot checkout a specific commit in the same way without detaching the HEAD pointer? 我想知道是否有人可以向我解释为什么我们可以在不分离头部的情况下签出分支,但是在不分离HEAD指针的情况下不能以相同的方式签出特定的提交? I have made the mistake of doing a git reset to view an old commit and this of course deletes everything that came after that commit. 我犯了一个错误,即执行git reset来查看旧的提交,这当然会删除该提交之后出现的所有内容。

Why does git checkout <commit hash> detach the head? 为什么git checkout <commit hash>分离头部? And if this isn't the right command for what I am trying to do what is? 如果这不是我要执行的正确命令,那是什么?

One of the primary purposes for HEAD is that it becomes the parent commit of any new commits you create. HEAD的主要目的之一是,它成为您创建的任何新提交的父提交。 Typically the HEAD reference takes one of two forms - either a symbolic reference to a branch tip (eg master ) or the hash of a specific commit. 通常, HEAD引用采用以下两种形式之一:对分支尖端的符号引用(例如master )或特定提交的哈希。 The first is the "normal" mode of operation, and a new commit results in 1) the parent of the new commit being set to the hash represented by the current HEAD , and 2) the branch reference that is the current target of the HEAD reference being moved to point to the new commit. 第一种是“正常”操作模式,新提交导致1)将新提交的父级设置为当前HEAD表示的哈希,以及2)作为HEAD当前目标的分支引用。引用被移至指向新提交。 The second case is called "detached", because your HEAD reference is not currently attached to a branch, but to a specific commit that may or may not be a branch tip. 第二种情况称为“分离”,因为您的HEAD引用当前未附加到分支,而是附加到可能是也可能不是分支提示的特定提交。 This is not a problem, but is just a reminder to you that, because you do not have a branch to update if you create a new commit, any new commits you do make will have nothing except HEAD pointing at them. 这不是问题,只是提醒您,因为创建新提交时没有分支要更新,因此您所做的任何新提交都将没有其他内容,而HEAD指向它们。 If you then check out a different branch, there is nothing at all pointing at the new commits, so you run the risk of losing them (there's still the HEAD reflog, so you can generally recover even then, though). 然后,如果您签出另一个分支,则根本没有指向新提交的内容,因此冒着丢失它们的风险(仍然存在HEAD reflog,因此,尽管如此,您通常仍可以恢复)。

So, the short answer is, no, there is no way to check out an arbitrary non-branch-tip commit without either detaching the HEAD or creating a new branch (but if you're just wanting to look at something on an older commit, that doesn't make sense, because you'll end up with many not-useful branches cluttering up your namespace. There's no harm in having HEAD detached, and it's a normal way of working within git . It just reminds you when you do things like git status so that you can keep in mind what you're in the middle of... 因此,简短的答案是,不,没有办法分离一个HEAD或创建一个新的分支就不能检出任意的非分支提示提交(但是如果您只是想查看一个较旧的提交, ,这没有任何意义,因为您最终会遇到很多没用的分支,使您的命名空间变得混乱。分离HEAD并没有什么害处,这是在git正常的工作方式,它只是在您执行操作时提醒您git status类的东西,这样您就可以记住自己在...中间

You do use checkout correctly. 您确实正确使用了结帐。 In git commits are in specific order. 在git中,提交按特定顺序进行。 For example, this would be your typical history: 例如,这将是您的典型历史记录:

A - B - C - D  <-- branch master
  \ E - F      <-- branch feature

Not sure what the design decision was, but it's convenient. 不确定设计决定是什么,但这很方便。 Branches always point to the last commit in a branch. 分支始终指向分支中的最后一次提交。 So checkout master will get commit D , when checkout feature will get F . 因此, checkout master将获得提交D ,而checkout feature将获得F Because when you check out a branch - you are interested in it's current state and you (probably) want to continue working starting from the last change. 因为当您签出分支时-您对分支的当前状态感兴趣,并且您(可能)想从上次更改开始继续工作。

When you check out a single commit - you look something up and usually revert back. 当您签出一个提交时-您会查找某些内容,通常会还原。 You rarely want to start doing something with commit C , because it has commit D after it (so C is basically "outdated"). 您很少想开始使用commit C ,因为它后面有commit D (因此C基本上是“过时的”)。 If you want to base work off a certain commit - you can start a new branch from it with git branch . 如果要基于某个提交进行工作,则可以使用git branch从中开始一个新git branch

When you checkout a branch, you do detach the HEAD. 签出分支时,您确实分离了HEAD。 You detach it from the branch you were working on. 您将其与正在处理的分支分离。 And you attach it immediatly to the branch you are going to. 然后,将其立即附加到要转到的分支。 When you checkout a commit, there is nothing you can attach your HEAD to. 签出提交时,没有什么可以附加HEAD的。

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

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