使用“git checkout”时,我对这两个选项感到有点困惑
我总是使用git checkout -- .
清除我的工作目录。
但今天我错误地输入了git checkout - .
。我发现没有来自git的错误警报。
我已经阅读了git文档,也不知道这个-
选项的作用。这很难谷歌。
所以,请有人对此有任何想法吗?
答案 0 :(得分:7)
使用git checkout
时,您可以使用-
作为@{-1}
的简写。
来自man git-checkout
(强调第二段):
<branch>
Branch to checkout; if it refers to a branch (i.e., a name that, when
prepended with "refs/heads/", is a valid ref), then that branch is checked
out. Otherwise, if it refers to a valid commit, your HEAD becomes
"detached" and you are no longer on any branch (see below for details).
As a special case, the "@{-N}" syntax for the N-th last branch/commit
checks out branches (instead of detaching). You may also specify - which is
synonymous with "@{-1}".
通过在分支master
中创建文件,在另一个分支中修改它,并使用master中的checkout -
来尝试在空的仓库中执行此操作:
$ git init
Initialized empty Git repository in workspace/git-test/.git/
git:(master) $ echo a > a
git:(master*) $ git add a
git:(master*) $ git commit
[master (root-commit) 8433343] Add a to master
1 file changed, 1 insertion(+)
create mode 100644 a
git:(master) $ git checkout -b other
Switched to a new branch 'other'
git:(other) $ echo b > a
git:(other*) $ git add a
git:(other*) $ git commit
[other be2298f] Replace a by b
1 file changed, 1 insertion(+), 1 deletion(-)
git:(other) $ git checkout -
Switched to branch 'master'
git:(master) $ git checkout -- . # no changes (no * next to master in the line below)
git:(master) $ git checkout - . # checking out files from alternate branch 'other'
git:(master*) $ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: a
git:(master*) $ cat a
b
答案 1 :(得分:4)
更新 - 我现在可以重现这种行为,但那是因为我遵循了Marth在答案中提供的信息。
我要补充的主要内容是:出于诊断目的,如果你不确定像checkout
这样的git命令的效果,请使用git status
并查看它是什么。由于checkout
主要影响索引和工作树,因此您应该能够至少看到命令以这种方式改变了什么。
总结是你偶然发现了一种不那么常见的语法,几乎肯定没有按照你的意图行事(当然也不能指望做你想做的事情)。
原始回答
我无法重现您描述的行为。具体来说,如果我说git checkout - .
我收到错误,非0返回代码,并且没有签出。
-
应该被解释为路径规范(我得到的错误反映了这一点);另一种可能性是“tree-ish”(意思是分支,标签,提交ID等);但-
不是有效的分支名称。
因此,如果您的工作目录中碰巧有一个名为-
的跟踪文件,git将只刷新该文件并报告没有警告/错误。
我不确定你对“难以谷歌”的意思;如果你需要git命令的帮助,只需谷歌命令(例如'git checkout`),至少根据我的经验,这应该导致该命令的权威git文档(包括命令语法,它应该告诉你如何解释给定的参数。)
在这种情况下,当我谷歌git checkout
时,第一个结果是https://git-scm.com/docs/git-checkout
答案 2 :(得分:2)
与Marth's answer中一样(这是正确的,而且我已经赞成它),我们从git checkout -
是git checkout @{-1}
的同义词的概念开始,它告诉Git: 看看我的HEAD reflog并在我运行 git checkout branchname
之前找到我所在的分支,并再次检查该分支。这种语法背后的一般思路是你可以这样做:
$ git checkout feature/X
... hack for a while ...
$ git commit -m "save some temporary work"
$ git checkout bug1234
... do a quick fix or look for something ...
$ git checkout -
... now back on feature/X ...
不幸的是,这与一般的git checkout [ tree-ish ] [ -- ] path [path ...]
命令格式结合得很差,正如我所知,这意味着:
--
:此部分是可选的,用于将 tree-ish (如果存在)与任何路径参数分开。如果我们有一个名为zorg
的文件,我们想从索引中提取,但还有一个名为zorg
的分支,我们需要这个。如果我们写了git checkout zorg
而不是git checkout -- zorg
,Git会尝试检查分支。因此,当我们写:
git checkout -- f1 f2 f3
Git将--
视为含义&#34;没有分支,因此没有树,因此请使用索引&#34 ;;因此,各种文件名是从索引中提取的文件,用于覆盖工作树中的内容。
我们可能会这样做的一个原因是我们已经编辑了f1
,f2
和f3
,并认为它们很好。然后我们git add
编辑它们以将这些版本复制到索引中。然后我们对它们进行了一些编辑......但是我们认为工作树版本很糟糕,我们希望 index 版本回到工作树中。这些索引版本尚未提交任何提交:它们仅存储在 索引中。
(我们可能使用git checkout -- f1 f2 f3
的另一个原因是我们编辑了它们但不 git add
编辑它们。在这种情况下,索引版本与{{{ 1}}版本...因此在这个的情况下我们很好:我们可以重新提取HEAD
版本。)
不幸的是,如果我们将其拼写为:
HEAD
然后Git将其视为我们输入的内容:
git checkout - f1 f2 f3
表示通过reflog查找上一个分支,然后将该分支提示中的文件提取到索引中,然后再导入工作树。 这会覆盖我们打算恢复的索引版本(除非这些&#34;旨在恢复&#34;版本与之前的分支版本相匹配)。
有一种方法可以恢复索引中的唯一版本,但这非常痛苦:运行git checkout @{-1} f1 f2 f3
,然后搜索Git写入{的哈希命名文件{1}}。可能有很多(实际数量取决于存储库中存在的悬空blob的数量)。其中三个 - 但没有告诉哪个三个没有仔细检查每个恢复的blob文件 - 我们的三个版本的文件git fsck --lost-found
,.git/lost-found/other
和{{1我们想要回来的。
我经常认为f1
应该至少有两个,可能是三个或更多个单独的命令:
f2
总是安全的,因为它永远不会覆盖任何文件;只有f3
会有危险。git checkout
。你可以使用它代替git checkout foo
。它是一个管道命令,所以它不是面向用户,更难以使用。)这个可能也许也是git checkout --force foo
,虽然它有点危险,因为它可以覆盖工作树工作,这是{{ {1}}做了,不做。前端瓷器git checkout-index
可能是正确的名称。git checkout
或某些此类),即使它是危险的&#34; (覆盖现有文件和/或索引条目),很明显我们不会使用&#34; safe&#34;各种git checkout
。 tree-ish 在这里不是可选的,因此更难以犯git checkout
vs git co-index
错误(这就是为什么它可能应该是git co-tree
)的单独命令。但这不是我们所拥有的。