Как я могу сделать git-слияния таким образом, чтобы их было легко откатить? - PullRequest
9 голосов
/ 20 января 2011

Существует много разговоров о том, как нелегко "отменить" слияние в git. Краткая версия: если вы отменяете коммит слияния, он также говорит git никогда не сливать эти изменения в будущем.

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

редактировать

Я видел решение в этой статье и на самом деле не считаю его решением, скорее объяснением проблемы. Требуется

  1. всегда используйте --no-ff
  2. помните все ваши отмены слияний, когда вы хотите вернуть код, который зависит от них (это может быть несколько часов, дней, недель или месяцев в будущем ...)

что я хочу

Вот как это работает в Subversion. Допустим, у меня есть ветка под названием «релиз-кандидат», которую мы запускаем на промежуточном сервере и где опробуем функции. Допустим, я сливаюсь в ветке A. В Subversion это все один набор изменений, и вся история для всех файлов объединяется. Допустим, нам это не нравится, поэтому мы хотим его убрать. Мы просто отменяем этот единственный набор изменений, и больше не нужно ни о чем думать. Мы можем объединить ветвь объектов A в любое время в будущем, не забывая о том, что в какой-то момент мы слили ее и вынули.

Я бы хотел быть в состоянии максимально приблизиться к этому потоку. Я хотел бы оптимизировать для того, чтобы «не вспоминать вещи в будущем», даже если это заставляет вещи делать больше шагов в пути. (это может быть невозможно ...)

1 Ответ

11 голосов
/ 20 января 2011

UPDATE:

Рабочий процесс, облегчающий работу с ответвлениями, представлен здесь: http://dymitruk.com/blog/2012/02/05/branch-per-feature/


(SVN часть вопроса была дана в конце)

Да, вот как вы снова вводите функцию, которую вы раскрыли. Рассмотрим следующую историю (предполагается, что вы «отменили» слияние):

x---x----x--x---x--M--U--L
     \            /
      x--x--x--x-F

F - это ветвь объекта, M - это слияние, U - противоположность, когда вы сливаете эту функцию, L - последний коммит.

Вот ваш выбор:

  1. вернуть U (нет --force необходимо нажать):

    x---x----x--x---x--M--U--L--^U
        \            /
         x--x--x--x-F
    
  2. переместите F на L (а затем объедините --ff-only F') (нет необходимости нажимать --force):

    x---x----x--x---x--M--U--L
         \            /       \
          x--x--x--x-x         x'--x'--x'--x'--F'
    
  3. перебазировать F на L (а затем объединить --no-ff F' - сохраняет вашу новую точку ветвления) (нет - необходимо принудительно нажать):

    x---x----x--x---x--M--U--L-------------------M2
         \            /       \                 /
          x--x--x--x-x         x'--x'--x'--x'--F'
    
  4. rebase -i head^^ и исключить U из списка (необходимо нажать --force) :

    x---x----x--x---x--M--L
         \            /
          x--x--x--x-F
    
  5. rebase --onto M^1 L^ L чтобы избавиться от слияния и слияния. Теперь вы можете вернуться к F позже.

                      L'
                     /
    x---x----x--x---x--M--U--L
         \            /
          x--x--x--x-F
    

Чтобы уничтожить все коммиты функций, используйте модификатор --squash при первоначальном слиянии. Я позволю вашему воображению работать над тем, как это будет выглядеть в истории. Есть причина, по которой я не рекомендую это делать. Важно знать, как работает функция и какие шаги она предприняла. Последующие слияния будут проще, поскольку Git может изучить историю того, почему определенный файл выглядит так. Сокращение коммитов вместе теряет эту информацию.

Существуют дополнительные недостатки, которые могут повлиять или не повлиять на вашу способность воспользоваться историей перевоплощений.

То, что я рекомендую, всегда отмечать то, что высвобождается, пустым слиянием в master Это делается путем слияния с опцией --no-ff. Вы никогда не работаете над мастером, и единственные коммиты, которые выполняются, это слияния - без изменений кода. В ветке QA вы отмечаете коммит, который отмечает точку, в которой вы выпустили. Поэтому, когда вы выполните git merge --no-ff rc-12.2, вы автоматически сгенерируете комментарий коммита «merged rc-12.2».

Проверьте git-flow.

Надеюсь, это даст вам больше деталей.

...