猿问

删除特定的提交

我和一个朋友一起在一个项目上工作,他编辑了一堆本不应该编辑的文件。我以某种方式将他的作品合并到我的作品中,无论是在我拉出它时,还是当我试图只选择想要的特定文件时。我一直在寻找和玩耍很长时间,试图弄清楚如何删除包含对这些文件所做的修改的提交,这似乎是在还原和变基之间的一次折腾,并且没有简单的示例,并且文档假定我比我知道的更多。


因此,这是问题的简化版本:


在以下情况下,如何删除提交2?


$ mkdir git_revert_test && cd git_revert_test


$ git init

Initialized empty Git repository in /Users/josh/deleteme/git_revert_test/.git/


$ echo "line 1" > myfile


$ git add -A


$ git commit -m "commit 1"

[master (root-commit) 8230fa3] commit 1

 1 files changed, 1 insertions(+), 0 deletions(-)

 create mode 100644 myfile


$ echo "line 2" >> myfile


$ git commit -am "commit 2"

[master 342f9bb] commit 2

 1 files changed, 1 insertions(+), 0 deletions(-)


$ echo "line 3" >> myfile


$ git commit -am "commit 3"

[master 1bcb872] commit 3

 1 files changed, 1 insertions(+), 0 deletions(-)

预期的结果是


$ cat myfile

line 1

line 3

这是我一直尝试还原的示例


$ git revert 342f9bb

Automatic revert failed.  After resolving the conflicts,

mark the corrected paths with 'git add <paths>' or 'git rm <paths>'

and commit the result.


犯罪嫌疑人X
浏览 546回答 3
3回答

牛魔王的故事

Git在计算要还原的差异时使用的算法要求还原的行不会被以后的任何提交修改。历史上以后没有其他“相邻”的提交。“相邻”的定义基于上下文差异的默认行数,即3。因此,如果“ myfile”的构造如下:$ cat >myfile <<EOFline 1junkjunkjunkjunkline 2junkjunkjunkjunkline 3EOF$ git add myfile$ git commit -m "initial check-in"&nbsp;1 files changed, 11 insertions(+), 0 deletions(-)&nbsp;create mode 100644 myfile$ perl -p -i -e 's/line 2/this is the second line/;' myfile$ git commit -am "changed line 2 to second line"[master d6cbb19] changed line 2&nbsp;1 files changed, 1 insertions(+), 1 deletions(-)$ perl -p -i -e 's/line 3/this is the third line/;' myfile$ git commit -am "changed line 3 to third line"[master dd054fe] changed line 3&nbsp;1 files changed, 1 insertions(+), 1 deletions(-)$ git revert d6cbb19Finished one revert.[master 2db5c47] Revert "changed line 2"&nbsp;1 files changed, 1 insertions(+), 1 deletions(-)然后一切都按预期工作。第二个答案非常有趣。有一个尚未正式发布的功能(尽管它在Git v1.7.2-rc2中可用)称为恢复策略。您可以像这样调用git:git revert --strategy解决 <commit>并且应该可以更好地弄清您的意思。我不知道可用策略的清单是什么,也不知道任何策略的定义。

回首忆惘然

有四种方法:干净的方法,还原但保留日志中的还原:git revert --strategy resolve <commit>严厉的方式,只删除最后一次提交:git reset --soft "HEAD^"注意:避免使用,git reset --hard因为它还会丢弃自上次提交以来文件中的所有更改。如果--soft不起作用,请尝试--mixed或--keep。重新设置基准(显示最近5次提交的日志,并删除不需要的行,或者重新排序或将多个提交压缩为一个,或者执行其他任何想要的操作,这是一个非常通用的工具):git rebase -i HEAD~5如果犯了一个错误:git rebase --abort快速变基:使用其ID仅删除特定的提交:git rebase --onto commit-id^ commit-id替代方法:您也可以尝试:git cherry-pick commit-id另一个选择:git revert --no-commit作为最后的选择,如果您需要完全的历史记录编辑自由(例如,由于git不允许您编辑想要的内容),则可以使用此非常快速的开源应用程序:reposurgeon。注意:当然,所有这些更改都是在本地完成的,git push此后您应该将更改应用到遥控器。并且如果您的仓库不想删除提交(“不允许快速转发”,当您想删除已经推送的提交时会发生这种情况),您可以git push -f用来强制推送更改。注意2:如果在分支上工作并且需要强制执行推送,则应绝对避免,git push --force因为这可能会覆盖其他分支(如果您在其中进行了更改,即使您当前的结帐在另一个分支上)。强制推送时,总是选择指定远程分支:git push --force origin your_branch。

江户川乱折腾

您的选择介于保持错误并引入修复程序,并删除错误并更改历史记录。您应该选择(1)如果其他任何人都接受了错误的更改,则选择(2)如果错误仅限于未按下的私有分支。Git恢复是一种自动执行的工具(1),它会创建一个新的提交来撤消某些先前的提交。您将在项目历史记录中看到错误和删除,但是从您的存储库中提取信息的人员在进行更新时不会遇到问题。在您的示例中,它不是自动运行的,因此您需要编辑“ myfile”(删除第2行),执行git add myfile并git commit处理冲突。然后,您将在历史记录中获得四次提交,而提交4将还原提交2。如果没有人关心您的历史记录更改,则可以重写它并删除提交2(选择2)。最简单的方法是使用git rebase -i 8230fa3。这将使您进入编辑器,并且可以通过删除提交(并在其他提交消息旁边保持“ pick”)来选择不包括错误的提交。请仔细阅读这样做的后果。
随时随地看视频慕课网APP
我要回答