Git 从先前的提交分支并从 master 拉取更改

Git branch from a prev commit and pull changes from master

假设我做出了以下承诺。 所有提交都在同一个分支中。在 Commit 3 中,我删除了 C,现在我需要将 C 添加回当前

Commit 1: A,
Commit 2: A, C 
Commit 3: A, 
.
.
.
Master (current) : A, B, D

现在,我想用 A、B、C 和 D 创建一个分支。 这是我试过的。

  1. 在提交 2 时创建本地和远程分支

    git 结帐分支 mybranch hashtag-of-commit2

  2. 从 origin/master(当前)中提取更改以添加 B 和 D

    git 查看 mybranch

    git 获取来源

    git合并origin/master

这样做,它删除了C并添加了B和D。最终结果是A,B,D。我想要的是A,B,C和D。我该怎么做?

这就是我认为问题的意思,在更传统的布局中,将字母更改为数字,将数字更改为字母。

日志(单分支)是这样的

---A---B---C---D--- .... ---- HEAD master
       +x  -x

提交 B 添加 x 并且提交 C 恢复该更改。 OP 想重新添加 x

假设你在 master 上(即已经有提交 D .. master 引入的更改),初步看来 git revert sha-1-of-C 应该这样做,即你正在恢复提交恢复了原来的变化。

我不明白这与远程分支有什么关系。

整个 git revert 也会还原 Commit3 中引入的对 A 的更改,所以这不是您想要的。

要将文件 C 恢复到 Commit2 中的状态,您不仅有一个选择:

1。简单显示C

的状态

git show 显示某个版本的文件内容。所以

git show Commit2:C > /path/to/C  

将打印文件 C 的内容并将其存储在 /path/to/C 中。我们仍然需要将它再次添加到索引中:

git add /path/to/C && git commit -m "restoring C"

2。部分还原提交

我们知道 CCommit3 中以我们不希望的方式进行了更改。要从 Commit3C 中引入的更改创建补丁(即删除),我们可以使用 git diff

git diff Commit3~..Commit3 -- /original/path/to/C > c-changes.patch  

现在,c-changes.diff 保留引入的更改。现在,我们 apply this patch in reverse order 并恢复 C

git apply --reverse c-changes.patch  

C被恢复,重新加入索引:

git add /path/to/C && git commit -m "restoring C"

3。 Rebase 移除删除

当您使用前一个选项时,Commit3 仍会删除 C 并且您有一个额外的提交来恢复 C。如果自 Commit3 后您没有推送任何内容,我们可以编辑 Commit3 使其不再删除 C。首先,按照选项 2 中的说明创建补丁。然后,调用交互式 git rebase

git rebase -i Commit2

这将在您的 $EDITOR 中弹出一个对话框。您会看到 Commit3。选择 e 编辑提交,保存文件并关闭文件。然后,变基将开始,并在应用 Commit3 后立即停止。现在获取您的补丁并以相反的顺序应用它:

git apply --reverse c-changes.patch

已应用补丁,现在我们修改最后一次提交并从历史记录中删除 C 的删除:

git add /path/to/C && git commit --amend -C HEAD && git rebase --continue  

Rebase 在此之后继续进行,一旦完成,您将拥有一个新的历史记录,其中 C 从未消失。