web-dev-qa-db-ja.com

Git:(同じベースコミットで)多くのブランチを一度にリベースする方法は?

私のプロジェクトには、他の人から変更をプルするために使用するmasterブランチがあります。それから、私は通常、現在取り組んでいるいくつかのトピックブランチを持っています。

私の質問は次のとおりです。新しい変更をマスターにプルして、すべてのトピックブランチを一度にそのベースにリベースする方法はありますか?

これは状況です:

        D--E topic1
       /
A--B--C  master
       \
        F--G topic2

そして、私はこれを単一のコマンドで実行したいです(Hは上流から来ました):

 D '-E'トピック1 
 /
 A--B--C--Hマスター
\
 F '-G 'トピック2 

これで、topic1とtopic2をマスターにリベースすることでこれを達成できることがわかりました。これを自動化するスクリプトを書くこともできました。しかし、他に複数のブランチがあり、新しいブランチを作成して他のブランチを頻繁に削除し、常にアップストリームの変更を受け取った場合はどうなりますか?

この操作(いくつかのリベース)を手動で行うと、面倒でエラーが発生しやすくなります。

もっと簡単な方法はありますか?

ありがとう!

57
malvim

これを自動的に行う方法はないと確信しています。 「git rebase master」を使用すると、マージの競合を解決する必要があるシェルに戻ることもあるので、これをすべて自動化するスクリプトを作成する場合は、それを考慮する必要があります。

ただし、どのブランチを更新する必要があるかはかなり簡単に追跡できます。うーん、どのブランチでも、ブランチが最新のwrtではない(つまり、その上でコミットする)場合、「git rev-list branch..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」を使用することを述べました。 。検出はブランチ構成に基づいていませんが、各ブランチをチェックアウトして「git pull」を実行し、ブランチ構成にリベースまたはマージを含むすべてを処理させるのが最も簡単でしょうか?

19
araqnid

いつでも次のようにシェルのワンライナーを書くことができます:

for branch in topic1 topic2 topic3;do git rebase master $branch;done

リベースしたいトピックのブランチは時間の経過とともに変化する可能性が高いため、これは迅速かつ簡単な^ H ^ H ^ H柔軟なソリューションです:-)

8
flacs

my git-extensions repository で管理されている堅牢なスクリプトにこれを変更しました。

$ 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]
0
Ingo Karkat