Git: Как перебазировать сразу несколько веток (с одним базовым коммитом)?
У меня есть основная ветка в моем проекте, которую я использую, чтобы получать изменения от других людей. Исходя из этого, у меня обычно есть несколько веток тем, над которыми я сейчас работаю.
Мой вопрос: есть ли способ для меня внести новые изменения в мой мастер, а затем перенести ВСЕ мои ветки тем на это сразу?
Это ситуация:
D--E topic1
/
A--B--C master
\
F--G topic2
И я хочу сделать это с помощью одной команды (H пришел из апстрима):
D '- E' topic1 / A- B- C- H мастер \ F'- G' topic2
Теперь я знаю, что могу сделать это, переместив topic1 и topic2 на master, и я мог бы даже написать скрипт для автоматизации этого. Но что, если у меня есть несколько других веток, я создаю новые и часто удаляю другие, и я постоянно получаю изменения из основной ветки?
Эта операция (несколько возвратов), когда выполняется вручную, утомительна и подвержена ошибкам.
Есть ли более простой способ?
Спасибо!
5 ответов
Я уверен, что нет способа автоматически сделать это. Помните, что "git rebase master" также может вернуть вас в оболочку, которая требует разрешения конфликтов слияния, поэтому, если вы хотите написать скрипт для автоматизации всего этого, вы должны принять это во внимание.
Вы можете довольно легко отследить, какие ветви нуждаются в обновлении. Хм, для любой ветви, "git rev-list branch..master" будет выдавать результат, если ветвь не обновлена по отношению к master (т.е. просто фиксируется поверх). Таким образом, вам нужно перебрать все локальные заголовки, кроме master, чтобы создать отчет (nb "git show-branch" примерно сделает это):
git for-each-ref 'refs/heads/*' | \
while read rev type ref; do
branch=$(expr "$ref" : 'refs/heads/\(.*\)' )
revs=$(git rev-list $rev..master)
if [ -n "$revs" ]; then
echo $branch needs update
git diff --summary --shortstat -M -C -C $rev master
fi
done
Поэтому, если вы чувствуете себя смелым, вы можете заменить этот "git diff" на что-то вроде "git checkout $branch && git rebase master" (или, может быть, просто "git pull --rebase", если вы настроили это). Я думаю, что вам нужно будет проверить наличие каталога ".git / rebase-apply" или проверить индекс на наличие необработанных файлов ("git ls-files -u"), чтобы проверить, не осталось ли нас в ожидании сделать слияние.
Конечно, если нет конфликтов, то это легко... это создает что-то, что также работает, когда это не так просто, это проблема:p
И это не обязательно относится к тому, что происходит, если одна из ваших веток основана на чем-то другом... вот почему я упомянул вместо этого использование "git pull --rebase", потому что это будет перебазировать в соответствии с конфигурацией ветки, а не вслепую от master, Хотя обнаружение не основано на конфигурации ветки... может быть, было бы проще всего проверить каждую ветку и сделать "git pull", и позволить конфигурации ветки обрабатывать все, включая перебазирование или слияние?
Вы всегда можете написать однострочную оболочку следующим образом:
for branch in topic1 topic2 topic3;do git rebase master $branch;done
Поскольку ветки тем, которые вы хотели бы перебазировать, со временем, вероятно, изменятся, это быстрое и быстрое решение: H)
Если вы хотите перебазировать все локальные ветки на master, вы можете попробовать это:
git branch | cut -c 3- | for branch in $(cat); do git rebase master $branch; done
Я превратил это в надежный скрипт, поддерживаемый в моем репозитории git-extensions:
$ git-urebaselocalbr --help
Rebase all / the last committed N local branches (except for the current branch
and master) to the updated upstream head.
Usage: git-urebaselocalbr [--continue|--skip|--abort] [--branches "<branch1> ..."] [N] [-i|--interactive] [options]