索引を、作業ツリーの指定されたパスにあるファイルの存在を含めて反映するようにします。

索引を、作業ツリーの指定されたパスにあるファイルの存在を含めて反映するようにします。

リポジトリを更新し、特定のパスにファイルを追加および削除するスクリプトがあります。パスがわかったら、これらの変更をどのように適用しますか?つまり、

  • 指定されたファイルが作業ツリーにある場合は、インデックスにコピーします。
  • 指定されたファイルが索引にあるが作業ツリーにない場合は、索引から削除します。
  • 指定されたファイルがジョブツリーまたはインデックスにない場合は、何も実行されません。

git add最後のケースでは失敗します。コマンドラインにパスがないとエラーが発生し、何もしません。

私は以下を考慮しました。

  • git add --ignore-errors、残念ながら、ファイルが存在しないことを無視するエラーの種類として扱われません。

  • git add --ignore-missing残念ながら存在するが--dry-run

  • エラーを無視してパスごとに1回呼び出すとgit add機能しますが、速度が遅く、ファイルが存在しない(インデックスまたはワークツリーの両方)によって引き起こされるエラーを他のエラーと区別することはできません。

  • git add --all特定のパスにのみファイルをステージングする呼び出しは許可されていません。

ベストアンサー1

git addこれまでに私が見つけた最良の解決策は、gitインデックスと作業ツリーを明示的にチェックして渡すパスのリストを整理することです。

与えられたリポジトリ:

git init .
echo $RANDOM > ignore-edited
echo $RANDOM > ignore-deleted
echo $RANDOM > add-edited
echo $RANDOM > add-deleted
git add .
git commit -m 'Initial commit'

echo $RANDOM > ignore-new
echo $RANDOM > ignore-edited
rm             ignore-deleted
echo $RANDOM > add-new
echo $RANDOM > add-edited
rm             add-deleted

更新するファイルのリストは次のとおりです。

printf '%s\n' add-new add-edited add-deleted add-nonexistent | sort \
    > /tmp/filelist.txt

追加するファイルとインデックスの交点、追加するファイルと作業ツリーの既存のファイルとの和集合を取ることで、ファイルのリストを整理できます。

comm -12 /tmp/filelist.txt <(git ls-files) \
    > /tmp/files-in-index.txt
while read -r line ; do test -e "$line" && printf -- '%s\n' "$line" ; done < /tmp/filelist.txt \
    > /tmp/files-in-worktree.txt
sort -um /tmp/files-in-index.txt /tmp/files-in-worktree.txt \
    > /tmp/files-to-add.txt
< /tmp/files-to-add.txt xargs git add

または、1 回の通話で次の操作を行います。

sort -um \
    <(comm -12 /tmp/filelist.txt <(git ls-files)) \
    <(while read -r line ; do test -e "$line" && printf -- '%s\n' "$line" ; done < /tmp/filelist.txt) |
    xargs git add

おすすめ記事