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在计算要恢复的差异时使用的算法需要这样做
任何以后的提交都不会修改被还原的行。
在以后的历史中没有任何其他“相邻”提交。
“相邻”的定义基于上下文差异的默认行数,即3。如果'myfile'是这样构造的:
$ cat >myfile <<EOF
line 1
junk
junk
junk
junk
line 2
junk
junk
junk
junk
line 3
EOF
$ git add myfile
$ git commit -m "initial check-in"
1 files changed, 11 insertions(+), 0 deletions(-)
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
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
1 files changed, 1 insertions(+), 1 deletions(-)
$ git revert d6cbb19
Finished one revert.
[master 2db5c47] Revert "changed line 2"
1 files changed, 1 insertions(+), 1 deletions(-)
然后一切都按预期工作。
第二个答案非常有趣。有一个尚未正式发布的特性(尽管在Git v1.7.2-rc2中可用)称为恢复策略。你可以像这样调用git:
Git revert—strategy resolve <commit>
它应该能更好地理解你的意思。我不知道可用的策略列表是什么,也不知道任何策略的定义。
我有一个简单的解决方案,使用补丁恢复您所有的更改。
检查当前的主要分支机构(例如开发)
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"