¿Las reglas git update-index –assume-unchanged se propagan a los clientes al extraer?

9 minutos de lectura

avatar de usuario
Jordan Arseno

Hay casos en los que no puedo usar un .gitignore archivo, de lo contrario, en git push, los archivos críticos se eliminan del control remoto. En estos casos aplico git update-index --assume-unchanged <file> a los archivos que quiero ignorar.

Después de aplicar las reglas de asumir sin cambios y llamar git push, ¿estas reglas se adjuntarán a la rama remota para que todas las extracciones posteriores (de otros clientes) las hereden? O, ¿deben estos clientes ejecutar también el git update-index --assume-unchanged <file> comandos individualmente en sus máquinas?

Si los comandos no se heredan, ¿alguien ha escrito un enlace de servidor para esto antes? ¿En lugar de exigir que todos los clientes actuales y futuros se protejan contra él?

  • Parece que debería hacer una nueva pregunta (después de trabajar en ella por su cuenta primero, por supuesto :-)), algo como: “en un enlace de actualización o pre-recepción de git, ¿cómo puedo rechazar un envío que incluye commit(s) que modifican o eliminan un archivo/conjunto de archivos/…” (defina el problema lo mejor posible aquí).

    – torek

    02/09/2013 a las 20:14

  • Estoy en una situación similar en la que tengo un conjunto de archivos con control de versión, lo que significa que están en el repositorio (requerido para la configuración inicial y permitido para la personalización), pero no es necesario realizar un seguimiento después de la clonación. Desearía como gitignore para archivos sin seguimiento, si GIT también tuviera una función “Olvidar” para los archivos con tachuelas. La alternativa sugerida son los ganchos (que se ejecutan sin cambios), pero deben entregarse manualmente para cada repositorio clonado. Siento que “Olvidar” será una característica útil que permitirá ignorar los archivos rastreados.

    – Desarrollador MG

    12 de junio de 2017 a las 15:46


  • Hice esta pregunta hace 7 años. Obtuvo un voto a favor y un marcador de seguimiento no triviales. Pero, como autor, 7 años en el futuro, debo admitir que no tengo idea de qué significa esto, o por qué necesitaba esta información, entonces.

    – Jordan Arseno

    27 de junio de 2020 a las 0:15

  • @JordanArseno 2021 ya está aquí. Necesito exactamente lo mismo: el archivo similar a una “plantilla” modificada temporalmente (durante la compilación) no debe confirmarse. Quiero propagar lo mismo a otros usuarios del equipo. git update-index --assume-unchanged ... sin pedirles que lo ejecuten. Tal vez tu idea era la misma

    – RandomB

    22 de abril de 2021 a las 6:43


avatar de usuario
Extremo de la barra

El índice es local para su estación de trabajo, cualquier cambio que realice allí no se propaga a otros clones del mismo control remoto.

(actualizado, después de que se actualizó la pregunta)

El archivo .gitignore

Hay casos en los que no puedo usar un archivo .gitignore; de ​​lo contrario, en git push, los archivos críticos se eliminan del control remoto.

Esto no es verdad. El archivo de ignorar de git no afecta los archivos que ya están rastreados en el repositorio. Si agrega un archivo a .gitignore después de que se haya confirmado, permanecerá dentro del repositorio; va a no ser purgado De hecho, se comporta prácticamente como si no se ignorara en absoluto.

Puede verificar esto fácilmente en un repositorio temporal:

$ mkdir -p /tmp/repo
$ cd /tmp/repo
$ git init
Initialized empty Git repository in /tmp/repo/.git/
$ echo red > a.txt
$ git commit -am '1'
 1 file changed, 1 insertion(+)
 create mode 100644 a.txt
$ echo a.txt > .gitignore
$ echo b.txt >> .gitignore
$ git commit -am '2'
 1 file changed, 2 insertions(+)
 create mode 100644 .gitignore

El repositorio ahora contiene dos archivos: a.txt y .gitignore. Ambos se comportan normalmente, lo cual puedes ver cuando lo clonas:

$ cd ..
$ git clone file://repo repo2
$ ls -A repo2
.git       .gitignore a.txt
$ cd repo

Si modificamos los archivos ignorados y solicitamos git statuseso lo veremos a.txt se ve como modificado, a pesar de haber sido gitignorado. Podemos agregarlo y enviarlo como de costumbre; de hecho, si agrega un archivo rastreado a gitignore, se comporta como si no estuviera en gitignore.

$ echo green > a.txt
$ echo blue > b.txt
$ git status --short
 M a.txt
$ git add a.txt

los b.txt El archivo es diferente, porque se ignoró antes de que git comenzara a rastrearlo. Este archivo normalmente no llegará al repositorio, pero podemos forzarlo si queremos.

$ git add b.txt
The following paths are ignored by one of your .gitignore files:
b.txt
Use -f if you really want to add them.
fatal: no files added
$ git add -f b.txt

Emisor git commit ahora confirma dos archivos que han sido ignorados por git:

$ git commit -m '3'
 2 files changed, 1 insertion(+), 1 deletion(-)
 create mode 100644 b.txt

Para resumir, piense en las reglas de ignorar git como pautas 🙂

Propagando asumir-sin cambios

Después de aplicar las reglas de asumir sin cambios y llamar a git push, ¿se adjuntarán estas reglas a la rama remota para que todas las extracciones posteriores (de otros clientes) las hereden? ¿O estos clientes también deben ejecutar los comandos git update-index –assume-unchanged individualmente en sus máquinas?

Este último. Lo más cercano que puede obtener es agregar un script de shell al repositorio que realiza los cambios por usted.

¿El gancho del servidor?

Si los comandos no se heredan, ¿alguien ha escrito un enlace de servidor para esto antes? ¿En lugar de exigir que todos los clientes actuales y futuros se protejan contra él?

Si su objetivo es escribir un enlace de servidor que elimine los archivos críticos como si no fueran parte del impulso, eso no es posible. Git push trata principalmente con comprometerse objetos (y árbitros). Sus objetos dependientes, como árboles y blobs, se transfieren según sea necesario, sujeto a accesibilidad desde una confirmación. Todo se reduce a que, si no está comprometido, no puede enviarlo a un control remoto (eso es una simplificación excesiva, pero es cierto para los archivos en el repositorio). Además, las confirmaciones de git están protegidas criptográficamente. No puede cambiar una confirmación sin cambiar su hash de confirmación, y si cambia el hash de confirmación, básicamente tiene una nueva confirmación diferente (que puede tener la misma diferencia que la anterior).

Esto significa que el servidor no puede reescribir confirmaciones; al menos no sin confundir seriamente al cliente que hizo el envío (que aún tendrá una copia de los objetos de confirmación anteriores).

Lo que tu pueden hacer es escribir un enlace posterior a la recepción que rechace las confirmaciones si contienen los archivos que no desea que se actualicen. Esto realmente no resuelve su problema, porque si tiene problemas para explicar git commit --assume-unchanged a sus compañeros de trabajo, es probable que tenga aún más problemas para explicarles cómo pueden usar la reorganización interactiva para recrear sus confirmaciones sin los archivos no deseados en ellas.

Para resumir, creo que perseguir a todos para que sigan usando asumir sin cambios (tal vez combinado con un enlace posterior a la recepción) es la opción menos mala si se trata de archivos que deben confirmarse una vez y nunca más, como lo ha hecho ahora.

Una posible solución

Tu vida se convertiría en un entero mucho más fácil si puede mantener estos archivos fuera de git en su totalidad. Una de las cosas que se me ocurren:

  • mueva los archivos dentro del repositorio a un directorio lib, donde no se modifican todo el tiempo
  • .gitignore los archivos en su ubicación definitiva, aquella donde tienen que estar pero reciben cambios no deseados todo el tiempo
  • agregue un script “init” a su repositorio que las personas deben ejecutar una vez después de la clonación y antes de comenzar a trabajar. Este script copia los archivos en la ubicación correcta.

  • Gracias. También actualicé mi pregunta, preguntando si hay soluciones de enganche mediante las cuales puedo suprimir directorios específicos para que no sean actualizados por git push

    – Jordan Arseno

    2 de septiembre de 2013 a las 11:03

  • Actualicé mi respuesta en función de mi comprensión de su pregunta actualizada. Se ha vuelto un poco más grande de lo que esperaba, espero que te sea útil.

    – Extremo de la barra

    3 de septiembre de 2013 a las 10:59

  • El tercer punto es una gran idea: esto le permitirá copiar un campo de configuración establecido, por ejemplo, mientras aún puede mantener los cambios de configuración local. Esto es especialmente útil para repositorios desnudos remotos donde no puede usar el comando skip-worktree para ignorar dichos archivos

    – JamesG

    24 de mayo de 2017 a las 12:48

al trabajar con npm

Como han explicado las respuestas anteriores, no es posible propagar git update-index --assume-unchanged mediante git.

Dicho esto, al trabajar con npmpuede agregar un postinstall gancho que actualiza el índice:

{
  "scripts": {
    "assume-unchanged": "git update-index --assume-unchanged file",
    "postinstall": "npm run assume-unchanged"
  }
}

Esto se ejecutará en cada npm install.

Una posible solución es escribir un gancho del lado del cliente para evitar que las personas realicen cambios locales en los archivos que desea ignorar.

Estos ganchos son scripts que se ejecutan en ciertos eventos en git, como confirmación previa, confirmación posterior, inserción previa, etc. Puede ver las muestras en <your_repo>/.git/hooks/.

La mala noticia es que también son no bajo control de versionespor lo que debe escribir su propia secuencia de comandos de configuración para copiar la secuencia de comandos de gancho a .git/hooks/.

Aquí hay una pequeña muestra de un gancho de compromiso previo que evita que el forbidden.txt archivo a confirmar (se puede adaptar para tomar una lista de archivos):

ROOT_DIR="$(pwd)/"
LIST=$(git diff --cached --name-only --diff-filter=ACRM)

for file in $LIST
do
    if [ "$file" == “forbidden.txt” ]; then
        echo You cannot commit file $file. Please reset it and try again.
        exit 1
    fi
done
exit 0

  • Una alternativa a la copia de los ganchos sería vincular un directorio (para que no tenga que copiarlos nuevamente si cambian). Hay un hilo discutiendo esto: stackoverflow.com/questions/3462955/…

    – Maurice Muller

    14 de diciembre de 2017 a las 8:34

¿Ha sido útil esta solución?