Ответ 1
Хорошо, поэтому я понял это. Это была двуединая проблема. Прежде всего, мое дерево выглядело так:
У меня была фиксация в моем дереве, которая касалась src/dirA
, но еще не была нажата, когда repoB/branchA
уже был включен.
Я обнаружил, что git subtree pull
не найдет правильную базу, потому что ищет общего предка, поэтому он использовал версию, когда я последний раз объединил деревья, т.е. когда я сначала набрал git subtree add
.
Теперь, чтобы решить проблему общего предка, нужно git subtree split --rejoin
, который выполняет поверхностное слияние, поэтому git снова находит правую базу, то есть после того, как коммиты переместились с repoA
на repoB/branchA
.
Однако, как вы можете видеть в моем случае, git subtree split --rejoin
, за которым следует git subtree pull
, не решает моих проблем:
В связи с тем, что git subtree split
создает синтетическую историю всех фиксаций, которые касаются src/dirA
независимо от того, были ли они нажаты, суммы SHA-1 расходятся. Я разделил синтетическую историю на свою собственную ветвь split
для демонстрационных целей.
git subtree pull
, конечно, будет успешным после git subtree split --rejoin
. Однако следующий git subtree push
завершится неудачно, потому что истории repoB
и синтетического дерева после этого полностью различаются.
Поэтому мне пришлось вернуться назад, чтобы оскорбить неподдерживаемую фиксацию и вытащить изменения в мою ветку оттуда. Это осложняется тем, что git subtree split --rejoin
по-прежнему необходимо, потому что git subtree pull
через git merge
все еще не может определить правильную базу самостоятельно.
Итак, способ, которым я в настоящее время разрешил свою проблему, состоял в том, чтобы проверить фиксацию непосредственно перед неподтвержденным фиксатором src/dirA
. Затем я сделал git subtree split --rejoin
, а затем git subtree pull
. Это, конечно, добавляет два слияния в мое основное дерево, что я не мог понять, как сквоивать в одно слияние, и из того, что я читаю в исходном коде, похоже, это не простое решение этой проблемы.
После успешного git subtree pull
я переустановил оставшиеся коммиты из ветки master
на master_fix
. Теперь суммы SHA-1 соответствуют всей общей истории repoA/master_fix
и repoB/branchA
.
Это, конечно, имеет обычные недостатки rebase: если кто-то другой работал над master
, их история будет разрушена git branch -m master_fix master
.