Hacer que el índice refleje archivos en rutas determinadas en el árbol de trabajo, incluida su presencia

Hacer que el índice refleje archivos en rutas determinadas en el árbol de trabajo, incluida su presencia

Tengo un script que actualiza un repositorio y agrega/elimina archivos en algunas rutas determinadas. ¿Cómo puedo cometer estos cambios conociendo las rutas? Es decir,

  • Si un archivo específico está en el árbol de trabajo, cópielo al índice
  • Si un archivo específico está en el índice pero no en el árbol de trabajo, elimínelo del índice
  • Si un archivo específico no está en el árbol de trabajo ni en el índice, no haga nada.

git addfalla en el último caso de la esquina: si alguna de las rutas en su línea de comando no existe, sale con un error y no hace nada.

Yo considere:

  • git add --ignore-errors, desafortunadamente no considera que el archivo no exista como el tipo de error que ignora.

  • git add --ignore-missingExiste de manera frustrante pero solo funciona con --dry-run.

  • Una git addinvocación por ruta, ignorando los errores, funcionaría, pero es lenta y no permite discernir los errores debidos a que el archivo no existe (ni en el índice ni en el árbol de trabajo) de otros errores.

  • Una git add --allinvocación no permite almacenar solo archivos en determinadas rutas.

Respuesta1

La mejor solución que encontré hasta ahora es construir una lista de rutas a las que pasar git addinspeccionando explícitamente el índice de git y el árbol de trabajo.

Dado el repositorio:

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

y la lista de archivos para actualizar:

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

Podemos construir la lista de archivos obteniendo la unión entre la intersección de nuestros archivos a agregar y el índice, y la intersección de nuestros archivos a agregar y los existentes en el árbol de trabajo:

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

O, en una invocación:

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

información relacionada