1. ホーム
  2. git

[解決済み] bash スクリプトを使用してすべての git ブランチを反復処理する方法

2022-08-30 04:57:30

質問

bash スクリプトを使用して、リポジトリ内のすべてのローカルブランチを反復処理するにはどうすればよいですか。 私は反復して、ブランチといくつかのリモートブランチの間に違いがあるかどうかをチェックする必要があります。 元

for branch in $(git branch); 
do
    git log --oneline $branch ^remotes/origin/master;
done

私は上記のようなことをする必要がありますが、私が直面している問題は、$(git branch)は、リポジトリに存在するブランチと一緒にリポジトリフォルダ内のフォルダを私に与えることです。

これはこの問題を解決するための正しい方法でしょうか?それとも別の方法があるのでしょうか?

ありがとうございます。

どのように解決するのですか?

この場合 gitブランチ を使うべきではありません。Git では 「plumbing" インターフェース を提供します(現在および過去の多くの通常のGitコマンド(add、checkout、mergeなど)の実装は、この同じインターフェイスを使用しています)。

あなたが望む配管コマンドは git for-each-ref :

git for-each-ref --shell \
  --format='git log --oneline %(refname) ^origin/master' \
  refs/heads/

注意: この場合 remotes/ を引き起こす他の参照がない限り、リモート参照のプレフィックスは必要ありません。 origin/master が参照名の検索パスの複数の場所にマッチするような他の参照がない限り(参照 "A symbolic ref name. ...」にある git-rev-parse(1) のリビジョンの指定のセクションを参照ください。 ). もし明確に曖昧さを避けたいのであれば、完全な参照名を指定しましょう。 refs/remotes/origin/master .

このような出力が得られます。

git log --oneline 'refs/heads/master' ^origin/master
git log --oneline 'refs/heads/other' ^origin/master
git log --oneline 'refs/heads/pu' ^origin/master

この出力をパイプで sh .

シェルコードを生成するのが嫌な場合は、少し堅牢性をあきらめることもできます * にして、このようにします。

for branch in $(git for-each-ref --format='%(refname)' refs/heads/); do
    git log --oneline "$branch" ^origin/master
done

* Ref 名はシェルの単語分割の影響を受けないようにする必要があります ( git-check-ref-format(1)を参照してください。 ). 個人的には、前者のバージョン(生成されたシェルコード)にこだわります。この方が、不適切なことが起こらないという確信があります。

あなたが指定した バッシュ を指定し、それが配列をサポートしているので、安全性を維持しながらも、ループの根幹を生成しないようにすることができます。

branches=()
eval "$(git for-each-ref --shell --format='branches+=(%(refname))' refs/heads/)"
for branch in "${branches[@]}"; do
    # …
done

同じようなことを $@ 配列に対応したシェルでない場合は ( set -- で初期化し set -- "$@" %(refname) で要素を追加します)。