Git: сохранение многих ветвей темы на часто движущейся базе
В моем ежедневном рабочем процессе git у меня много ветвей темы, например:
o--o--o (t2)
/
o--o (t1)
/
o--o--o (master)
\
o--o--o (t3)
Когда я тянусь вверх по течению,
o--o--o (t2)
/
o--o (t1)
/
o--o--o--n--n--n (master)
\
o--o--o (t3)
Я хочу переустановить все мои ветки темы поверх нового мастера:
o'--o'--o' (t2)
/
o'--o' (t1)
/
o--o--o--n--n--n (master)
\
o'--o'--o' (t3)
В настоящее время я делаю это вручную, используя git rebase --onto
. В этом случае весь процесс обновления будет:
$ git checkout master
$ git pull
$ git rebase master t1
$ git rebase --onto t1 t2~3 t2
$ git rebase master t3
Это становится еще более причудливым, когда вы прыгаете между различными ветками темы и добавляете коммиты.
Зависимости между ветвями темы в моем случае являются чисто древовидными: ни одна ветка не зависит от более чем одной другой ветки. (Я должен в конечном итоге воссоздать зависимые исправления в определенном порядке, поэтому я выбираю этот порядок априори.)
Существуют ли какие-либо инструменты, которые могут помочь мне управлять этим документооборотом? Я видел TopGit, но, похоже, он очень сильно привязан к рабочему процессу на основе электронной почты tg patch
, что не имеет для меня отношения.
Ответы
Ответ 1
Почти такой же вопрос задавался в списке рассылки git: Rebasing Несколько ветвей сразу... Связанный ответ имеет прикрепленный скрипт perl, который генерирует команды, которые вам понадобятся.
Если вы хотите, чтобы этот скрипт был быстрым и не пропустил его на пальцах ног, также подумайте о том, чтобы использовать git-new-workdir
для создания рабочей копии только для автоматического перезагрузки.
Если вы снова и снова разрешаете одни и те же конфликты, подумайте о включении git rerere.
Сказав все это, вот альтернативный рецепт:
# Construct a placeholder commit that has all topics as parent.
HEADS="$(git for-each-ref refs/heads/\*)" &&
MAGIC_COMMIT=$(echo "Magic Octopus"$'\n\n'"$HEADS" |
git commit-tree \
$(git merge-base $(echo "$HEADS" | sed 's/ .*//' ))^{tree} \
$(echo "$HEADS" | sed 's/ .*//;s/^/-p /')) &&
git update-ref refs/hidden/all $MAGIC_COMMIT
# Rebase the whole lot at once.
git rebase --preserve-merges master refs/hidden/all
# Resolve conflicts and all that jazz.
# Update topic refs from the rebased placeholder.
PARENT=
echo "$HEADS" |
while read HASH TYPE REF
do
let ++PARENT
git update-ref -m 'Mass rebase' "$REF" refs/hidden/all^$PARENT "$HASH"
done
Ответ 2
Не переустанавливайте. Начните свои функции с общей точки. В конечном итоге слияния - это еще меньше.
Это то, что мы делаем:
http://dymitruk.com/blog/2012/02/05/branch-per-feature/