Вытащить все коммиты из ветки, нажать указанные коммиты в другой
У меня есть следующие ветки:
master
production
и следующие удаленные ветки:
origin/master
origin/production
У меня есть скрипт, который выбирает origin/master
ветвь и получает разницу того, что изменилось с моей последней выборки (log -p master..origin/master
). Потом сливаю origin/master
,
Найденные коммиты передаются в инструмент просмотра кода.
Я хочу отправить успешные коммиты - и только их - в производственную ветвь, а затем, конечно, origin/production
,
Как я могу это сделать?
Кроме того, у меня работает 2 скрипта: тот, который извлекается из origin/master
push push фиксирует детали в базе данных, и объединяет, и другие, которые я сейчас пишу, которые должны будут подтолкнуть успешные коммиты.
Я хотел бы, чтобы эти 2 сценария работали, избегая при этом условий гонки / конфликта слияния. Поскольку я хочу работать только с указанными коммитами, может быть, есть способ избавиться от коммитов, которые мне не нужны?
2 ответа
Я думаю, что вы ищете термин "вишня". То есть взять один коммит из середины одной ветви и добавить его в другую:
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 - он считает хранилище набором исправлений, и поэтому сбор вишни становится основной операцией. Однако у этого есть свой собственный набор проблем, таких как очень медленный:)
Изменить: Кроме того, я не уверен, что я понимаю ваш второй вопрос, о двух сценариях. Может быть, вы могли бы описать это более подробно, возможно, как отдельный вопрос, чтобы избежать путаницы?
Я понимаю, что это старый вопрос, но здесь есть ссылка: Как объединить конкретный коммит в Git
Следовательно, более новый ответ: используйте функциональные ветки и запросы запросов.
Как это выглядит, где fA - это коммит с функцией A, а fB - это коммит с функцией B:
fA fC (bad commit, don't merge)
/ \ /
master ----A----B----C
\ /
fB
Запросы на извлечение связаны с функциональностью GitHub, но на самом деле все, что я имею в виду, состоит в том, что кто-то несет ответственность за объединение ветвей функций в master.