Подтвердить что ты не робот

Слияние ветки ветки после первой ветки раздавливается при объединении с мастером

Вот рабочий процесс, который я обычно рассматриваю на работе.

git checkout -b feature_branch
# Do some development
git add .
git commit
git push origin feature_branch

В этот момент ветвь функции просматривается у моих коллег, но я хочу продолжать разрабатывать другие функции, зависящие от feature_branch. Итак, пока feature_branch находится в обзоре...

git checkout feature_branch
git checkout -b dependent_branch
# Do some more development
git add .
git commit

Теперь я вношу некоторые изменения в ответ на обзор кода на feature_branch

git checkout feature_branch
# Do review fixes
git add .
git commit
git checkout dependent_branch
git merge feature_branch

Теперь у нас возникают проблемы. У нас есть политика squash на master, а это означает, что ветки функций, которые объединены в master, должны быть сжаты в один commit.

git checkout feature_branch
git log # Look for hash at beginning of branch
git rebase -i  first_hash_of_branch # Squash feature_branch into a single commit
git merge master

Все круто, кроме dependent_branch. Когда я пытаюсь переустановить зависимую ветвь на master или пытаюсь объединить в нее мастер, git путается переписанной/сжатой историей и в основном отмечает каждое изменение в depedendent_branch как конфликт. Это PITA, чтобы пройти и в основном повторить или де-конфликтовать все изменения в dependent_branch. Есть ли какое-то решение? Иногда я вручную создаю патч и применяю его к новой ветке мастера, но если есть какие-то реальные конфликты с этим, еще хуже, чтобы исправить.

git checkout dependent_branch
git diff > ~/Desktop/dependent_branch.diff
git checkout master
git checkout -b new_dependent_branch
patch -p1 < ~/Desktop/dependent_branch.diff
# Pray for a clean apply.

Любые идеи? Я знаю, что это происходит из-за переписанной истории во время сквоша, но это требование, которое я не могу изменить. Какое лучшее решение/обходное решение? Есть ли какая-то магия, которую я могу сделать? Или существует более быстрый способ выполнить все шаги, связанные с ручным созданием diff?

4b9b3361

Ответ 1

Немного о том, почему это происходит:

Я дам O быть "оригинальным мастером" и FB быть "новым мастером", после того, как ветвь функции была объединена в:

Скажите feature_branch выглядит так:

O - A - B - C 

dependent_feature содержит несколько дополнительных коммитов:

O - A - B - C - D - E - F

Вы объединяете свою оригинальную ветку функций в мастер и выкапываете ее, давая вам:

O - FB

Теперь, когда вы пытаетесь переустановить зависимую ветвь, git попытается выяснить общий предок между этими ветвями. Хотя изначально был C, если вы не раздавили коммиты вниз, git вместо этого находит O в качестве общего предка. В результате git пытается воспроизвести A, B и C, которые уже содержат в FB, и вы получите кучу конфликтов.

По этой причине вы не можете действительно полагаться на типичную команду переадресации, и вы должны быть более явным образом, предоставляя параметр --onto:

git rebase --onto master HEAD~3  # instruct git to replay only the last
                                 # 3 commits, D E and F, onto master.

Измените параметр HEAD~3, необходимый для ваших веток, и вам не придется иметь дело с любым избыточным разрешением конфликта.

Некоторый альтернативный синтаксис, если вам не нравится указывать диапазоны, и вы еще не удалили свою исходную ветвь функции:

git rebase --onto master feature_branch dependent_feature

                                 # replay all commits, starting at feature_branch
                                 # exclusive, through dependent_feature inclusive 
                                 # onto master

Ответ 2

Я искренне не согласен с политикой "mash every feature development down into one commit", но это их вызов...

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

Ответ 3

В этом конкретном случае кажется, что вы "знаете", что только сжатая работа ветки, с которой вы первоначально работали, была помещена в мастер.

Таким образом, вы можете с радостью объединиться, сохраняя свои изменения каждый раз, когда есть конфликт. Для этого есть опция:

git merge -Xours master

Подробнее см. https://git-scm.com/docs/git-rebase.