我在脚本中进行了更改并提交了它.然后我做了一些其他更改,并将它们推送到远程存储库等.
然后我意识到我提到的第一个更改是愚蠢的,并且想要撤消它.我可以"取消应用"提交,而无需手动复制/粘贴差异吗?
举个例子:我有两个文件,a.py
并且b.py
:
Commit 1: I delete a function in a.py Commit 2: I change a few lines in b.py Commit 3: I change the docstring in a.py
我可以撤消该功能删除,并使其显示为"提交4"(而不是删除提交1)
是的,你可以使用git revert.有关详细信息,请参阅git手册部分.
要点是你可以说:
git revert 4f4k2a
其中4f4k2a是您要撤消的提交的ID,它将尝试撤消它.
只是评论:
git revert aCommit
确实恢复了所有提交(如"提交的所有文件部分"):
它计算反向补丁,将其应用于HEAD并提交.
所以这里有两个问题(第一个很容易解决):
它总是提交,所以你可能想要添加-no-commit
选项:" git revert --no-commit aCommit
":当连续将多个提交效果恢复到你的索引时,这很有用.
它不适用于特定文件(如果你的a.py是一个提交的一部分,你可能不希望还原1000个其他更改,那该怎么办?)
为此,如果你想提取特定文件,就像它们在另一个提交中一样,你应该看到git-checkout
,特别是git checkout
语法(虽然这不是你需要的)
Easy Git(Elijah Newren)试图为Git Mailing列表带来更"完整的恢复" ; 但没有太大的成功:
人们偶尔会想"恢复变化".
现在,这可能是:
之前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标志).
假设您已经知道旧的提交X引入了不应该发生的更改.
有点管道是有序的.
您需要的是一种列出您需要还原的所有特定文件的方法
(如"取消在提交X中进行的更改,同时保留所有后续更改"),
然后,对于每个文件:
git-merge-file -p a.py X X^
这里的问题是恢复丢失的功能而不删除您可能想要保留的a.py中的所有后续更改.
这种技术有时称为"负合并".
由于方法:整合了从导致所有更改,以进入,你可以恢复,说你想将所有的变化删除功能).git merge-file
from: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!
如果要对先前提交中的大量文件执行此操作...某些脚本按顺序排序;)