cómo controlar la propiedad de los files auto-push a un repository de destino git mediante commit hooks?

Creé un repo desnudo @

/srv/repos/test 

establezco propiedad para wwwrun: www con SUID + set de bits GUID

 chown -R wwwrun:www /srv/repos/hub chmod ug+s /srv/repos/hub ls -ald /srv/repos/test drwsrws---+ 10 wwwrun www 4.0K Mar 7 21:28 /srv/repos/hub/ 

cloné el repository en una webroot y cambié su propiedad,

 git clone /srv/repos/hub /srv/www/siteA chown -R wwwrun:www /srv/www/siteA 

por conveniencia, defino un control remoto

 cd /srv/www/siteA git remote add HUB /srv/repos/hub 

luego crea ganchos post-commit y post-update para mantener las cosas sincronizadas,

 vi /srv/www/siteA/.git/hooks/post-commit #!/bin/sh git push HUB vi /srv/repos/hub/hooks/post-update #!/bin/sh cd /srv/www/siteA || exit unset GIT_DIR git pull HUB master exec git-update-server-info 

como mi usuario normal, busco HUB

 whoami locuse cd ~ git clone /srv/repos/hub WORK ls -ald WORK drwxr-xr-x 10 locuse users 4.0K Mar 7 21:44 WORK/ 

hacer un cambio, comprometerse y empujar,

 cd WORK touch touch_file ls -al touch_file -rw-r--r-- 1 locuse users 0 Mar 7 21:44 touch_file git add -A git commit -m "add test" git push 

luego verificando que el gancho se disparó y la actualización se envió a la webroot,

 ls -al /srv/www/siteA/touch_file -rw-rw----+ 1 locuse www 0 Mar 7 21:45 /srv/www/siteA/touch_file 

el file está allí, como se esperaba.

pero, no es la propiedad del usuario que quiero, es decir, es user = 'locuse' not user = 'wwwrun'.

en este caso de uso específico, ¿cuál es la forma correcta de asegurar que i, INSTEAD, siempre termine automáticamente con,

 ls -al /srv/www/siteA/touch_file -rw-rw----+ 1 wwwrun www 0 Mar 7 21:45 /srv/www/siteA/touch_file 

? es decir, todo siempre se promociona a / srv / www / siteA solo como wwwrun: www.

algo en un gancho, supongo?

Sé que podría agregar

 chown -R wwwrun:www /srv/www/siteA 

al enganche post-commit, que funciona bien para un tree pequeño, pero se empantana en cada commit / update hacia abajo si es grande (cuál será).

quizás si pudiera atraer de manera eficiente solo el compromiso actual …?

esto funciona,

 vi /srv/repos/hub/hooks/post-update #!/bin/sh cd /srv/www/siteA || exit unset GIT_DIR - git pull HUB master + git fetch HUB master + files=`git diff ..FETCH_HEAD --name-only --diff-filter=ACMRTUXB` + git merge FETCH_HEAD + for file in $files + do + sudo chown wwwrun:www $file + done exec git-update-server-info 

chown execs solo en los files identificados como en el set de confirmación: pequeño y rápido.

Tuve el mismo problema y después de algunas investigaciones descubrí que no hay una solución si actualiza el repository desnudo (HUB) a través de SSH, ya que los ganchos son ejecutados por el usuario que se conectó al repository HUB (en nuestro caso git) . Si desea evitar dar el permiso de chown / chmod al usuario de git (problema de security), la única solución es crear un trabajo de cron para mantener actualizado el repository. Hice este script (mi primer script bash) modificando el anterior y agregando también una notificación por correo electrónico sobre la actualización exitosa:

 #!/bin/sh # web repository directory REPO_DIR="/srv/www/siteA" # remote repository REMOTE_REPO="HUB" # public branch of the remote repository (only this branch well be public accessible trough the web server) REMOTE_REPO_BRANCH="master" # email address where receive notification EMAIL_TO="your@email.com" # sender email address and name SENDER_ADDR="sender@email.com" SENDER_NAME="sender name" # tmp file that contain email body TMP_MSG_FILE="emailmessage.txt" cd $REPO_DIR || exit unset GIT_DIR echo "fetching changes..." git fetch $REMOTE_REPO $REMOTE_REPO_BRANCH files=`git diff ..FETCH_HEAD --name-only --diff-filter=ACDMRTUXB` if [[ -n $files ]]; then echo "changes found for the following file:" echo ${files[*]} echo "merging changes" git merge FETCH_HEAD echo "sending email" SUBJECT="GIT: Web Directory Updated" TMP_MSG_FILE="emailmessage.txt" echo "following file are been updated/created/deleted: "> $TMP_MSG_FILE echo ${files[*]} >>$TMP_MSG_FILE echo "Working directory:" >>$TMP_MSG_FILE echo "$repo_dir" >>$TMP_MSG_FILE mutt -e "unmy_hdr from; my_hdr From: $SENDER_ADDR" -e "set realname='$SENDER_NAME' " -s "$SUBJECT" $EMAIL_TO < $TMP_MSG_FILE else echo "no changes found" fi