检查旧的提交并维护主分支上的头?

发布于 2024-11-01 04:36:21 字数 202 浏览 1 评论 0原文

目前,为了切换到另一个 git 提交(在同一个分支上......实际上,在主分支上!),我正在执行命令

git checkout ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a

现在,每次执行此操作时,git 都会告诉我,我现在有一个分离的头。如何转到较旧的提交并仍将头保留在同一分支上?

Currently for switching to another git commit (on the same branch...actually, on the master branch!), I'm executing the command

git checkout ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a

Now, every time I do this git tells me that I'm now with a detached head. How do I go to an older commit and still maintain the head on the same branch?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

┾廆蒐ゝ 2024-11-08 04:36:21

大多数时候,当我这样做时,我会签出临时分支:

git checkout -b temp-branch-name ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a

然后在完成后我只需删除该分支

Most of the time when I do this I checkout to a temp branch:

git checkout -b temp-branch-name ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a

Then after I'm done i just delete the branch

枉心 2024-11-08 04:36:21

这取决于您签出该提交时想要执行的操作。如果您所做的只是检查它,以便可以构建或测试该修订版,那么使用独立的头工作并没有什么问题。只需记住在进行任何提交之前检查实际分支(例如 git checkout master ),这样您就不会创建未包含在任何分支中的提交。

但是,如果您想从该点开始进行更多提交,则应该创建一个分支。如果您进行的提交未被分支引用,它们很容易丢失,并且最终会被 git 的垃圾收集器清理,因为没有任何东西引用它们。您可以通过运行以下命令来创建新分支:

git checkout -b newbranch ea3d5ed

为了帮助可视化,这里有一些图表演示了在分离头上工作与在分支上工作有何不同。

让我们从 master、A、B 和 C 上的 3 次提交开始。master 是当前分支,因此 HEAD 指向 master,它指向提交 C。

A  B  C
*--*--* <-- master <-- HEAD

现在,如果我们提交,git 将创建一个以 C 作为父级的提交(因为这是当前提交,通过 HEAD 指向) master),并将更新master 指向该新提交。我们所有的提交现在都在 master 中,并且 HEAD 通过 master 指向新的提交。

A  B  C  D
*--*--*--* <-- master <-- HEAD

现在让我们看看 B,给我们一个分离的 HEAD

A  B  C  D
*--*--*--* <-- master
   ^
    \-- HEAD

这里一切正常;我们可以查看所有文件,构建我们的程序,测试它等等。我们甚至可以创建新的提交;但如果我们这样做,我们所在的分支就不再存在,因此我们无法将任何分支指向该新提交。唯一指向它的是 HEAD

A  B  C  D
*--*--*--* <-- master
    \
     * <-- HEAD
     E

如果我们稍后决定再次检查 master,则不会有任何内容引用 E。

A  B  C  D
*--*--*--* <-- master <-- HEAD
    \
     *
     E

由于没有任何内容引用它,因此它可以很难找到,并且 git 认为没有引用的提交是被放弃的(如果你变基,或者压缩补丁,或者做其他有趣的历史操作,它们通常会发生;它们通常代表你不再关心的被放弃的补丁)。一段时间后,git 会将其视为垃圾,并在下次运行垃圾收集时将其丢弃。

因此,如果您觉得要进行更多提交,而不是检查一个裸版本并获得一个分离的头,您应该使用 git checkout -bbranch B 来创建一个分支并检查它出去。现在您的提交不会丢失,因为它们将包含在分支中,您可以轻松引用并稍后合并。

A  B  C  D
*--*--*--* <-- master
   ^
    \-- branch <-- HEAD

如果您忘记执行此操作并在分支上创建提交,则无需担心。您可以使用 git checkout -bbranch 创建一个引用头修订版的分支。如果您已经切换回 master 分支,并且意识到您忘记了杂散提交,则可以使用 git reflog,它将向您显示提交 HEAD 内容的历史记录过去几天已经指出。仍然在引用日志中的任何内容都不会被垃圾收集,并且通常引用会在引用日志中保留至少 30 天。

It depends on what you want to do when you checkout that commit. If all you're doing is checking it out so you can build or test that revision, then there's nothing wrong with working with a detached head. Just remember to check out an actual branch before you make any commits (git checkout master, for example), so that you don't create commits that are not included in any branch.

If, however, you want to make more commits starting from that point, you should create a branch. If you make commits that are not referenced by a branch, they can easily get lost, and will eventually be cleaned up by git's garbage collector, as nothing refers to them. You can create a new branch by running:

git checkout -b newbranch ea3d5ed

To help visualize, here's are some diagrams demonstrating how working on a detached head differs from working on a branch.

Let's start out with 3 commits on master, A, B, and C. master is the current branch, so HEAD points to master, which points to commit C.

A  B  C
*--*--* <-- master <-- HEAD

Now if we commit, git will create a commit that has C as a parent (because that's the current commit, pointed to from HEAD via master), and will update master to point to that new commit. All of our commits are now in master, and HEAD points to the new commit through master.

A  B  C  D
*--*--*--* <-- master <-- HEAD

Now let's check out B, giving us a detached HEAD.

A  B  C  D
*--*--*--* <-- master
   ^
    \-- HEAD

Everything works fine here; we can look at all of the files, build our program, test it, etc. We can even create new commits; but if we do so, there's no branch that we're on, so we can't point any branch at that new commit. The only thing pointing at it is HEAD:

A  B  C  D
*--*--*--* <-- master
    \
     * <-- HEAD
     E

If we later decide to check out master again, there will be nothing referring to E.

A  B  C  D
*--*--*--* <-- master <-- HEAD
    \
     *
     E

Since there's nothing referring to it, it can be hard to find, and git considers commits with no references to be abandoned (they happen quite commonly if you rebase, or squash patches in, or do other fun history manipulation; they usually represent abandoned patches that you no longer care about). After a certain amount of time, git will consider it garbage, to be discarded the next time garbage collection runs.

So, instead of checking out a bare revision and getting a detached head, if you feel like you are going to make more commits, you should use git checkout -b branch B to create a branch and check it out. Now your commits won't be lost, as they will be included in a branch, that you can easily refer to, and merge later on.

A  B  C  D
*--*--*--* <-- master
   ^
    \-- branch <-- HEAD

If you forget to do this, and create commits off a branch, there's no need to worry. You can create a branch referring to the head revision with git checkout -b branch. If you have already switched back to the master branch, and realize that you forgot a stray commit, you can find it using git reflog, which will show you a history of what commits HEAD has pointed to over the last few days. Anything that's still in the reflog will not be garbage collected, and generally references are kept in the reflog for at least 30 days.

£烟消云散 2024-11-08 04:36:21

如果您只是想返回到较早的提交来使用它而不进行任何更改,则可以执行

git co <previous-commit-id>

此命令后您将位于名为“(无分支)”的分支上。

通过以下方式确认这一点:

git br

在使用完之前提交的代码后,您可以通过以下方式切换到您所在的分支

git co <the-branch-you-were-on>

。“(无分支)”将被自动删除。这样您就不需要创建临时分支。

If you simply want to return to an earlier commit to play with it without making any changes, you can do

git co <previous-commit-id>

you'll will be on a branch called "(no branch)" after this command.

Confirm this by

git br

After you've played with this previously committed code, you can switch to the branch you were on by

git co <the-branch-you-were-on>

The "(no branch)" will be deleted automatically. This way you don't need to create a temporary branch.

等往事风中吹 2024-11-08 04:36:21

Git 的 HEAD 只是一个指针,指示工作目录中的内容。如果您想签出不是分支头的提交,您只需将 HEAD 重定向到指向该提交即可。没有办法解决这个问题。您可以在该提交时创建一个临时分支,但 HEAD 仍将被引导远离 master。

这就是简短的解释。下面的详细内容有望帮助您理解 HEAD 和 master 有何不同:

通常情况下,情况如下所示: 这

C ← refs/heads/master ← HEAD 
↓
B
↓
A

就是说:“C 的父级是 B,B 的父级是 A。分支 master 指向 C ,目前我已经查看了master的内容。另外,当我提交时,master 也会更新。”

其中隐含了一些假设,这些假设对于彻底理解提交图是必要的。也就是说,提交仅引用其父级,而分支的内容是那些可以通过父级链接到达的提交(并且仅是那些提交)。工作树和索引的(未修改的)内容必须对应于 HEAD 命名的提交,无论是间接(“符号”)还是直接(“分离”)。

因此,如果您想签出旧的提交,则必须更新 HEAD 以指向所需的提交。 git-checkout 就是这么做的:

C ← refs/heads/master 
↓
B ← HEAD
↓
A

现在,你已经把你的分支抛在了身后,因为你正在查看旧的东西。这完全没问题,正如“超然的头脑”建议冷静地告诉你的那样(强调我的):

您可以环顾四周,进行实验性更改并提交它们,并且可以通过执行另一次签出来放弃在此状态下所做的任何提交,不会影响任何分支

另一方面,虽然重置分支也会使 HEAD 到达需要的位置,但它会产生非常不同的效果!

C
↓
B ← refs/heads/master ← HEAD
↓
A

提交 C 将成为垃圾,因为您已经声明您不希望它再成为 master 分支的一部分。

简而言之,您所要做的就是理解 git 中“HEAD”的含义 - 它是您所在的位置,而不是任何给定分支所在的位置。如果您所在的位置与分支所在的位置不同,则别无选择,只能使用分离的 HEAD。

(如果你的 HEAD 脱轨仍然让你烦恼,也许还可以查看 GitHub、gitk 或 gitweb 来浏览提交历史记录。)

Git’s HEAD is simply a pointer that says what’s in the working directory. If you want to check out a commit which is not the head of a branch, you simply have to redirect your HEAD to point at that commit. There’s no way around it. You can create a temporary branch at that commit, but HEAD will be directed away from master nonetheless.

That’s the short explanation. The verbosity below will hopefully aid in understanding how HEAD and master are different:

Normally, things look like this:

C ← refs/heads/master ← HEAD 
↓
B
↓
A

Which is to say: “The parent of C is B, and the parent of B is A. The branch master is pointing to C, and I currently have checked out the contents of master. In addition, when I commit, master shall be updated.”

Some assumptions are implicit in this which are necessary for a thorough understanding of the commit graph. Namely, commits refer only to their parents, and the contents of a branch are those commits (and only those commits) which can be reached by following the parent links. The (unmodified) contents of the working tree and the index must correspond to the commit named by HEAD, either indirectly (“symbolic”) or directly (“detached”).

Thus, if you want to check out an old commit, the HEAD must be updated to point to the desired commit. git-checkout does just that:

C ← refs/heads/master 
↓
B ← HEAD
↓
A

Now, you’ve left your branch behind you, since you’re looking at something old. That’s perfectly OK, as the “detached head” advice tell you calmly (emphasis mine):

You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout.

On the other hand, while resetting your branch also gets HEAD where it needs to be, it would have a very different effect!

C
↓
B ← refs/heads/master ← HEAD
↓
A

The commit C will become garbage, since you have declared that you do not wish for it to be part of the master branch anymore.

In short, all you have to do is understand what git means by “HEAD” — it’s where you are, not where any given branch is. And if where you are is not the same as where a branch is, there is no choice but to use a detached HEAD.

(Perhaps also look into GitHub, gitk, or gitweb to browse the commit history, if derailing your HEAD continues to irk you.)

橙味迷妹 2024-11-08 04:36:21

这个问题有点模糊,但是如果您只想更改工作树中的文件,您可以简单地执行以下操作:

git checkout [commit|branch] -- .

然后您可以暂存更改并如果您愿意,可以创建一个新的提交。这有时非常有用。

The question is a bit vague, but if you want to just change files in your working tree, you can simply do this:

git checkout [commit|branch] -- .

You can then stage the changes and create a new commit if you wish. This is pretty useful sometimes.

知你几分 2024-11-08 04:36:21

我想我理解你的问题。这是我发现解决它的方法。而且它没有GUI解决方案,只能使用命令来解决,而且非常简单。

步骤 1:创建您想要返回的旧提交的标签。

就像标签 v2.0

第 2 步:git checkout v2.0

一样,现在你的 HEAD 指向“v2.0”提交,但 master 仍然指向最后一次提交。

C:\Program Files\Git\doc\git\html\git-checkout.html 这个文档可能会帮助你

或者输入 git help <结帐>>

I think I understand your questions. Here is what I found to solve it. and there is no GUI solution of it, you can only use command to solve it, and it's really simple.

step 1: creat a tag of the old commit which you want to go back.

like tag v2.0

step 2: git checkout v2.0

here it is, now your HEAD is pointing at 'v2.0' commit, but master is still pointing at last commit.

C:\Program Files\Git\doc\git\html\git-checkout.html this document may help you

or type git help < checkout >

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文