tag - ¿Cuáles son las consecuencias de usar receive.denyCurrentBranch en Git?
qué es un branch en git (6)
Por qué Git no te deja empujar a repositorios no desnudos
El cartel original dice:
Una solución es ejecutar el siguiente comando:
git config receive.denyCurrentBranch ignore
Después de esto, funciona, pero me gustaría saber por qué necesito usar esta opción. ¿Es esta la única opción? ¿Cuáles son las consecuencias de hacer esto?
Como señalo en mi respuesta a una pregunta similar , desde la versión 1.6.2 de Git , Git no le permitirá presionar a un repositorio no desnudo por defecto . Esto se debe a que el comando git push
solo actualiza las referencias de rama y HEAD
en el repositorio remoto. Lo que no hace es actualizar también el área de trabajo y el área de ensayo en ese control remoto no desnudo.
Como consecuencia, cuando usa el git status
en el repositorio remoto, verá que el estado previo del repositorio aún está presente en la copia de trabajo (y se encuentra en el índice):
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: previous-state.txt
Si observa el mensaje de error que recibió la primera vez que intentó ingresar a su repositorio remoto no vacío con la configuración receive.denyCurrentBranch
establecida en el valor de refuse
predeterminado, verá que el mensaje básicamente le dice lo mismo:
error: refusing to update checked out branch: refs/heads/master
error: By default, updating the current branch in a non-bare repository
error: is denied, because it will make the index and work tree inconsistent
error: with what you pushed, and will require ''git reset --hard'' to match
error: the work tree to HEAD.
error:
error: You can set ''receive.denyCurrentBranch'' configuration variable to
error: ''ignore'' or ''warn'' in the remote repository to allow pushing into
error: its current branch; however, this is not recommended unless you
error: arranged to update its work tree to match what you pushed in some
error: other way.
Realmente deberías empujar a los repositorios de Git desnudos
Como se señala en algunas de las otras respuestas , en realidad no deberías empujar a un repositorio no desnudo, por las razones que señalé anteriormente, y que Git mismo te está diciendo.
Así que, como dice esta respuesta , una forma sencilla de convertir un repositorio existente no desnudo en uno simple es recolocarlo como un repositorio simple:
git clone --bare old-repo
O podría tratar de jugar con la configuración de configuración core.bare
, como se detalla en esta respuesta .
Tengo un repositorio de Git. He clonado el repositorio y puedo comprometer mis cambios locales. Cuando envío mis cambios al servidor, funciona.
Tan pronto como creo una sucursal, pago por la sucursal, comprometo mi trabajo y luego pago la rama maestra. Luego fusiono mis cambios locales en la rama principal. Cuando intento presionar al servidor obtengo la siguiente excepción:
Welcome to Git (version 1.7.11-preview20120620)
Run ''git help git'' to display the help index.
Run ''git help <command>'' to display help for specific commands.
$ git push origin master:master
Counting objects: 9, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (8/8), 13.68 KiB, done.
Total 8 (delta 2), reused 1 (delta 0)
Unpacking objects: 100% (8/8), done.
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require ''git reset --hard'' to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set ''receive.denyCurrentBranch'' configuration variable to
remote: error: ''ignore'' or ''warn'' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: ''receive.denyCurrentBranch'' configuration variable to ''refuse''.
To c:/jGit
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to ''c:/gitRepository''
Una solución es ejecutar el siguiente comando:
git config receive.denyCurrentBranch ignore
Después de esto, funciona, pero me gustaría saber por qué necesito usar esta opción. ¿Es esta la única opción? ¿Cuáles son las consecuencias de hacer esto?
Lo que realmente me gustaría hacer es crear ramas, fusionarlas en la rama principal y luego enviar mis cambios al servidor.
Autopsia del problema
Cuando se desprotege una sucursal, la confirmación agregará una nueva confirmación con la cabeza de la sucursal actual como su padre y moverá la cabeza de la sucursal para que sea la nueva confirmación.
Asi que
A ← B
↑
[HEAD,branch1]
se convierte
A ← B ← C
↑
[HEAD,branch1]
Pero si alguien pudiera presionar a esa rama en medio, el usuario se metería en lo que git llama el modo de cabeza separada:
A ← B ← X
↑ ↑
[HEAD] [branch1]
Ahora el usuario ya no está en la rama1, sin haber solicitado explícitamente verificar otra rama. Peor aún, el usuario ahora se encuentra fuera de cualquier sucursal y cualquier compromiso nuevo estará colgando:
[HEAD]
↓
C
↙
A ← B ← X
↑
[branch1]
Hipotéticamente, si en este punto, el usuario visita otra sucursal, este compromiso se convierte en un juego justo para el recolector de basura de Git.
Creo que un repositorio no desnudo puede ser útil cuando el usuario configura el gancho de actualización de git para implementarlo desde el propio repositorio después de que sucedió el envío. Simplemente no te olvides de reiniciar el repositorio. Si pierde los archivos de paso no rastreará el estado real ...
Debería tener un repositorio vacío en el servidor, no uno con un árbol de trabajo desprotegido. Git le dice que se rehúsa a sobrescribir la rama que está actualmente desprotegida en el servidor.
Consulte esta respuesta para obtener información sobre cómo convertir su repositorio no vacío en el servidor en uno simple.
El servidor al que está presionando debería usar un repositorio simple.
Tuve el mismo error y necesitaba que el repositorio se ejecutara como una página de prueba de desarrollo en línea (es decir, supongo, para mantener un repositorio no vacío). Espero haberlo resuelto iniciando el repositorio con esta serie de comandos (desde git 2.3):
git init
git config --global user.email "[email protected]"
git config --global user.name "Your Name"
git commit
git config receive.denyCurrentBranch updateInstead
Como se ve aquí: no puede ingresar al repositorio de git