format-patch работает достаточно хорошо, ищем лучший способ

StackOverflow https://stackoverflow.com/questions/773685

  •  13-09-2019
  •  | 
  •  

Вопрос

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

У меня есть «публичная» ветка, из которой удалено несколько файлов (с использованием ветки фильтра).Несмотря на то, что большинство коммитов совпадают с точки зрения дельт, идентификаторы всех коммитов разные.Я попробовал немало способов перенести изменения из моей ветки разработки в публичную ветку...Мне трудно поверить, что он может делать то, что я хочу, но подозреваю, что просто не знаю, как это сделать.В любом случае, это работает нормально, но кажется неправильным.

git checkout dev
git format-patch --stdout last_sync_tag > catchup.mbox
git checkout public
git am catchup.mbox
git --skip # talks about a missing file
git --skip # talks about a missing file
git --skip # talks about a missing file

Любые советы и предложения, которые, вероятно, будут включать в себя отказ от фильтрации файлов, которые вам не нужны, в общедоступной ветке (хотя как от них избавиться?), приветствуются.

Мои деревья выглядят примерно так:

dev: a-b-c-d-e-f-g-h-i-j-k
pub: t-u-v-w-x

т ≅ а, ты ≅ с, v ≅ d, ш ≅ е, х ≅ г.i,j,k — новые патчи, которые я бы хотел перенести.

checkout pub
rebase --onto pub i  # I really expected this to work
Это было полезно?

Решение

мерзавец cherry-pick команда может быть полезна.Я не использовал это в вашей ситуации, но думаю, что это должно сработать.Единственная проблема заключается в том, что он не предназначен для работы с различными коммитами, поэтому, если вы хотите написать сценарий/автоматизировать его, вам придется использовать что-то вроде git rev-list.

Опять же, я не пробовал это, но подобный bash-скрипт может дать вам хорошую отправную точку.

git checkout public
for rev in $(git rev-list --reverse last_sync_tag..dev) ; do
   git cherry-pick $rev && git tag -f last_sync_tag $rev || exit 1
done

Другие советы

Вы регулярно поддерживаете в своей ветке разработки файлы, которые не являются общедоступными?Или они просто тусуются?

Если вы не склонны вносить в них изменения и готовы немного переписать историю, вы можете организовать их создание в виде одного коммита на основе вашей публичной ветки;и объединить это обратно в публичный доступ, но с «-s Ours», чтобы они фактически не проникли.(предыдущий ответ о git merge -s наш)

Что-то вроде:

git checkout -b dev public
git am create-dev-only-files.patch
git checkout public
git merge -s ours dev
git checkout dev
# write more dev patches...
git checkout public
git merge dev
# and this should merge in the patches without bringing in the
#  dev-only files

Поэтому, если вы затем внесли последующие изменения в свою ветку разработки и объединили их с общедоступной, если вы не меняете те файлы, которые не являются общедоступными, все остальное просто применится.Но если набор файлов, которые вы хотите скрыть при общедоступных изменениях, это может оказаться непростой задачей.Вы можете попытаться предотвратить это, добавив, например, перехватчик предварительной фиксации для отмены подготовки определенных файлов перед началом любой фиксации в общедоступной ветке.

Поскольку вы использовали «ветвь фильтра», вам придется помочь git найти правильный коммит для выполнения перебазирования.

Я собираюсь догадаться, но, по-видимому, у вас есть «почти» общий коммит, который имеет две версии: заголовок вашей публичной ветки и место в вашей ветке разработки, которому соответствует этот коммит (нефильтрованный).Вызов публичного головного коммита <PH> и фиксация разработчика, которой это соответствует (перед фильтрацией) <DevPH>.

с извлеченной веткой dev вы хотите сделать что-то вроде этого:

git rebase --onto <PH> <DevPH>

Это указывает rebase принимать исправления, внесенные каждым коммитом, поскольку <DevPH> в текущей ветке и применить эти коммиты к <PH>.Я думаю, что это то, что вам нужно.

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

Ваше обновление вопроса показывает, что h эквивалентен заголовку общедоступного потока в ветке разработки и что вы хотите перенести все отсюда и далее из ветки разработки в публичную ветку.Если да, то команда

git rebase --onto pub h

Что ж, если я не хочу, чтобы файл попадал в .gitignore.Вероятно, это конфиг, а не настоящий код, поэтому его вообще не нужно отслеживать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top