Я думаю, что вы ищете термин «вишневый кирка». То есть, возьмите один коммит из середины одной ветви и добавьте его в другую:
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 - он считает хранилище набором исправлений, и поэтому сбор вишни становится основной операцией. Однако у этого есть свой собственный набор проблем, таких как очень медленный:)
Редактировать: Кроме того, я не уверен, что понимаю ваш второй вопрос о двух сценариях. Может быть, вы могли бы описать это более подробно, возможно, как отдельный вопрос, чтобы не запутаться?