只是一个评论:
git revert aCommit
确实恢复所有提交(如“提交的所有文件部分”):
它计算一个反向补丁,将其应用于 HEAD 并提交。
所以这里有两个问题(第一个很容易解决):
- 它总是提交,因此您可能需要添加
-no-commit
选项:“ git revert --no-commit aCommit
”:这在将多个提交的效果连续恢复到您的索引时很有用。
- 它不适用于特定文件(如果您的 a.py 是提交的一部分,并且您可能不想恢复 1000 个其他更改)?
为此,如果您想像在另一个提交中一样提取特定文件,您应该看到git-checkout
,特别是git checkout <commit> <filename>
语法(尽管在这种情况下,这并不是您所需要的)
Easy Git (Elijah Newren) 试图为Git 邮件列表带来更“完整的还原” ;但没有多大成功:
人们偶尔想要“还原更改”。
现在,这可能是:
- 32 和 29 版本之前的变化,
- 可能是自上次提交以来的所有更改,
- 可能是自 3 次提交以来的更改,或者
- 它可能只是一个特定的提交。
- 用户可能希望将此类还原子集化为特定文件,
(eg revert
在此处记录,但我不确定它是否是当前发行版的一部分,尽管如此)
但这最终归结为“还原更改”。
eg revert --since HEAD~3 # Undo all changes since HEAD~3
eg revert --in HEAD~8 # much like git revert HEAD~8, but nocommit by default
eg revert --since HEAD foo.py # Undo changes to foo.py since last commit
eg revert foo.py # Same as above
eg revert --in trial~7 bar.c baz. # Undo changes made in trial~7 to bar.[ch]
这些类型的“恢复数据”是否真的如此不同以至于需要不同的命令,或者简单的恢复命令不应该支持其中一些操作?
当然,大多数用户大部分时间可能会使用“ eg revert FILE1 FILE2...
”形式,但我没有看到支持额外功能的危害。
另外……有什么基本的东西可以阻止核心 git 采用这种行为吗?
以利亚
revert
注意:默认情况下,提交对通用命令没有意义,并且“ git revert REVISION
”会错误地显示指令(告诉用户添加 --in 标志)。
假设您有 50 个提交的文件,有 20 个文件您意识到旧的提交 X 引入了不应该发生的更改。
一个小管道是为了。
您需要的是一种列出您需要恢复
的所有特定文件的方法
(如“取消提交 X 中所做的更改,同时保留所有后续更改”),
然后,对于每个文件:
git-merge-file -p a.py X X^
这里的问题是恢复丢失的功能,而不会删除您可能想要保留的 a.py 中的所有后续更改。
这种技术有时被称为“负合并”。
由于表示:包含从to导致的所有更改,因此您可以通过说要合并所有更改来恢复已删除的功能。)git merge-file <current-file> <base-file> <other-file>
<base-file>
<other-file>
<current-file>
- 来自:X(函数已被删除的地方)
- to: X^(X 之前的上一次提交,该函数仍然存在)
注意:' -p
'参数允许您在不对当前文件执行任何操作的情况下首先查看更改。确定后,删除该选项。
注意:并不是git merge-file
那么简单:您不能像那样引用文件的以前版本。
(您会一遍又一遍地收到令人沮丧的消息:) error: Could not stat X
您
必须:
git cat-file blob a.py > tmp/ori # current file before any modification
git cat-file blob HEAD~2:a.py > tmp/X # file with the function deleted
git cat-file blob HEAD~3:a.py > tmp/F # file with the function which was still there
git merge-file a.py tmp/X tmp/F # basically a RCS-style merge
# note the inversed commit order: X as based, then F
# that is why is is a "negative merge"
diff -u a.py tmp/ori # eyeball the merge result
git add a.py
git commit -m "function restored" # and any other changes made from X are preserved!
如果要对先前提交中的大量文件执行此操作...一些脚本是有序的;)