Как добиться упрощенного объединения слиянием - PullRequest
0 голосов
/ 16 января 2020

Рационально: в нашей среде проверка выполняется в филиале, который здесь обозначается master>. Я бы хотел, чтобы squa sh (лучше: объединить) фиксировал вместе, чтобы все изменения в одном шаге развития были вместе. Таким образом:

Как мне пройти слева направо?

                                                   master> * C <feature  
                                                           |\
            * H <feature   - just local                    | * H     (merged)
            |                                              | |
            * G     - pushed to remote          =??=>      | * G     (merged)
master> B * |       - pushed to remote                   B * |
          | * F     - pushed to remote                     | * F     (merged)
          |/                                               |/
          *                                              A *                

На самом деле количество коммитов на пути к функциям велико (10+), и я бы хотел набрать sh их всех. Части их уже опубликованы в удаленном хранилище (и не должны быть изменены или изменены). Однако я просто хочу создать один единственный коммит в основной ветке.

git merge --squash, очевидно, выполняет это, но не помечает коммиты как объединенные. Таким образом, если я продолжу работу над <feature -Branch, следующий вызов git merge приведет к множеству конфликтов. Я нашел объяснение для stackoverflow : git merge --squash приводит к патчу, не связанному с исходными коммитами.

Итак, что я хочу добиться - это перейти справа налево и все коммиты в Featurebranch (F, G и H) будут помечены как объединенные *) - если я продолжу работать над Featurebranch, следующее объединение не приведет к конфликтам с моими собственными изменениями. Этот Вопрос решается, если все Изменения в Featurebranch не опубликованы в удаленном репозитории (см. git merge --squash -Question ).

PS: Конечно, было бы достаточно отметить отдельные коммиты как слитые, но я не знаю, как это сделать, и как git управляет информацией о слиянии.

PSS: Нормальный merge делает это, но не работает, если нет фиксации на master.

*): «помечено как объединенное» означает, что в gitk - если вы выберете коммит, список ветвей содержит функцию, remotes / Происхождение / функция, мастер, пульты / происхождение / мастер. В результате эти коммиты не будут учитываться при последующем вызове git merge.

Ответы [ 3 ]

2 голосов
/ 17 января 2020

Нет способа сделать то, что вы хотите.

Когда Git выполняет слияние, он вычисляет базу слияния, которая составляет примерно общий коммит предков обоих ветви. Три (и только) три точки, рассматриваемые в типичном слиянии, - это основа слияния и две головы. Если вы выполните обычное слияние, то вы создадите новый коммит в основной ветви, и этот коммит или один из его потомков обычно будут использоваться в качестве базы слияния в будущем, что означает, что Git не учитывает ваш изменяется во второй раз.

Если вы выполняете слияние sh, то база слияния является исходной точкой разветвления, поэтому при последующих слияниях вы увидите, что вы сделали несколько коммитов с одинаковыми изменениями, что вызывает конфликты, подобные вам '

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

Что вы Можно удалить существующую ветку и воссоздать ее из ветви master (или просто сбросить до последней фиксации на master), что будет означать, что будущая работа будет основана на фиксации, включая всю предыдущую работу. Это позволит избежать конфликтов.

Вы также можете использовать стандартное слияние вместо слияния sh, которое позволит обнаружению базы слияния делать правильные вещи.

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

Но в конечном итоге, учитывая ваши ограничения рабочего процесса, вариантов не так много. тебе. Я лично предлагаю другой, более стандартный рабочий процесс с меньшими ограничениями; логические, независимые коммиты; и стандартная политика слияния.

0 голосов
/ 27 января 2020

После некоторого исследования я узнал следующее: git выберет метод слияния, основанный на состоянии вовлеченных ветвей - в тривиальном ( рисунок b) из моего эскиза ниже ) git выбирает fast-foreward , то есть, когда изменяется только одна из двух ветвей. В этом случае может случиться так, что все изменения из ветки feater будут помещены поверх главной ветви.

Off-topi c: если есть изменения в более чем одной из вовлеченных ветвей ( рисунок a) из моего эскиза ниже ) git выбирает merge-Strateg ie в соответствии с текущим состоянием задействованных веток и конфигурацией git. Кроме того, вы выполняете миграцию с использованием командной строки для принудительного применения определенного поведения (https://git-scm.com/docs/merge-strategies или http://gitbu.ch/ch03.html).

С этим знанием есть ответ на мои вопросы:

Ответ: пользу --no-ff более --squash Если я когда-нибудь захочу избежать "перемотки вперед" объединить, вы должны использовать

git merge --no-ff --no-commit feature

, и после этого вы должны синхронизировать функцию с основной

git checkout feature
git merge --ff-only master

, это приведет вас слева направо от эскиза в вопросе И каждый оригинал коммита, сделанный в ветвь feature будет помечена как присутствующая в ветке master (эта информация отображается в gitk, когда вы выбираете коммит).

Возможно, есть и другая причина, чтобы избежать "fast-foreward": Достигнутая ситуация документирует, какие изменения первоначально регистрируются в Feature-Branch и которые выполняются в main-Branch.

Эскиз для быстрой иллюстрации вперед:

    a) real merge                          b) trivial - no chanes on master

                * H <feature                           * H <feature
                |                                      |
                * G <feature/origin                    * G  <feature/origin
    master> B * |                                      |
              | * F                                    * F 
              |/                                      /
              *                            master> A *                

a) - это обычный случай, когда обе стороны принимают меры, когда для их решения используется mergestrategi. b) является тривиальным случаем, когда возможен быстрый переход вперед.

Сводка: В любом случае данные команды объединяют весь рабочий коммит в ветви feature в один коммит в master без потери информации о слиянии.

0 голосов
/ 16 января 2020

Ваши описания (и изображение, и ваши слова) требуют регулярного слияния:

git checkout master
git merge feature

Если это не то, чего вы хотите, и вы настаиваете на сжатом коммите, то вы не можете продолжить свою работу над ветвь feature, но должна ветвиться новая ветвь функций из master, как только она получит старую ветвь функций, объединенную с squa sh.

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