听起来你的历史记录是这样的:
...---o---A---o---...---o---o---B master
\
o---o---...---o---C verydifferentbranch
您说您担心如果强制推送verydifferentbranch
到master
,将会丢失历史记录。这样的操作相当于扔掉了从A
到B
之后的所有内容。
您可以通过合并它来保留历史记录,或者只需在被弃用的分支末尾放置一个标签并将其保留未合并即可。
使用合并
合并将允许您保留历史记录的两个方面:
...---o---A---o---...---o---o---B
\ \
o---o---...---o---C---M master
你所做的合并类型将决定为提交M创建的内容。在你的情况下,普通合并(使用
recursive
合并策略)似乎会产生大量冲突。如果你确实需要合并
A..B
提交中的更改,那么除了通过合并或变基解决所提出的冲突外,别无选择。(如果您能够更频繁地合并或变基以处理冲突,则在将来可能会遇到更少的问题。)但是,如果您只想让
M
具有与
C
相同的内容(即您想忽略由
A..B
提交表示的更改),则可以使用
ours
合并策略。
git-merge(1)描述了
ours
合并策略:
这解决了任意数量的头,但合并的结果树始终是当前分支头的树,有效地忽略了所有其他分支的更改。它旨在用于取代旁路的旧开发历史记录。请注意,这与递归合并策略的-Xours选项不同。
您可以像这样生成消息为
Merge commit 'abandoned/foo-features'
的M:
git tag -m 'describe reason for abandonment here...' \
abandoned/foo-features master
git checkout verydifferentbranch
git branch -M verydifferentbranch master
git merge -s ours abandoned/foo-features
git tag -d abandoned/foo-features
git push wherever master tag abandoned/foo-features
这些命令的变化将为您提供略有不同的自动提交消息,适用于
M
(您始终可以使用
git merge -m
提供自己的消息,或者在之后使用
git commit --amend
进行修改)。
主要问题是,生成的
master
将具有两个历史记录片段,但没有来自原始
master
侧的任何更改(这些更改仍然存在于历史记录中,只是它们未在由提交
M
引用的树中表示)。
悬而未决
如果“重写”
master
是可接受的(即不存在基于任何提交
A..B
的其他工作,或者涉及的用户不介意从重写中
恢复所需的工作),则可以在当前
master
的末端留下一个标签,并将
master
替换为
verydifferentbranch
。
...---o---A---o---...---o---o---B (tag: abandoned/foo-features)
\
o---o---...---o---C master
像这样安排:
git tag -m 'describe reason for abandonment here...' \
abandoned/foo-features master
git branch -M verydifferentbranch master
git push wherever +master tag abandoned/foo-features