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]
      git branch | sed 's/\*/ /g' | xargs -n1 git rebase master
Другие вопросы по тегам