Вытащить все коммиты из ветки, нажать указанные коммиты в другой - PullRequest
91 голосов
/ 19 мая 2009

У меня есть следующие филиалы:

  • master
  • production

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

  • origin/master
  • origin/production

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

Найденные коммиты передаются в инструмент просмотра кода.

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

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

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

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

Ответы [ 2 ]

287 голосов
/ 19 мая 2009

Я думаю, что вы ищете термин «вишневый кирка». То есть, возьмите один коммит из середины одной ветви и добавьте его в другую:

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, вы никогда не узнаете.

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

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

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

1 голос
/ 25 июня 2015

Я понимаю, что это старый вопрос, но на него есть ссылка: Как объединить определенный коммит в Git

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

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

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

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

...