tipos tag qué permisos existen etiquetas eliminar dar crear commits commands linux git file-permissions

linux - tag - qué tipos de etiquetas existen en git



Retención de permisos de archivos con Git (7)

El git-cache-meta mencionado en la pregunta de SO " git - ¿cómo recuperar los permisos de archivo git piensa que el archivo debería ser? " (Y las preguntas frecuentes de git ) es el enfoque más directo.

La idea es almacenar en un archivo .git_cache_meta los permisos de los archivos y directorios.
Es un archivo separado no versionado directamente en el repositorio de Git.

Es por eso que el uso es:

$ git bundle create mybundle.bdl master; git-cache-meta --store $ scp mybundle.bdl .git_cache_meta machine2: #then on machine2: $ git init; git pull mybundle.bdl master; git-cache-meta --apply

Vos tambien:

  • agrupe su repositorio y guarde los permisos de archivos asociados.
  • copia esos dos archivos en el servidor remoto
  • restaurar el repositorio allí y aplicar el permiso

Quiero controlar la versión de mi servidor web como se describe en el control de versiones para mi servidor web , al crear un repositorio git fuera de mi /var/www directory . Tenía la esperanza de poder enviar contenido web de nuestro servidor de desarrollo a Github, llevarlo a nuestro servidor de producción y pasar el resto del día en la piscina.

Aparentemente un inconveniente en mi plan es que Git no respetará los permisos de archivos (no lo he intentado, solo lo he leído ahora). Creo que esto tiene sentido ya que es probable que diferentes cuadros tengan diferentes configuraciones de usuario / grupo. Pero si quería forzar la propagación de permisos, sabiendo que mis servidores están configurados de la misma manera, ¿tengo alguna opción? ¿O hay una manera más fácil de abordar lo que intento hacer?


En caso de que te estés planteando esto ahora, he pasado por esto hoy y puedo resumir dónde está esto. Si aún no lo has intentado, algunos detalles aquí pueden ayudarte.

Creo que el enfoque de @Omid Ariyan es la mejor manera. Agregue los scripts de precompilación y postpago. NO te olvides de nombrarlos exactamente como lo hace Omid y NO olvides hacerlos ejecutables. Si olvida alguno de estos, no tienen ningún efecto y ejecuta "git commit" una y otra vez preguntándose por qué no sucede nada :) Además, si corta y pega fuera del navegador web, tenga cuidado de que las comillas y los tics no sean correctos. alterado

Si ejecuta el script de precompilación una vez (ejecutando un commit de git), entonces se crearán las permisos de archivo. Puede agregarlo al repositorio y creo que es innecesario agregarlo una y otra vez al final del script precompromiso. Pero no duele, creo (esperanza).

Hay algunos pequeños problemas sobre el nombre del directorio y la existencia de espacios en los nombres de los archivos en los scripts de Omid. Los espacios eran un problema aquí y tuve algunos problemas con el arreglo IFS. Para el registro, este script de precompilación funcionó correctamente para mí:

#!/bin/bash SELF_DIR=`git rev-parse --show-toplevel` DATABASE=$SELF_DIR/.permissions # Clear the permissions database file > $DATABASE echo -n "Backing-up file permissions..." IFSold=$IFS IFS=$''/n'' for FILE in `git ls-files` do # Save the permissions of all the files in the index echo $FILE";"`stat -c "%a;%U;%G" $FILE` >> $DATABASE done IFS=${IFSold} # Add the permissions database file to the index git add $DATABASE echo "OK"

Ahora, ¿qué sacamos de esto?

El archivo .permissions está en el nivel superior del repositorio git. Tiene una línea por archivo, aquí está la parte superior de mi ejemplo:

$ cat .permissions .gitignore;660;pauljohn;pauljohn 05.WhatToReport/05.WhatToReport.doc;664;pauljohn;pauljohn 05.WhatToReport/05.WhatToReport.pdf;664;pauljohn;pauljohn

Como puede ver, tenemos

filepath;perms;owner;group

En los comentarios sobre este enfoque, uno de los carteles se queja de que solo funciona con el mismo nombre de usuario, y eso es técnicamente cierto, pero es muy fácil solucionarlo. Tenga en cuenta que el script post-checkout tiene 2 acciones,

# Set the file permissions chmod $PERMISSIONS $FILE # Set the file owner and groups chown $USER:$GROUP $FILE

Así que solo estoy guardando el primero, eso es todo lo que necesito. Mi nombre de usuario en el servidor web es realmente diferente, pero lo más importante es que no puede ejecutar chown a menos que sea root. Puede ejecutar "chgrp", sin embargo. Es bastante claro cómo poner eso en uso.

En la primera respuesta de esta publicación, la que es más ampliamente aceptada, la sugerencia es usar git-cache-meta, una secuencia de comandos que está haciendo el mismo trabajo que están haciendo los scripts pre y post hook (análisis de salida de git ls-files ). Estos guiones son más fáciles de entender, el código git-cache-meta es bastante más elaborado. Es posible mantener git-cache-meta en la ruta y escribir scripts de pre-commit y post-checkout que lo usarían.

Los espacios en los nombres de archivos son un problema con los dos scripts de Omid. En el script post-checkout, sabrá que tiene los espacios en los nombres de archivo si ve errores como este

$ git checkout -- upload.sh Restoring file permissions...chmod: cannot access ''04.StartingValuesInLISREL/Open'': No such file or directory chmod: cannot access ''Notebook.onetoc2'': No such file or directory chown: cannot access ''04.StartingValuesInLISREL/Open'': No such file or directory chown: cannot access ''Notebook.onetoc2'': No such file or directory

Estoy buscando soluciones para eso. Aquí hay algo que parece funcionar, pero solo lo he probado en un caso

#!/bin/bash SELF_DIR=`git rev-parse --show-toplevel` DATABASE=$SELF_DIR/.permissions echo -n "Restoring file permissions..." IFSold=${IFS} IFS=$ while read -r LINE || [[ -n "$LINE" ]]; do FILE=`echo $LINE | cut -d ";" -f 1` PERMISSIONS=`echo $LINE | cut -d ";" -f 2` USER=`echo $LINE | cut -d ";" -f 3` GROUP=`echo $LINE | cut -d ";" -f 4` # Set the file permissions chmod $PERMISSIONS $FILE # Set the file owner and groups chown $USER:$GROUP $FILE done < $DATABASE IFS=${IFSold} echo "OK" exit 0

Dado que la información de permisos es una línea a la vez, configuro IFS en $, por lo que solo los saltos de línea se consideran cosas nuevas.

¡Leí que es MUY IMPORTANTE volver a configurar la variable de entorno IFS como estaba! Puede ver por qué una sesión de shell puede salir mal si deja $ como el único separador.


En precompromiso / postpago, una opción sería usar la utilidad "mtree" (FreeBSD) o "fmtree" (Ubuntu) que "compara una jerarquía de archivos con una especificación, crea una especificación para una jerarquía de archivos o modifica una especificación."

El conjunto predeterminado son flags, gid, link, mode, nlink, size, time, type y uid. Esto se puede adaptar al propósito específico con el modificador -k.


Esto es bastante tarde pero podría ayudar a otros. Hago lo que quiero hacer agregando dos ganchos git a mi repositorio.

.git / hooks / pre-commit:

#!/bin/bash # # A hook script called by "git commit" with no arguments. The hook should # exit with non-zero status after issuing an appropriate message if it wants # to stop the commit. SELF_DIR=`git rev-parse --show-toplevel` DATABASE=$SELF_DIR/.permissions # Clear the permissions database file > $DATABASE echo -n "Backing-up file permissions..." IFS_OLD=$IFS; IFS=$''/n'' for FILE in `git ls-files` do # Save the permissions of all the files in the index echo $FILE";"`stat -c "%a;%U;%G" $FILE` >> $DATABASE done IFS=$IFS_OLD # Add the permissions database file to the index git add $DATABASE echo "OK"

.git / hooks / post-checkout:

#!/bin/bash SELF_DIR=`git rev-parse --show-toplevel` DATABASE=$SELF_DIR/.permissions echo -n "Restoring file permissions..." IFS_OLD=$IFS; IFS=$''/n'' while read -r LINE || [[ -n "$LINE" ]]; do FILE=`echo $LINE | cut -d ";" -f 1` PERMISSIONS=`echo $LINE | cut -d ";" -f 2` USER=`echo $LINE | cut -d ";" -f 3` GROUP=`echo $LINE | cut -d ";" -f 4` # Set the file permissions chmod $PERMISSIONS $FILE # Set the file owner and groups chown $USER:$GROUP $FILE done < $DATABASE IFS=$IFS_OLD echo "OK" exit 0

Se llama al primer enlace cuando "confirma" y leerá la propiedad y los permisos de todos los archivos en el repositorio y los almacenará en un archivo en la raíz del repositorio llamado .permissions y luego agregará el archivo .permissions al commit.

Se llama al segundo enlace cuando "realiza el pago" y revisa la lista de archivos en el archivo .permissions y restaura la propiedad y los permisos de esos archivos.

  • Es posible que deba realizar la confirmación y la extracción usando sudo.
  • Asegúrese de que las secuencias de comandos precompromisos y posteriores a la salida tengan permiso de ejecución.

Git es el Sistema de control de versiones, creado para el desarrollo de software, por lo que de todo el conjunto de modos y permisos almacena solo el bit ejecutable (para archivos comunes) y el bit de enlace simbólico. Si desea almacenar permisos completos, necesita una herramienta de terceros, como git-cache-meta ( mencionada por VonC ) o Metastore (utilizada por etckeeper ). O puede usar IsiSetup , que IIRC usa git como back-end.

Consulte la página Interfaces, interfaces y herramientas en Git Wiki.


Me estoy ejecutando en FreeBSD 11.1, el concepto de virtualización de la cárcel de FreeBSD hace que el sistema operativo sea óptimo. La versión actual de Git que estoy usando es 2.15.1, también prefiero ejecutar todo en scripts de shell. Con eso en mente, modifiqué las sugerencias anteriores de la siguiente manera:

git push: .git / hooks / pre-commit

#! /bin/sh - # # A hook script called by "git commit" with no arguments. The hook should # exit with non-zero status after issuing an appropriate message if it wants # to stop the commit. SELF_DIR=$(git rev-parse --show-toplevel); DATABASE=$SELF_DIR/.permissions; # Clear the permissions database file > $DATABASE; printf "Backing-up file permissions.../n"; OLDIFS=$IFS; IFS=$''/n''; for FILE in $(git ls-files); do # Save the permissions of all the files in the index printf "%s;%s/n" $FILE $(stat -f "%Lp;%u;%g" $FILE) >> $DATABASE; done IFS=$OLDIFS; # Add the permissions database file to the index git add $DATABASE; printf "OK/n";

git pull: .git / hooks / post-merge

#! /bin/sh - SELF_DIR=$(git rev-parse --show-toplevel); DATABASE=$SELF_DIR/.permissions; printf "Restoring file permissions.../n"; OLDIFS=$IFS; IFS=$''/n''; while read -r LINE || [ -n "$LINE" ]; do FILE=$(printf "%s" $LINE | cut -d ";" -f 1); PERMISSIONS=$(printf "%s" $LINE | cut -d ";" -f 2); USER=$(printf "%s" $LINE | cut -d ";" -f 3); GROUP=$(printf "%s" $LINE | cut -d ";" -f 4); # Set the file permissions chmod $PERMISSIONS $FILE; # Set the file owner and groups chown $USER:$GROUP $FILE; done < $DATABASE IFS=$OLDIFS pritnf "OK/n"; exit 0;

Si por algún motivo necesita recrear el script, la salida del archivo .permissions debe tener el siguiente formato:

.gitignore;644;0;0

Para un archivo .gitignore con 644 permisos otorgados a la raíz: rueda

Tenga en cuenta que tuve que hacer algunos cambios en las opciones de estadísticas.

Disfrutar,


Una adición a la respuesta de @Omid Ariyan son los permisos en los directorios. Agregue esto después de que el bucle for haya done en su script de pre-commit .

for DIR in $(find ./ -mindepth 1 -type d -not -path "./.git" -not -path "./.git/*" | sed ''s@^/./@@'') do # Save the permissions of all the files in the index echo $DIR";"`stat -c "%a;%U;%G" $DIR` >> $DATABASE done

Esto también guardará los permisos del directorio.