Формат-патч работает достаточно хорошо, ищет лучший способ - PullRequest
0 голосов
/ 21 апреля 2009

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

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

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

t ≅ a, u ≅ c, v w d, w ≅ e, x ≅ g. i, j, k - новые патчи, которые я бы хотел перенести.

checkout pub
rebase --onto pub i  # I really expected this to work

Ответы [ 4 ]

1 голос
/ 22 апреля 2009

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

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

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

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

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

1 голос
/ 22 апреля 2009

Поскольку вы использовали "filter-branch", вам нужно будет помочь git найти правильный коммит для выполнения ребазировки.

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

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

git rebase --onto <PH> <DevPH>

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

Edit:

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

git rebase --onto pub h
1 голос
/ 21 апреля 2009
Команда

Git's 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
0 голосов
/ 21 апреля 2009

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

...