Вытяните все фиксации из ветки, нажмите, чтобы зафиксировать фиксацию другого

У меня есть следующие ветки:

  • master
  • production

и следующие удаленные ветки:

  • origin/master
  • origin/production

У меня есть script, который извлекает ветвь origin/master и получает разницу в том, что изменилось с моей последней выборки (log -p master..origin/master). Затем я объединяю origin/master.

Обнаруженные коммиты переносятся в средство проверки кода.

Я хочу нажать успешные коммиты - и только они - на производственную ветвь, а затем, конечно, на origin/production.

Как я могу это сделать?

Кроме того, у меня есть 2 скрипта: тот, который извлекает из origin/master, push коммит детализирует в базу данных и объединяется, а другой, который я сейчас пишу, должен будет нажать успешные коммиты.

Я бы хотел, чтобы эти 2 скрипта работали, избегая условий гонки/слияния конфликтов. Поскольку я только хочу работать с указанными коммитами, может быть, есть способ избавиться от коммитов, которые мне не нужны?

Ответ 1

Термин, который, я думаю, вы ищете, - это "вишневый выбор". То есть, возьмите одну фиксацию из середины одной ветки и добавьте ее в другую:

A-----B------C
 \
  \
   D

становится

A-----B------C
 \
  \
   D-----C'

Это, конечно, можно сделать с помощью команды git cherry-pick.

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

A-----B-----C

И попытайтесь избавиться от B, вам нужно создать совершенно новую фиксацию следующим образом:

A-----------C'

Где C 'имеет другой идентификатор SHA-1. Аналогично, вишня, собирающая фиксацию из одной ветки в другую, в основном включает в себя создание патча, а затем его применение, тем самым также теряя историю.

Это изменение идентификаторов фиксации ломает git слияние функций между прочим (хотя, если использовать экономно, есть эвристика, которая будет документировать это). Что еще более важно, но он игнорирует функциональные зависимости - если C фактически использовал функцию, определенную в B, вы никогда не узнаете.

Возможно, лучший способ справиться с этим - иметь более мелкозернистые ветки. То есть вместо того, чтобы просто иметь "хозяина", есть "featureA", "bugfixB" и т.д. Выполняйте проверку кода на всей ветки за раз - где каждая ветвь очень сосредоточена на выполнении только одной вещи - и затем объединяет эту когда вы закончите. Это рабочий процесс, для которого git предназначен и для чего он хорош:)

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

Изменить: Кроме того, я не уверен, что понимаю ваш второй вопрос, о двух сценариях. Может быть, вы могли бы описать его более подробно, возможно, как отдельный вопрос, чтобы не путать вещи?

Ответ 2

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

Следовательно, новый ответ: используйте ветки функций и запросы на перенос.

Как это выглядит, где fA - фиксация с функцией A, а fB - фиксация с функцией B:

            fA   fC (bad commit, don't merge)
           /  \ /
master ----A----B----C
                \  /
                 fB

Запросы Pull связаны с функциональностью GitHub, но на самом деле все, что я имею в виду, это то, что кто-то несет ответственность за объединение ветвей функции в master.