I was working with a friend on a project, and he edited a bunch of files that shouldn't have been edited. Somehow I merged his work into mine, either when I pulled it, or when I tried to just pick the specific files out that I wanted. I've been looking and playing for a long time, trying to figure out how to remove the commits that contain the edits to those files, it seems to be a toss up between revert and rebase, and there are no straightforward examples, and the docs assume I know more than I do.

下面是这个问题的简化版本:

给定下面的场景,我如何删除提交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.

当前回答

最近遇到了类似的问题,最后这样做,感觉更简单,可以在少数情况下工作。

我的情况:

% git log --oneline

4ad59d6 commit 3
f244533 commit 2
c5b4688 commit 1

我们要做的是创建commit 4,并将“commit 2”中的更改还原。这就是我们所做的:

获取commit 2中的更改: % git显示> ~/patches/commit.2.patch 恢复更改: % git应用-R ~/patches/commit.2.patch 创建新的提交: % git commit -Am“提交4:恢复提交2中的更改”

附注:这适用于我们可以轻松应用revert的情况-如果相同的代码行在一定时间内被修改了,这将不起作用。

其他回答

最近遇到了类似的问题,最后这样做,感觉更简单,可以在少数情况下工作。

我的情况:

% git log --oneline

4ad59d6 commit 3
f244533 commit 2
c5b4688 commit 1

我们要做的是创建commit 4,并将“commit 2”中的更改还原。这就是我们所做的:

获取commit 2中的更改: % git显示> ~/patches/commit.2.patch 恢复更改: % git应用-R ~/patches/commit.2.patch 创建新的提交: % git commit -Am“提交4:恢复提交2中的更改”

附注:这适用于我们可以轻松应用revert的情况-如果相同的代码行在一定时间内被修改了,这将不起作用。

有四种方法:

干净的方式,恢复,但保持日志恢复: Git revert—strategy resolve <commit> 严厉的方式,完全删除只有最后一个提交: git重置-软“头^”

注意:避免git重置——很难,因为它也会丢弃自上次提交以来文件中的所有更改。如果——软的不行,那就试试——混合的或者——保留的。

Rebase(显示最近5次提交的日志并删除你不想要的行,或重新排序,或将多个提交压缩在一个文件中,或做任何你想做的事情,这是一个非常通用的工具): git rebase -i HEAD~5

如果犯了错误:

git rebase --abort

快速rebase:只删除使用id的特定提交: Git rebase—to commit-id^ commit-id 替代方案:你还可以试试: Git选择commit-id 还有另一种选择: Git恢复——不提交 作为最后的手段,如果你需要完全自由的历史编辑(例如,因为git不允许你编辑你想要的内容),你可以使用这个非常快速的开源应用程序:reposurgeon。

注意:当然,所有这些更改都是在本地完成的,你应该在git push之后将更改应用到远程。如果你的repo不想删除提交(“不允许快进”,当你想删除已经提交的提交时就会发生),你可以使用git push -f强制推送更改。

注2:如果在一个分支上工作,你需要强制push,你应该绝对避免git push——force,因为这可能会覆盖其他分支(如果你对它们做了更改,即使你当前的签出是在另一个分支上)。当你强制push时,最好总是指定远程分支:git push——force origin your_branch。

这里有一个简单的解决方法:

git rebase -i HEAD~x

其中x是提交的数量。

在提交之前输入drop:

就这样,完成了。如果您删除的提交已经在远程上,则必须强制push。因为——force被认为是有害的,所以使用git push——force-with-lease。

我有一个简单的解决方案,使用补丁恢复您所有的更改。

检查当前的主要分支机构(例如开发)

git checkout develop

在历史日志中查找你的commit-id,只签出你对一个新分支的更改:

git log
git checkout -b your-branch <your-commit-id>

在你的分支中查找,找到你想要恢复到的前一个状态:

git checkout -b prev-status <previous-commit-id>

创建一个补丁,可以恢复您的所有更改:

git diff your-branch..prev-status > reverts.patch
# the comparing order of branches is important

检查当前的头分支,并应用恢复补丁

git checkout origin develop
git apply reverts.patch
git add *
git commit -m "revert all my changes"

我能想到一个很简单的方法

git重置——hard HEAD <你的提交ID>

然后重置远程分支

Git push origin -f