使索引反映工作樹中給定路徑的文件,包括它們的存在

使索引反映工作樹中給定路徑的文件,包括它們的存在

我有一個腳本可以更新儲存庫,並在某些給定路徑中新增/刪除檔案。知道路徑後如何提交這些變更? IE,

  • 如果指定檔案在工作樹中,則將其複製到索引
  • 如果指定的檔案在索引中但不在工作樹中,則將其從索引中刪除
  • 如果指定的檔案既不在工作樹中也不在索引中,則不執行任何操作。

git add在最後一個極端情況下失敗 - 如果其命令列上的任何路徑不存在,則會出現錯誤並不會執行任何操作。

我考慮過:

  • git add --ignore-errors,不幸的是,它不會將文件不存在視為它忽略的錯誤類型。

  • git add --ignore-missing令人沮喪地存在,但僅適用於--dry-run.

  • 每個路徑一次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

或者,在一次調用中:

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

相關內容