Слияние двух очень расходящихся веток с помощью git? - PullRequest
6 голосов
/ 11 мая 2011

У меня есть master ветвь и мои verydifferentbranch они имели одного и того же предка ... около 300 коммитов назад.Теперь, когда verydifferentbranch завершена, я хочу поместить его под мастер branch.Выполнение перебазирования приводит к тому, что каждый патч имеет множество конфликтов слияния, так что сам по себе будет большой проект, чтобы пройти через все конфликты.

Я понятия не имею, что делать, кроме просто принудительноготолкая головку verydifferentbranch в master ветку.Я бы потерял всю свою историю, занимаясь этим, и я не хочу этого делать.

Какие у меня есть другие варианты?

Ответы [ 3 ]

10 голосов
/ 11 мая 2011

Похоже, ваша история выглядит следующим образом:

...---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

Тип слияния будет определять контент, созданный дляcommit M. Обычное слияние (используя стратегию слияния recursive) звучит так, как будто в вашем случае возникнет очень большое количество конфликтов. Если вам действительно нужно включить изменения из коммитов A..B, вам ничего не остается, кроме как работать с конфликтами, возникающими в результате слияния или перебазирования. (В будущем у вас, вероятно, будет меньшепроблемы, если вы можете объединять или перебазировать чаще, чтобы иметь дело с конфликтами по мере их возникновения.) Но, если вы просто хотите, чтобы M имел тот же контент, что и C (т.е. вы хотите игнорировать изменения, представленные A..B коммиты), тогда вы можете использовать стратегию слияния ours.

git-merge (1) описывает стратегию слияния ours:

Это разрешает любое количество головок, кромерезультирующее дерево слияния всегда является деревом текущего заголовка ветви, эффективно игнорируя все изменения из всех других ветвей.Он предназначен для замены старой истории развития боковых веток.Обратите внимание, что это отличается от опции -Xours для стратегии рекурсивного слияния.

Вы можете создать M с сообщением Merge commit 'abandoned/foo-features', например:

git tag -m 'describe reason for abandonment here...' \
    abandoned/foo-features master                   # tag abandoned branch tip
git checkout verydifferentbranch                    # checkout dominant branch
git branch -M verydifferentbranch master            # replace master
git merge -s ours abandoned/foo-features            # merge only other's history
git tag -d abandoned/foo-features                   # optional: delete the tag
git push wherever master tag abandoned/foo-features # publish them

Variations onэти команды дадут вам немного отличающиеся сообщения автоматической фиксации для M (вы всегда можете указать свое git merge -m или изменить его на git commit --amend впоследствии).

Суть в том, что получившийся master будет иметь оба фрагмента истории, но ни одно из изменений с исходной стороны master (эти изменения все еще находятся в истории, они просто не представлены в дереве, на которое ссылается коммит M).

Leave It Hanging

Если допустимо «переписать» 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                    # tag abandoned branch tip
git branch -M verydifferentbranch master             # replace master
git push wherever +master tag abandoned/foo-features # publish them
2 голосов
/ 11 мая 2011

Вот почему существует функциональность git merge.

$> git checkout master
$> git merge verydifferentbranch

Шансы - это первый раз, когда вы делаете это, будет много конфликтов (если они разошлисьвы утверждаете).Но если вы будете в курсе всех событий, после первоначального слияния это будет не так уж и плохо.

1 голос
/ 11 мая 2011

Почему вы сначала делаете ребаз? Это, вероятно, вызовет проблемы с вашими наборами изменений, так как ваши наборы изменений будут искать версии файлов, начиная с коммита, где вы отошли от master.

Вместо этого используйте git merge.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...