我曾在两个分支上工作并混淆了一切。一些旨在应用于A分支的更改实际上被应用到了B分支,反之亦然。有些提交同时包含对正确分支和错误分支的更改。我进行了几次这种混合的提交。
后来我在正确的分支上再次进行了更改。所以我最终得到了所有的更改都在正确的分支中,但是每个分支上还有属于另一个分支的旧更改。然后我将A分支推送了出去,而B分支则已经发起了拉取请求。
问题1:如何从每个分支中删除不属于该分支的更改?我清楚地知道需要将哪些文件还原为原始状态。
问题2:如何更改已经发起的拉取请求?
我曾在两个分支上工作并混淆了一切。一些旨在应用于A分支的更改实际上被应用到了B分支,反之亦然。有些提交同时包含对正确分支和错误分支的更改。我进行了几次这种混合的提交。
后来我在正确的分支上再次进行了更改。所以我最终得到了所有的更改都在正确的分支中,但是每个分支上还有属于另一个分支的旧更改。然后我将A分支推送了出去,而B分支则已经发起了拉取请求。
问题1:如何从每个分支中删除不属于该分支的更改?我清楚地知道需要将哪些文件还原为原始状态。
问题2:如何更改已经发起的拉取请求?
为了以后的参考,推送前清理代码会更加安全。此时你有两个选择:
你可以创建新的分支(使用新名称),并将所需更改迁移到每个分支中。现有的分支最终将被废弃。
你可以“重写历史”来修复现有的分支。任何已经获取/拉取现有分支的人都必须执行恢复过程(请参见“git rebase”文档中的“从上游rebase恢复”的一般讨论)。
我将假设第一个选项较为安全,并编写此过程。如果你想使用历史记录重写,请注意如何调整此过程。我将演示如何处理branchA
,而branchB
的过程基本相同。我将假设该分支是从master
创建的(因此如果不是,请将所有引用master
的内容替换为适当的“父分支”)。
检出现有分支。
git checkout branchA
master
的末端,您需要找到分支点。为了简化说明,让我们在该点创建一个临时标签(尽管从技术上讲,您可以使用此提交的SHA1 ID代替)。x --- A --- x <--(master)
\
A1 --- B1 --- AB1 --- A2 <--(branchA)
你需要找到A
。如果你知道在branchA
从master
分离后有(在此示例中)4个提交,你可以说
git tag rootA branchA~4
git log --graph master branchA
(如果提交历史记录足够小,这是可行的)来估算它,否则:git rev-list master..branchA
git tag rootA 31337c0d3^
(注意末尾的^
)。
无论如何,现在你应该已经拥有了
[rootA]
|
x --- A --- x <--(master)
\
A1 --- B1 --- AB1 --- A2 <--(branchA)
git checkout -b new_branchA
git rebase -i --onto rootA master
branchA
的提交,请保留该行不变(使用pick
命令)。branchB
的提交-假设您已经在branchB
上进行了这些更改-您只需将命令从pick
更改为drop
。branchA
,另一些属于branchB
),请将命令从pick
更改为edit
。edit
,则git将暂停并提示您进行编辑,然后告诉它恢复重新设置基础。 [rootA]
|
x --- A --- x <--(master)
|\
| A1 --- B1 --- AB1 --- A2 <--(branchA)
\
A1' --- Ab1' --- A2' <--(new_branchA)
(其中Ab1'
是对AB1
进行编辑替换的结果,只保留了针对BranchA
的更改)。
如果您将其作为历史重写,则branchA
将指向A2'
,当然也不会有new_branchA
。
您可以清除临时标记。
git tag --delete rootA
如果你没有进行历史重写,那么你不再需要旧的branchA
:
git branch --delete branchA
git push
-f
选项。)如果您还没有推送这些分支,您可以:
tmpA
和tmpB
(例如从origin/A
和origin/B
)git cherry-pick
从A
到tmpA
,从B
到tmpB
中选择所需的提交;如果需要编辑提交,请使用选项--no-commit
,然后使用git reset
清除索引,接着使用git add -p
仅添加所需更改,最后提交结果A
重置为tmpA
(git branch -f A tmpA
),对于B
也是如此。tmpA
和tmpB
。--no-commit
选项的 git cherry-pick
。然后执行 git reset
,现在你可以使用 git add -p
只添加你需要的内容。一旦你添加了所需的文件(或文件的部分),就进行提交,并执行 git clean -fd
。 - VonC