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恢复——策略解析 如果commit是一个merge: 使用git revert——strategy resolve -m

其他回答

Git恢复——策略解析 如果commit是一个merge: 使用git revert——strategy resolve -m

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

我的情况:

% 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 rebase删除不需要的提交。 假设您将同事的topic分支的一些提交包含到您的topic分支中,但后来决定不需要这些提交。

git checkout -b tmp-branch my-topic-branch  # Use a temporary branch to be safe.
git rebase -i master  # Interactively rebase against master branch.

此时,文本编辑器将打开交互式rebase视图。例如

通过删除它们的行来删除您不想要的提交 保存并退出

如果改基不成功,删除临时分支并尝试其他策略。否则,请继续执行以下说明。

git checkout my-topic-branch
git reset --hard tmp-branch  # Overwrite your topic branch with the temp branch.
git branch -d tmp-branch  # Delete the temporary branch.

如果将主题分支推到远程,可能需要强制推,因为提交历史已经更改。如果其他人在同一个分支上工作,给他们提个醒。

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

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

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"

你的选择是

保留错误并引入修复 删除错误并更改历史记录。

您应该选择(1)如果错误的更改已被其他人拾取,以及(2)如果错误仅限于一个私有的未推送分支。

Git revert是一个自动执行(1)的工具,它创建了一个新的提交,撤销了之前的一些提交。您将在项目历史中看到错误和删除,但是从您的存储库中提取的人在更新时不会遇到问题。在你的例子中,它不是以自动的方式工作的,所以你需要编辑'myfile'(删除第2行),git添加myfile和git提交来处理冲突。然后,历史记录中将有四个提交,提交4将还原提交2。

如果没有人关心你的历史改变,你可以重写它并删除提交2(选择2)。最简单的方法是使用git rebase -i 8230fa3。这将使您进入一个编辑器,您可以通过删除提交来选择不包括错误的提交(并将“pick”放在其他提交消息旁边)。仔细研究一下这样做的后果。