dev*_*ium 85 git version-control
目前切换到另一个git提交(在同一个分支上......实际上,在主分支上!),我正在执行命令
git checkout ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a
Run Code Online (Sandbox Code Playgroud)
现在,每次我这样做,git告诉我,我现在有一个超然的头.我如何进行较早的提交仍然保持在同一分支上?
Nic*_*eri 191
大多数时候,当我这样做时,我会结账到临时分支:
git checkout -b temp-branch-name ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a
Run Code Online (Sandbox Code Playgroud)
然后,在我完成后,我只删除分支
Bri*_*ell 78
这取决于您在签出提交时要执行的操作.如果您所做的只是检查它以便您可以构建或测试该修订版,那么使用分离的头部没有任何问题.只需记住在进行任何提交之前检查一个实际的分支(git checkout master
例如),这样就不会创建任何分支中未包含的提交.
但是,如果您希望从该点开始提交更多提交,则应创建一个分支.如果你做了一个没有被分支引用的提交,它们很容易丢失,最终会被git的垃圾收集器清理掉,因为没有任何东西引用它们.您可以通过运行以下命令来创建新分支:
git checkout -b newbranch ea3d5ed
Run Code Online (Sandbox Code Playgroud)
为了帮助可视化,这里有一些图表,展示了在分离头上工作与在分支上工作的不同之处.
让我们从3个提交开始master
,A,B和C. master
是当前分支,所以HEAD
指向master
,指向提交C.
A B C *--*--* <-- master <-- HEAD
现在,如果我们提交,git将创建一个C作为父项的提交(因为这是当前提交,从HEAD
via 指向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 -b branch B
创建分支并检查它,而不是检查一个简单的修订版并获得一个独立的头部.现在你的提交不会丢失,因为它们将被包含在一个分支中,你可以很容易地引用它,并在以后合并.
A B C D *--*--*--* <-- master ^ \-- branch <-- HEAD
如果您忘记这样做,并在分支机构上创建提交,则无需担心.您可以创建一个引用头部修订的分支git checkout -b branch
.如果您已经切换回master
分支,并意识到您忘记了一个迷路提交,您可以使用它来查找它git reflog
,它将显示HEAD
过去几天提交的指向的历史记录.仍然存在于reflog中的任何内容都不会被垃圾回收,并且通常引用会在reflog中保留至少30天.
如果您只想返回之前的提交以使用它而不进行任何更改,您可以这样做
git co <previous-commit-id>
Run Code Online (Sandbox Code Playgroud)
在此命令之后,您将在一个名为"(无分支)"的分支上.
通过确认
git br
Run Code Online (Sandbox Code Playgroud)
使用此前提交的代码后,您可以切换到您所在的分支
git co <the-branch-you-were-on>
Run Code Online (Sandbox Code Playgroud)
"(无分支)"将自动删除.这样您就不需要创建临时分支.
Git的HEAD只是一个指针,指出工作目录中的内容.如果要查看不是分支头的提交,只需将HEAD重定向到指向该提交即可.没有办法绕过它.您可以在该提交中创建一个临时分支,但HEAD将被引导远离master.
这是简短的解释.下面的详细内容有望帮助理解HEAD和master如何不同:
通常,事情看起来像这样:
C ? refs/heads/master ? HEAD
?
B
?
A
Run Code Online (Sandbox Code Playgroud)
也就是说:"C的父级是B,B的父级是A.分支大师指向C,我目前已经检查了master的内容.另外,当我提交时,主人应该更新."
在此中隐含了一些假设,这些假设对于彻底理解提交图是必需的.也就是说,提交只引用它们的父项,而分支的内容是那些可以通过跟随父链接到达的提交(并且只有那些提交).工作树和索引的(未修改的)内容必须对应于HEAD命名的提交,间接("符号")或直接("分离").
因此,如果要签出旧提交,则必须更新HEAD以指向所需的提交.git-checkout
这样做:
C ? refs/heads/master
?
B ? HEAD
?
A
Run Code Online (Sandbox Code Playgroud)
现在,你已经离开了你的分支,因为你正在寻找旧的东西.这是完全可以的,因为"独立的头"建议平静地告诉你(强调我的):
您可以环顾四周,进行实验性更改并提交它们,并且您可以放弃在此状态下进行的任何提交,而不会通过执行另一次检出来影响任何分支.
另一方面,虽然重置你的分支也会在需要的地方获得HEAD,但它会产生非常不同的效果!
C
?
B ? refs/heads/master ? HEAD
?
A
Run Code Online (Sandbox Code Playgroud)
提交C将变为垃圾,因为您已声明您不希望它再次成为主分支的一部分.
简而言之,你所要做的就是通过"HEAD"理解git的意思 - 它就在你所在的位置,而不是任何给定分支的位置.如果您所在的地方与分支的位置不同,则别无选择,只能使用分离的HEAD.
(也许还会查看GitHub,gitk或gitweb以浏览提交历史记录,如果您的HEAD出轨仍然让您烦恼.)
归档时间: |
|
查看次数: |
78763 次 |
最近记录: |