我有一个分支A
,在其中进行了一些更改a
,然后我从B
创建了一个新分支A
,以继续进行一些更改{ {1}},因此b
中的总更改为B
。最后,其他人将他们的更改a, b
合并到master中,因此工作树现在如下所示:
c
然后,我将- c (master)
\
- a (A) - b (B)
改成Master,将更改从A
更改为a
,并强行将其推到分支a'
,因此工作树如下所示:>
A
问题
如何将- c (master) - a' (A)
\
- a - b (B)
重新设置为B
,以便仅更改新更改A
,然后工作树如下所示:
b
如果我在- c (master) - a' (A) - b' (B)
上尝试git rebase origin/A
时,它会尝试针对B
来解决a
的提交,我不希望这样做,因为我担心它将创建一个新的提交c, a'
,然后工作树将如下所示:
a''
有没有办法现在仅对变更- c (master) - a' (A) - a'' - b' (B)
进行基准调整? (我曾经有过OFC试图用Google搜索它,但是我没有找到任何具体可以解决这种情况的东西)
编辑:
我尝试在b
上挤压a'
和b
,但这甚至更糟,因为现在B
的所有更改都被记录为冲突。为了说明这一点,假设我:
b
中添加了新行l1
。a
中将该行更改为l2
。b
中未触碰此行。c
中添加了l1
,但在废止的提交a'
中添加了l2
。答案 0 :(得分:1)
git rebase --onto A a B
--onto A
使用A
作为新基础。 a B
获得一组类似git log a..B
的提交,在您的情况下,该提交仅包含b
。提交集将应用于新的基础。
您始终可以使用interactive rebase
处理简单或复杂的案件。
git rebase -i A
在编辑页面上,将pick
行中的前导drop
修改为a
,或简单地删除整行。保存并退出。
如果git rebase
不起作用,您也可以尝试git cherry-pick
仅应用所需的提交,然后将B
重置为新的标题。
git checkout -b tmp A
git cherry-pick b
git checkout B
git branch B_bak
git reset tmp --hard
git branch -D tmp
如果出现任何问题,可以运行git checkout B && git reset B_bak --hard
来还原B
。
答案 1 :(得分:0)
如何将
B
改成A
,以便仅更改新更改b
?
您可以轻松地做到:
git rebase A B
这与说“ 切换到分支B
并将其重新建立在A
之上”相同。 Git不会重新应用提交a
,因为它可以确定a'
已经引入了相同的更改。
当两个不同的提交(即具有不同的SHA-1
散列的提交)引入相同的一组更改时,它们被称为与补丁等效。
您可以通过使用--cherry-pick
的git log
选项来确定两个分支之间哪些提交等同于补丁:
--cherry-pick
当提交集受到对称差异限制时,请忽略任何与“另一端”的另一次提交引入相同更改的提交。
如果您这样做,则:
git log --oneline --cherry-pick --left-right A...B
您将看到提交a'
和a
被排除在输出之外,因为它们与补丁等效。 1
当您将B
置于A
之上时,Git cherry-picks 来自B
的提交并将其应用于A
之上一次一个。提交与现有更改相同的更改时,只需跳过该更改并移至下一个。
1 ...
表示法(也称为triple dot)从两个引用中的一个引用中选择一个提交,但是两个引用都不是。从共同的父级开始,选择两个不同分支中的“新”提交很有用。
答案 2 :(得分:0)
事实上,我发现了这篇文章:RECOVERING FROM UPSTREAM REBASE,但我还没有尝试过。
编辑:经过大量研究,正确答案是:
git checkout B
git rebase --onto A a
有关说明,请参见I can't understand the behaviour of git rebase --onto。
答案 3 :(得分:0)
告诉基地重新寻找过去新基地的尖端并从那里开始:
git rebase --fork-point A
并且如果您当前分支的上游已设置,则该分支和--fork-point
选项都是默认值,因此您的命令为
git rebase