http://norbauer.com/notebooks/code/notes/git-revert-reset-a-single-file
我发现了一篇文章。
但是仍然不知道以下两个命令的区别:
git checkout <filename>
git checkout -- <filename>
在什么情况下应该分别使用第一个和第二个命令?
http://norbauer.com/notebooks/code/notes/git-revert-reset-a-single-file
我发现了一篇文章。
但是仍然不知道以下两个命令的区别:
git checkout <filename>
git checkout -- <filename>
在什么情况下应该分别使用第一个和第二个命令?
特殊的“选项”--
意味着“将此点之后的每个参数视为文件名,无论其外观如何”。这不是Git特有的,而是一般Unix命令行约定。通常情况下,您使用它来说明参数是文件名而不是选项,例如:
rm -f # does nothing
rm -- -f # deletes a file named "-f"
git checkout
1也可以使用--
,表示后面的参数不是可选的 "treeish" 参数,该参数用于指定您想要的提交。
因此,在这种情况下,始终使用--
是安全的,但当您要恢复的文件名称以-
开头或与分支的名称相同时,您就需要使用它。以下是一些分支/文件消歧的示例:
git checkout README # would normally discard uncommitted changes
# to the _file_ "README"
git checkout master # would normally switch the working copy to
# the _branch_ "master"
git checkout -- master # discard uncommitted changes to the _file_ "master"
并且选项/文件消歧:
git checkout -p -- README # interactively discard uncommitted changes
# to the file "README"
git checkout -- -p README # unconditionally discard all uncommitted
# changes to the files "-p" and "README"
如果你有一个以-
开头的分支,我不确定该怎么做。也许最好一开始就不要这样做。
1在这个模式下,“checkout”还可以做其他几件事情。我不明白为什么git选择将“放弃未提交的更改”作为“checkout”子命令的一种模式实现,而不是像大多数其他版本控制系统那样实现“恢复”或者像我认为在git自己的术语中更合理的"reset"。
--
作为选项和参数之间的分隔符被广泛实现。它适用于任何使用POSIX getopt(3)
处理其命令行选项的程序/实用程序(请参见man 3 getopt
),使用getopt(1)
的shell脚本以及一些自己实现它的程序,但不能保证在所有情况下都能正常工作。 - arielf--
意味着“否定更改”,就像 C/C++ 一样 - 从那以后我一直这么想。我的思维被震撼了! - underscore_d--
后面的任何内容都被视为文件名(而不是程序参数)。这一点非常重要,比如当你有以破折号开头的文件名时。
git checkout -- filename
将使用索引(暂存区)中的文件版本替换您在工作目录中拥有的版本。
git checkout filename
将尝试检出与同名的分支,如果不存在,则执行与 git checkout -- <filename>
相同的操作。
git checkout <filename>
和 git checkout -- <filename>
的区别在于如何处理未合并的更改。
git checkout <filename>
会放弃当前分支中的更改,并用指定分支或提交版本中的文件替换它。如果文件中有未合并的更改,则此命令将失败并显示错误消息。
git checkout -- <filename>
会放弃文件中的所有更改,包括任何未合并的更改。当您想要完全放弃本地更改并重新开始使用指定分支或提交版本的版本时,这非常有用。
总之,git checkout <filename>
用于切换到文件的特定版本,同时保留已合并到当前分支的更改,而 git checkout -- <filename>
则放弃文件中的所有更改,包括未合并的更改。