我想“撤消”对一个特定文件的所有本地更改,即在origin / master处返回此文件的状态:
git checkout origin/master -- path/to/file.txt
适用于已修改的文件,但特别是对于已添加但因此在origin / master中不存在的文件(“没有此类文件或目录”)而失败。
如果需要,我可以依赖提交只改变一个文件。 (那么也许我可以解析来自git log --follow --oneline --decorate origin/master.. path/to/file.txt
的SHA,然后还原(或重新设置/删除)这些提交。但这似乎是手动和hacky,我更喜欢更具声明性的解决方案......)
更新:为了澄清,已经提交了本地更改。可能有多个提交对文件进行了更改。
答案 0 :(得分:3)
我假设您已经在本地进行了所有更改...
我会这样做:
git reset HEAD~
git checkout path/to/file.txt
git add -A
git commit -m "commit message"
这也很容易作为脚本添加到bash / other shell中。
如果有多个提交对文件进行了更改,您可以执行以下操作:
git log -p path/to/file.txt
然后找到要将文件还原到的提交。然后,只恢复该文件:
git checkout <sha-from-above> path/to/file.txt
请参阅:Reset or revert a specific file to a specific revision using Git?
答案 1 :(得分:3)
除重命名问题外,您首先建议的一般方法(git checkout <rev> -- <path>
)是明显的正确方法。如果失败,则必须添加该文件,因此您只需将“失败”作为“删除指示”。
再次出现重命名问题。
在这里,您可以使用您建议的git log --follow
方法。关注,观看重命名操作,并收集它们。您可以使用--name-status
来观察重命名,例如:
$ git log --follow --oneline --name-status -- builtin/var.c
f9bc573 ident: rename IDENT_ERROR_ON_NO_NAME to IDENT_STRICT
M builtin/var.c
c2e86ad Fix sparse warnings
M builtin/var.c
2bc8c1a var: run setup_git_directory_gently() sooner
M builtin/var.c
81b50f3 Move 'builtin-*' into a 'builtin/' subdirectory
R100 builtin-var.c builtin/var.c
64778d2 Make 'git var GIT_PAGER' always print the configured pager
M builtin-var.c
9fabb6d Fix 'git var' usage synopsis
M builtin-var.c
55b6745 make "git var" a built-in
R096 var.c builtin-var.c
6361824 Teach git var about GIT_PAGER
M var.c
[snip]
(我在git源代码上运行了以上内容)。这里有一个相当大的打嗝,因为你必须知道文件的 new 名称,而不是旧名称,但也许这就是问题。
按照重命名后,您可以git checkout <rev> -- <path-by-name-at-the-time>
。 --name-status
部分还将显示文件是否在历史版本之前的转录中创建(状态将为A
,已添加),您将知道要删除该文件。
省略了“文件被删除”的情况,这与您知道文件新名称的基本想法相冲突。删除文件foo
后,它首先只有一个旧名称。
据我所知,没有好办法处理这最后一个案例。您可以假设,如果{“1}}存在于”旧“提交中并且您没有新名称,则必须将其删除;但是如果跟随重命名的想法是以旧名称开头,那么这在git中不起作用:foo
选项仅在从最近的历史记录开始并在时间上回溯时才有效。 / p>
答案 2 :(得分:2)
我设法用这些命令获得了我的预期结果:
$ git reset origin/master path/to/file.txt
$ git commit -m "undo changes to path/to/file.txt"
[master ab4553d] undo changes to path/to/file.txt
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 path/to/file.txt
$ git reset --hard
HEAD is now at ab4553d undo changes to path/to/file.txt
粗略测试后,这可以按预期添加/删除/修改文件。对于重命名的文件,需要为旧名称和新名称执行git reset
。
使用git reset
而不是git checkout
是否有不利之处?