
Ich habe ein Skript, das ein Repository aktualisiert und Dateien an bestimmten Pfaden hinzufügt/löscht. Wie kann ich diese Änderungen übernehmen, wenn ich die Pfade kenne? D. h.
- Wenn sich eine angegebene Datei im Arbeitsbaum befindet, kopieren Sie sie in den Index
- Wenn eine angegebene Datei im Index, aber nicht im Arbeitsbaum vorhanden ist, entfernen Sie sie aus dem Index
- Wenn sich eine angegebene Datei weder im Arbeitsbaum noch im Index befindet, tun Sie nichts.
git add
schlägt im letzten Sonderfall fehl – wenn einer der Pfade in der Befehlszeile nicht existiert, wird es mit einem Fehler beendet und es geschieht nichts.
Ich habe überlegt:
git add --ignore-errors
, betrachtet das Nichtvorhandensein der Datei leider nicht als die Art von Fehler, die es ignoriert.git add --ignore-missing
existiert frustrierenderweise, funktioniert aber nur mit--dry-run
.Ein
git add
Aufruf pro Pfad unter Ignorieren von Fehlern würde funktionieren, ist aber langsam und ermöglicht keine Unterscheidung zwischen Fehlern, die auf das Nichtvorhandensein der Datei (weder im Index noch im Arbeitsbaum) zurückzuführen sind, und anderen Fehlern.Ein
git add --all
Aufruf erlaubt nicht die Bereitstellung ausschließlich von Dateien in bestimmten Pfaden.
Antwort1
Die beste Lösung, die ich bisher gefunden habe, besteht darin, git add
durch explizite Überprüfung des Git-Index und des Arbeitsbaums eine Liste mit zu übergebenden Pfaden zu erstellen.
Angesichts des Repository:
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
und die Liste der zu aktualisierenden Dateien:
printf '%s\n' add-new add-edited add-deleted add-nonexistent | sort \
> /tmp/filelist.txt
Wir können die Dateiliste erstellen, indem wir die Schnittmenge aus der Schnittmenge unserer hinzuzufügenden Dateien und dem Index sowie der Schnittmenge unserer hinzuzufügenden Dateien und der im Arbeitsbaum vorhandenen Dateien ermitteln:
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
Oder in einem Aufruf:
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