我对编程没有任何经验,我只是开始学习Git。我不明白git checkout
是如何运作的。
根据this:
签出旧提交是一种只读操作。在查看旧版本时,不可能损坏您的存储库。项目的“当前”状态在主分支中保持不变。
下面的段落,他们说明了这一点:
另一方面,签出旧文件确实会影响存储库的当前状态。
对我而言似乎是完全矛盾的。有人可以用外行的话来解释这个吗?
答案 0 :(得分:4)
第二句最好写成:
签出旧文件确实会影响工作区的当前状态
如果您将存储库视为整个项目历史记录中所有文件版本的历史记录,则工作区是某些州的文件快照。
checkout
将内容从存储库移动到工作区中。它只从存储库中读取,但它将写入工作空间。因此,它无法更改仓库,但它可以更改您的工作区。
答案 1 :(得分:0)
因为第一段解释了
git checkout <some commit>
和第二段解释
git checkout <some file>
它们具有不同的语义,特别是第一个是只读的,而第二个确实改变了存储库的状态。
答案 2 :(得分:0)
想象一下,你是在你的主分支,这是你完美的现状。
git checkout master
想象一下,你只是想进入特定的状态或看看你做某些提交时的情况,想象提交的名称是97b4b6c。如果你之前做过97b4b6c提交,git提供了一个选项你可以进入那个状态并检查存储库。
记住
git checkout ~97b4b6c
进入97b4b6c提交状态。 进入这种状态,你的当前状态(主)将不会 伤害。您可以随时返回当前状态(主)。这个 就像,你可以在A(主)和B(97b4b6c)状态之间切换,这个 切换不会影响A或B.
. .
A (master) B (97b4b6c)
git checkout ~97b4b6c #commit name
如果您只对单个文件感兴趣,还可以使用git checkout来获取旧版本的文件。例如,如果您只想查看旧提交中的hello.py文件,则可以使用以下命令:
git checkout commit hello.py
以同样的方式,如果你想在主状态下看到hello.py,在97b4b6c中看到hello.py。
. .
hello.py-A (master) hello.py-B (97b4b6c)
git checkout 97b4b6c hello.py
将在97b46c提交状态下显示hello.py文件。以同样的方式,您也可以通过执行以下操作来查看处于主状态的同一文件:
git checkout master hello.py
请记住,与签出提交不同,这会影响项目的当前状态。旧文件修订版将显示为“要提交的更改”,使您有机会恢复到该文件的先前版本。如果您决定不想保留旧版本,可以使用以下内容查看最新版本。
<强>要点:强>
git check <commit>
将带您进入特定的提交状态,
git checkout <some file>
然而,git checkout和git之间的重要区别 结帐是,
git checkout <commit>
不会影响 您项目的当前状态,但git checkout <some file>
会 肯定会影响你当前的项目状态
还会将您带到特定文件的旧版本
所以,git checkout是一个基本上把你带到某个状态的命令。它是通过提交名称或文件名来执行的。
答案 3 :(得分:0)
Git的文档肯定会有所不足。
上面的一个答案点击了一个关键点,即如果你要求git checkout
从特定版本获取特定文件,这会产生比你预期更大的影响
您需要知道的是,在检出文件时,有三个感兴趣的事情:
第四项,即当前分支,git checkout
也会影响,但这一部分最初是显而易见的。最终它以通常的git方式变得不那么清晰了。 :-)我稍后会谈到这一点。
在使用git checkout
到&#34时,请及时回顾&#34;对于早期的提交,相当清楚这会影响您的工作树。除非git实际上提取了README.txt
的早期版本,否则无法查看早期版本的README.txt
。因此,当然git checkout
会影响工作树。
然而,存储库本身 - 每个已提交文件的每个版本的集合,加上所有提交本身 - 实际上都不受影响,所以说存储库<是合理的/ em>在这里是只读的。 (实际上,更改内容的操作,添加新提交,大多数只是添加到存储库。一旦事情是 现在,这就是它有点松散的地方:在我看来,git commit
,很难让git忘记任何事情 - ed。甚至出现以删除事物的操作,例如在交互式rebase期间删除提交,实际上只是添加的东西。但这又是另一次。)< / p>
使用
git checkout
git checkout
实际上是两到五个相当不同(虽然相关)的命令,都被压缩成一个git checkout
命令。确切的数字取决于你想要将它们分开的清晰度(我说它们至少应该分成两部分,我自己):
的内容是安全的,但结果是映射到有效的版本ID。
git checkout master
或git checkout feature
。git checkout afe3ca9
,或git checkout v1.2
v1.2
是标记。git checkout -- fromindex.txt
。仅当文件的名称可能类似于有效的修订版ID时才需要--
,但总是要包含它是一个好主意,以免您意外使用您认为
git checkout master~20 README.txt
。git checkout -m recreate.py
或git checkout HEAD file.c
。 (请注意,最后一个看起来与命令#4相同。这里的关键区别在于命令#4仅在您处于冲突合并的中间时适用,并且由于这种方式而存在合并使用索引。我们稍后会对此有更多的了解。)这些命令中的每一个都有不同的效果。
分支机构结账会让您“#34; on&#34;该分支,删除和/或替换到达那里所需的任何工作树文件。这种结账非常小心,不要破坏您在工作树中所做的任何修改,如果您丢失了一些工作,它会给您一个错误(此时您可以先保存该工作,然后使用force标志,例如)。
历史结帐非常类似于分支结帐。如果您git checkout v1.2
,为了查看标记为版本1.2的提交中的内容,git会执行与更改分支相同的安全检查。关键的区别在于,如果一切顺利,git会为您提交标记为v1.2
的提交,并且您不再在任何分支上。你有什么git称为&#34;分离的HEAD&#34;。 (您可以&#34;分离您的头部&#34;即使在检查分支时,也可以添加--detach
。很少有理由这样做,还有其他方法可以做到这一点,所以--detach
标志实际上是完全没必要的,但这完全是另一个问题。)
这两种git checkout
都会将您从一个提交(和/或分支)转移到另一个提交(不同的提交)。他们更新工作树,并改变git对当前分支/提交的想法。
我之前提到&#34;当前分支&#34;仔细观察时会有点朦胧。这是因为&#34;分离的HEAD&#34;事情。为了记录您当前的分支,git将分支名称写入文件.git/HEAD
。您可以使用文件查看器或编辑器查看此文件(但请注意不要删除它,就像它已经消失一样,git将不再相信您有一个存储库!)。通常,此文件包含ref: refs/heads/master
或ref: refs/heads/branch
,而 .git/refs/heads/master
,但有时这些参考文件被打包并且#34;以节省空间和时间。)
现在让我们回到结帐命令类型#3到#5。这些不检查您是否在工作树中删除某些内容,因为他们不更改您当前的提交ID,也不会影响您当前的分支。相反,它们使用所选提交中的所选文件的内容覆盖您的工作树,或者,为了重新创建合并,重新尝试合并的结果是您在中间的。但他们又做了一件非常重要的事情:他们写入索引。 (或者,您可能希望将此视为将通过索引写入工作树。)
为什么这很重要?
Git使用索引来构建 next 提交,即尚未创建的提交,但是当您运行git commit
时。这就是为什么它也称为&#34;暂存区域&#34;:它是您安排文件的地方,然后一旦按照您想要的方式排列所有内容,您只需运行{ {1}}将暂存区域快照到存储库中,进行新的提交。
这意味着,如果您在分支git commit
上,并且您的工作树和索引都是干净的,那么您决定查看较早版本的{{1 }}:
master
然后git不仅更新了您的工作树,而且还修改了您当前的索引,因此,如果您执行新的README.txt
,那么您就可以了放回旧的$ git checkout master
$ git checkout master~20 README.txt
文件。
您可以轻松切换索引版本:
git commit
但你需要记住这样做。 (您也可以使用README.txt
执行此操作,但请注意,$ git checkout master README.txt
与git reset
一样,是几个命令都被压缩为一个。)
我提到合并使用索引。如果您处于冲突合并的中间,git会在索引中保留每个冲突文件的三个 1 版本,这些版本通常称为&#34; merge-base&#34;,& #34;我们的&#34;,&#34;他们的&#34;,但也被计算在内:1,2和3.到&#34;解决&#34;合并,你告诉git用&#34;版本0&#34;替换这三个。当您使用git reset
添加已解决的合并时,这就是您正在做的事情;但您也可以使用git checkout
解析合并,该git add
写入版本号为零,以便解决版本1-3。
运行git checkout
时,此checkout变体将删除版本0并重新创建版本1-3。你不需要正常地了解所有这些,但它可以在合并过程中从错误中恢复。
1 由于合并可以运行到文件删除或文件创建的操作中,因此实际上最多三个版本。如果该文件不存在于合并库中但存在于两个合并更改中,那么您将在&#34; merge-base&#34;中出现冲突。插槽中的插槽。