16

次のことを行うシェルスクリプトを作成しようとしています。

  1. プルする変更がないかリモート git リポジトリをチェックします。
  2. リモート git リポジトリに変更がある場合は、それらの変更をプルします。
  3. 新規または変更されたファイルをループします。

私の研究を通じて、これらのことを行うために必要なコマンドのいくつかを見つけましたが、それらをシェルスクリプトで一緒に動作させることはできませんでした.

これは、私が持っているコマンドのいくつかを含むスクリプトです。

#!/bin/sh

#Check if there are any changed files
git --git-dir="/dir/.git" fetch origin

if git --git-dir="/dir/.git" log HEAD..origin/master --oneline
then

#Output the modified files from the last pull
        git --git-dir="/dir/.git" diff --name-status ORIG_HEAD..

fi

このスクリプトのコマンドでうまくいかなかった点は次のとおりです。

  1. 変更があるかどうかを確認する if ステートメントは常に true であるとは限りません。他の git コマンドで if ステートメントを試してみましたが、それらも常に true です。git は、0 または 1 の応答が得られる通常のシェル コマンドのようには機能しないようです。このような git コマンドや他の git コマンドを取得して、if ステートメントで正しい応答を返すにはどうすればよいですか?
  2. コマンドからの変数出力を割り当てて、変更されたファイルを配列に表示し、for を使用してそれらをループできるようにするにはどうすればよいですか?

この場合、スクリプトのコマンドが実際に機能しない場合、これを行うためのより良い方法は何ですか?

編集:変更されたファイルをループするときは、申し訳ありませんが、ファイルをループする前にリモートリポジトリから変更をプルする必要があるため、これらのファイルを操作するときに最新の変更が得られるようにする必要があります。

4

4 に答える 4

14

最初の質問では、変更があったかどうかを判断するために使用できますgit diff --quiet(またはgit diff --exit-code、通常、終了コードに使用している場合は、出力を出力しないようにします。これは)をgit diff --quiet意味--exit-codeします。変更がある場合は1の値になり、変更がない場合は0になります。したがって、変更があった場合にのみ実行されるコードが必要な場合は、次のようになります。

if ! git --git-dir="/dir/.git" diff --quiet
then
    # do stuff...
fi

2番目の質問では、次のwhile read ...行を読み取るためのループをお勧めしgit diff-treeます。

git --git-dir="/dir/.git" diff-tree ORIG_HEAD.. | \
    while read srcmode dstmode srcsha dstsha status srcfile dstfile
    do
        # do something with $srcfile and $dstfile
    done

最初に$srcmode余分なものがあり、ファイルの名前が変更された場合にのみ値が含まれることに注意してください。名前の変更について心配したくない場合は、を渡してください。名前の変更が表示される代わりに、追加と削除のみが表示されます。:$dstfile--no-renames

于 2012-12-05T03:15:52.820 に答える
3

そうですgit、エラーがない限り、通常はゼロ以外のステータスで終了しません。コミットされていない変更を検出するために私が見つけた最も簡単な方法は、次のようなものです。

 let changes=0
 while read status filename; do
    let changes=1
    # do something with this filename/status
 done < <(git status --porcelain)
 if (( ! changes )); then
    echo "No changes."
 fi

一般に、コードから git を駆動しようとする場合は、--porcelainそれをサポートするサブコマンドで使用して、より自動化に適した方法で動作させる必要があります。独自のシェル コマンドを作成せずに git と対話するために、他の言語のライブラリを調査することもできます。たとえば、Ruby にはgritがあります。

さて、あなたの場合、上流で何が変更されたかを検出したいと考えています。そのためには、おそらく を使用したいと思うでしょうgit diff-tree。上記と同様のロジック:

 git fetch   # not pull
 while read filename; do
   # do something with filename
 done < <(git diff-tree --name-only origin/master master)  # or whatever branch you're using
于 2012-12-05T03:00:43.540 に答える