tab - Error de inserción de Git ''[remoto rechazado] maestro-> maestro(la rama está actualmente retirada)''
git tags best practices (30)
Ayer, publiqué una pregunta sobre cómo clonar un repositorio Git de una de mis máquinas a otra. ¿Cómo puedo ''clonar Git '' de otra máquina? .
Ahora puedo clonar con éxito un repositorio Git de mi fuente (192.168.1.2) a mi destino (192.168.1.1).
Pero cuando hice una edición en un archivo, un git commit -a -m "test"
y un git push
, obtengo este error en mi destino (192.168.1.1):
git push
[email protected]''s password:
Counting objects: 21, done.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 1010 bytes, done.
Total 11 (delta 9), reused 0 (delta 0)
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.
error:
error: To squelch this message and still keep the default behaviour, set
error: ''receive.denyCurrentBranch'' configuration variable to ''refuse''.
To git+ssh://[email protected]/media/LINUXDATA/working
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to ''git+ssh://[email protected]/media/LINUXDATA/working''
Estoy usando dos versiones diferentes de Git (1.7 en el control remoto y 1.5 en la máquina local). ¿Es esa una posible razón?
Resumen
No puede pasar a la única rama de un repositorio de un repositorio porque se enredaría con el usuario de ese repositorio de una manera que probablemente termine con la pérdida de datos e historial . Pero puede empujar a cualquier otra rama del mismo repositorio.
Como los repositorios no tienen ninguna rama desprotegida, siempre puede enviar a cualquier rama de un repositorio.
Existen múltiples soluciones, dependiendo de sus necesidades.
Solución 1: usar un repostorio desnudo
Como se sugirió, si en una máquina no necesita el directorio de trabajo, puede pasar a un repositorio simple. Para evitar meterse con el repositorio, simplemente puede clonarlo:
machine1$ cd ..
machine1$ mv repo repo.old
machine1$ git clone --bare repo.old repo
Ahora puedes empujar todo lo que quieras a la misma dirección que antes.
Solución 2: Empuje hacia una sucursal sin check-out
Pero si necesita revisar el código en su <remote>
, entonces puede usar una rama especial para empujar. Digamos que en su repositorio local ha llamado a su origin
remoto y está en el maestro de sucursal. Entonces podrias hacer
machine2$ git push origin master:master+machine2
Entonces necesitas fusionarlo cuando estés en el repositorio remoto de origin
:
machine1$ git merge master+machine2
Autopsia del problema
Cuando una rama está desprotegida, la confirmación agregará una nueva confirmación con la cabeza de la rama actual como su padre y moverá la cabeza de la rama para que sea la nueva confirmación.
Asi que
A ← B
↑
[HEAD,branch1]
se convierte en
A ← B ← C
↑
[HEAD,branch1]
Pero si alguien pudiera empujar a esa rama en medio, el usuario se pondría en lo que git llama modo de cabeza separada :
A ← B ← X
↑ ↑
[HEAD] [branch1]
Ahora el usuario ya no está en Branch1, sin haber pedido explícitamente que revise otra rama. Peor aún, el usuario ahora está fuera de cualquier rama , y cualquier nueva confirmación simplemente estará colgando :
[HEAD]
↓
C
↙
A ← B ← X
↑
[branch1]
Hipotéticamente, si en este punto, el usuario verifica otra rama, entonces este compromiso se convierte en un juego justo para el recolector de basura de Git.
Tienes 3 opciones
Tire y empuje de nuevo:
git pull; git push
Empuje en diferentes ramas:
git push origin master:foo
y fusionarlo en remoto (ya sea por
git
o pull-request )git merge foo
rebase
(no se recomienda a menos que haya cambiado las confirmaciones deliberadamente a través derebase
)git push origin master -f
Si aún se rechaza, deshabilite
denyCurrentBranch
en el repositorio remoto:git config receive.denyCurrentBranch ignore
Acabo de tener el mismo error mientras empecé a aprender Git . ¡Algunas de las otras respuestas claramente no son para alguien nuevo en Git!
(Voy a utilizar términos no técnicos para transmitir la idea). De todos modos, lo que está sucediendo es que tiene dos repositorios, uno es el original que hizo primero y el otro el trabajo que acaba de hacer.
Ahora mismo estás en tu repositorio de trabajo y estás usando la rama "maestra". Pero también está "conectado" en su repositorio original a la misma rama "maestra". Ahora que estás "conectado" en el original, Git teme que puedas estropearlo porque podrías estar trabajando en el original y arruinar las cosas. Por lo tanto, debe volver al repositorio original y hacer un "git checkout someotherbranch", y ahora puede presionar sin problemas.
Espero que esto ayude.
Aquí hay una prueba que puede hacer para ver cómo funcionan las cosas del servidor:
Imagine que tiene una estación de trabajo y un servidor con un sitio en vivo alojado en él y desea actualizar este sitio de vez en cuando (esto también se aplica a una situación en la que dos desarrolladores envían su trabajo de un lado a otro a través de un intermediario).
Inicialización
Cree un directorio en su computadora local y cd
en él, luego ejecute estos comandos:
# initialization
git init --bare server/.git
git clone server content
git clone server local
- Primero crea un directorio de
server
desnudo (observe el .git al final). Este directorio servirá como un contenedor para sus archivos de repositorio solamente. - Luego, clona el repositorio de tu servidor en un directorio de
content
recién creado. Este es su directorio de producción / en vivo que será servido por el software de su servidor. - Los dos primeros directorios residen en su servidor, el tercero es un directorio local en su estación de trabajo.
Flujo de trabajo
Ahora aquí está el flujo de trabajo básico:
Ingrese al directorio
local
, cree algunos archivos y confírmelos. Finalmente empujarlos al servidor:# create crazy stuff git commit -av git push origin master
Ahora ingrese el directorio de
content
y actualice el contenido del servidor:git pull
Repita 1-2. En este caso, el
content
puede ser otro desarrollador que también puede enviar al servidor, ylocal
como usted puede obtener de él.
Con unos pocos pasos de configuración, puede implementar fácilmente cambios en su sitio web utilizando una sola línea como
git push production
Lo que es agradable y simple, y no tiene que iniciar sesión en el servidor remoto y hacer una extracción o cualquier cosa. ¡Tenga en cuenta que esto funcionará mejor si no utiliza su verificación de producción como una rama de trabajo! (El OP estaba trabajando en un contexto ligeramente diferente, y creo que la solución de @Robert Gould lo abordó bien. Esta solución es más adecuada para la implementación en un servidor remoto).
Primero necesita configurar un repositorio simple en algún lugar de su servidor, fuera de su raíz web.
mkdir mywebsite.git
cd mywebsite.git
git init --bare
Luego crea archivos hooks/post-receive
:
#!/bin/sh
GIT_WORK_TREE=/path/to/webroot/of/mywebsite git checkout -f
Y hacer el archivo ejecutable:
chmod +x hooks/post-receive
En su máquina local,
git remote add production [email protected]:mywebsite.git
git push production +master:refs/heads/master
¡Todo listo! Ahora, en el futuro, puede utilizar git push production
para implementar sus cambios.
El crédito para esta solución va a http://sebduggan.com/blog/deploy-your-website-changes-using-git/ . Busque allí una explicación más detallada de lo que está pasando.
De acuerdo, en caso de que desee un repositorio remoto normal, cree una rama adicional y verifíquelo. Empújelo en una rama (que no está desprotegida) y combínela con una que esté activa más tarde después de presionar localmente.
Por ejemplo, en un servidor remoto:
git branch dev
git checkout dev
En la configuración local:
git push
En el servidor remoto:
git merge dev
De hecho, establecer el control remoto en una rama no verificada es suficiente. Después de que verificaste tu control remoto en una rama diferente, puedes presionar.
El mensaje de error describe lo que ha sucedido. Las versiones más modernas de Git se niegan a actualizar una sucursal a través de un empuje si esa rama está activada.
La forma más fácil de trabajar entre dos repositorios no desnudos es a
siempre actualice los repositorios mediante extracción (o captura y fusión) o, si tiene que hacerlo,
presionando a una rama separada (una rama de importación) y luego fusionando esa rama en la rama maestra en la máquina remota.
El motivo de esta restricción es que la operación de inserción solo opera en el repositorio remoto de Git, no tiene acceso al índice ni al árbol de trabajo. Por lo tanto, si se permite, un empuje en la rama extraída cambiaría el HEAD
para que sea inconsistente con el índice y el árbol de trabajo en el repositorio remoto.
Esto haría que sea muy fácil cometer un cambio accidentalmente que deshace todos los cambios impulsados y también hace que sea muy difícil distinguir entre los cambios locales que no se han confirmado y las diferencias entre la nueva HEAD
, el índice y el árbol de trabajo que se han realizado. Ha sido causado por empujar moviendo la HEAD
.
Estoy seguro de que la mayoría de las personas que vean esta pregunta se detendrán en las primeras dos grandes respuestas, pero todavía me gustaría ofrecer mi solución.
Tuve una configuración de proyecto web Eclipse + EGit cuando encontré el error descrito. Lo que me ayudó fue simplemente usar la aplicación GitHub, que parecía resolver mágicamente el problema. Si bien EGit siempre rechazaría el impulso, la aplicación de escritorio GitHub simplemente se encogería de hombros y empujaría mis cambios. Tal vez maneja la situación de inicio de sesión múltiple con más gracia.
Las versiones más antiguas de Git se utilizaban para permitir la inserción en la rama actualmente retirada de un repositorio no desnudo.
Resulta que esto era una cosa terriblemente confusa para permitir. Así que agregaron el mensaje de advertencia que ves, lo que también es terriblemente confuso.
Si el primer repositorio está actuando como un servidor, conviértalo en un repositorio simple, como lo recomiendan las otras respuestas, y termine con él.
Sin embargo, si necesita tener una rama compartida entre dos repositorios que están en uso, puede lograrlo con la siguiente configuración
Repo1: actuará como servidor y también se utilizará para el desarrollo
Repo2 - será solo para desarrollo
Config Repo1 de la siguiente manera
Crear una rama para compartir el trabajo.
git branch shared_branch
Para estar seguro, también debe crear un $ (REPO) .git / hooks / update que rechace cualquier cambio a cualquier otra cosa que no sea shared_branch, porque no quiere que la gente se meta con sus sucursales privadas.
repo1/.git/hooks (GIT_DIR!)$ cat update
#!/bin/sh
refname="$1"
oldrev="$2"
newrev="$3"
if [ "${refname}" != "refs/heads/shared_branch" ]
then
echo "You can only push changes to shared_branch, you cannot push to ${refname}"
exit 1
fi
Ahora cree una sucursal local en repo1 donde realizará su trabajo real.
git checkout -b my_work --track shared_branch
Branch my_work set up to track local branch shared_branch.
Switched to a new branch ''my_work''
(Es posible que necesite git config --global push.default upstream
en git config --global push.default upstream
para que git push
funcione)
Ahora puedes crear repo2 con
git clone path/to/repo1 repo2
git checkout shared_branch
En este punto, tiene la configuración de repo1 y repo2 para trabajar en las sucursales locales que presionan y shared_branch
de shared_branch
en repo1, sin tener que preocuparse por ese mensaje de error o tener el directorio de trabajo desincronizado en repo1. Cualquier flujo de trabajo normal que uses debería funcionar.
Me gusta la idea de tener un repositorio utilizable en el cuadro remoto, pero en lugar de una rama ficticia, me gusta usar:
git checkout --detach
Esta parece ser una característica muy nueva de Git : estoy usando la versión 1.7.7.4 de git.
Puede evitar esta "limitación" editando .git/config
en el servidor de destino. Agregue lo siguiente para permitir que un repositorio de git se envíe, incluso si está "desprotegido":
[receive]
denyCurrentBranch = warn
o
[receive]
denyCurrentBranch = false
El primero permitirá el empuje mientras advierte la posibilidad de desordenar la rama, mientras que el segundo solo lo permitirá silenciosamente.
Esto se puede usar para "implementar" el código en un servidor que no está destinado a la edición. Este no es el mejor enfoque, sino uno rápido para implementar el código.
Puede volver a crear el repositorio de su servidor y enviarlo desde su maestro de sucursal local al servidor maestro.
En su servidor remoto:
mkdir myrepo.git
cd myrepo.git
git init --bare
OK, desde su sucursal local:
git push origin master:master
Simplemente puede convertir su repositorio remoto en un repositorio simple (no hay una copia de trabajo en el repositorio desnudo; la carpeta solo contiene los datos reales del repositorio).
Ejecute el siguiente comando en su carpeta de repositorio remoto:
git config --bool core.bare true
Luego borre todos los archivos excepto .git
en esa carpeta. Y luego podrás realizar git push
en el repositorio remoto sin ningún error.
Solo deberías estar empujando a un repositorio simple. Un repositorio simple es un repositorio que no tiene ramas desprotegidas. Si tuviera que copiar en un directorio de repositorio simple, solo vería el contenido de un directorio .git.
Tuve el mismo problema al usar Git para sincronizar repositorios en mi teléfono Android y computadora portátil. La solución para mí fue hacer un tirón en lugar de un empujón, como sugirió @CharlesBailey.
git push origin master
en el repositorio de Android falla para mí con los mismos mensajes de error que @ hap497 recibió debido a un empuje a un checkout sin reserva de un repositorio + copia de trabajo.
git pull droid master
en el repositorio de portátiles y trabajos de copia funciona para mí. Por supuesto, debe haber ejecutado previamente algo como git remote add droid /media/KINGSTON4GB/notes_repo/
.
Tuve el mismo problema. Para mí, uso Git push para mover código a mis servidores. Nunca cambio el código en el lado del servidor, así que esto es seguro.
En el repositorio, estás presionando para escribir:
git config receive.denyCurrentBranch ignore
Esto le permitirá cambiar el repositorio mientras se trata de una copia de trabajo.
Después de ejecutar un Git push, vaya a la máquina remota y escriba esto:
git checkout -f
Esto hará que los cambios que empujó se reflejen en la copia de trabajo de la máquina remota.
Tenga en cuenta que esto no siempre es seguro si realiza cambios en la copia de trabajo a la que está presionando.
Tuve que volver a ejecutar git --init
en un repositorio desnudo existente, y esto había creado un directorio .git
dentro del árbol de repositorio desnudo - Me di cuenta de que, después de escribir el git status
allí. Borré eso y todo estuvo bien otra vez :)
(Todas estas respuestas son geniales, pero en mi caso fue algo completamente diferente (por lo que puedo ver), como se describe).
Un artículo que encontré que podría ser útil para otros es Git en 5 minutos .
Tenía un proyecto Xcode bajo el control de versión de Git que quería enviar a una Ethernet virtual distribuida (VDE) que tengo en un DC. El VDE ejecuta Centos 5.
Ninguno de los artículos que leí sobre Git hablaba de repositorios simples. Todo sonaba tan simple hasta que probé lo que pensé que debería ser fácil provenir de un fondo SVN .
Las sugerencias aquí para hacer que el repositorio remoto funcione. Aún mejor para mis requisitos fue clonar el proyecto Xcode para projectname.git
, copiarlo al servidor remoto; Luego empuja mágicamente trabajado. El siguiente paso será lograr que Xcode presione sin errores acerca de las confirmaciones, pero por ahora estoy bien haciéndolo desde Terminal.
Asi que:
cd /tmp (or another other directory on your system)<br/>
git clone --bare /xcode-project-directory projectname.git<br/>
scp -r projectname.git [email protected]:repos/<br/>
Para impulsar cambios desde su proyecto Xcode después de que haya confirmado en Xcode:
cd /xcode-project-directory<br/>
git push [email protected]:repos/projectname.git<br/>
Estoy seguro de que hay una forma más suave y sofisticada de hacer lo anterior, pero como mínimo esto funciona. Para que todo quede claro, aquí hay algunas aclaraciones: /xcode-project-directory
es el directorio en el que está almacenado el proyecto de xcode. Probablemente sea /Users/Your_Name/Documents/Project_Name
.projectname es, literalmente, el nombre del proyecto, pero puede ser cualquier cosa que llames. Git no le importa, lo harás.
Para usar scp, necesita tener una cuenta de usuario en el servidor remoto que tenga acceso SSH . Cualquiera que esté ejecutando su propio servidor tendrá esto. Si está utilizando alojamiento compartido o similar, es posible que no tenga suerte.
remotehost.com
es el nombre de su host remoto. Podrías usar tan fácilmente su dirección IP. Solo para mayor claridad, estoy usando Gitosis en el host remoto con claves SSH, por lo que no me Gitosis las contraseñas cuando presiono. El artículo Hosting Git Repositories, the Easy (and Secure) Way te dice cómo configurar todo eso.
git config --local receive.denyCurrentBranch updateInstead
https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155
Use eso en el repositorio del servidor, y también actualiza el árbol de trabajo si no se produce una sobrescritura sin seguimiento.
Se agregó en Git 2.3 como lo mencionó VonC en los comentarios.
He compilado Git 2.3 y lo probé. Uso de la muestra:
git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead
cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master
cd ../server
ls
Salida:
a
b
Yay, b
fue empujado!
Lo que probablemente hiciste para causar esto:
Este tipo de cosas sucede cuando vas a golpear un pequeño programa. Estás a punto de cambiar algo que ya estaba funcionando, así que lanzas tu hechizo de deshacer perpetuo de nivel 3:
machine1:~/proj1> git init
y empiezas a añadir / cometer. Pero luego , el proyecto comienza a involucrarse más y desea trabajar en él desde otra computadora (como la computadora de su casa o computadora portátil), por lo que hace algo como:
machine2:~> git clone ssh://machine1/~/proj1
y clona y todo se ve bien, y así trabajas en tu código desde machine2.
Luego ... intenta empujar sus confirmaciones desde machine2, y aparece el mensaje de advertencia en el título.
El motivo de este mensaje es porque el repositorio de git que obtuvo se diseñó para ser usado solo para esa carpeta en machine1. Puedes clonar bien, pero empujar puede causar problemas. La forma "correcta" de administrar el código en dos ubicaciones diferentes es con un repositorio "simple", como se ha sugerido. Un repositorio simple no está diseñado para hacer ningún trabajo en él, está destinado a coordinar las confirmaciones de múltiples fuentes. Esta es la razón por la que la respuesta mejor calificada sugiere eliminar todos los archivos / carpetas que no sean la carpeta .git después de que git config --bool core.bare true
.
Aclarando la respuesta más calificada: muchos de los comentarios a esa respuesta dicen algo como "No borré los archivos que no son .git de la máquina1 y aún pude cometer desde la máquina2". Está bien. Sin embargo, esos otros archivos están completamente "divorciados" del repositorio de git, ahora. Ve a probar git status
allí y deberías ver algo como "fatal: esta operación debe ejecutarse en un árbol de trabajo". Por lo tanto, la sugerencia de eliminar los archivos no es para que funcione la confirmación desde machine2; es para no confundirse y pensar que git todavía está rastreando esos archivos. Pero, eliminar los archivos es un problema si aún desea trabajar en los archivos en machine1, ¿no es así?
Entonces, ¿qué deberías hacer realmente?
Depende de cuánto planea seguir trabajando en machine1 y machine2 ...
Si ha terminado de desarrollar desde machine1 y ha movido todo su desarrollo a machine2 ... simplemente haga lo que sugiere la mejor respuesta: git config --bool core.bare true
y luego, opcionalmente, elimine todos los archivos / carpetas. que .git de esa carpeta, ya que no están rastreados y es probable que causen confusión.
Si su trabajo en machine2 fue solo una vez, y no necesita continuar con el desarrollo allí ... entonces no se moleste en hacer un repo simple; sólo ftp / rsync / scp / etc. sus archivos de la máquina * 2 * encima de los archivos en la máquina * 1 *, confirme / presione desde la máquina * 1 *, y luego borre los archivos de la máquina * 2 *. Otros han sugerido crear una rama, pero creo que eso es un poco complicado si solo deseas combinar un poco de desarrollo que hiciste una sola vez desde otra máquina.
Si necesita continuar con el desarrollo en machine1 y machine2 ... entonces necesita configurar las cosas correctamente. Necesitas convertir tu repositorio en un simple, entonces necesitas hacer un clon de eso en machine1 para que trabajes. Probablemente la forma más rápida de hacerlo es hacerlo.
machine1:~/proj1> git config --bool core.bare true
machine1:~/proj1> mv .git/ ../proj1.git
machine1:~/proj1> cd ..
machine1:~> rm -rf proj1
machine1:~> git clone proj1.git
machine1:~> cd proj1
Muy importante: debido a que ha movido la ubicación del repositorio de proj1 a proj1.git, necesita actualizar esto en el archivo .git / config en machine2 . Después de eso, puedes confirmar tus cambios desde machine2. Por último, trato de mantener mis repositorios vacíos en una ubicación central, lejos de mis árboles de trabajo (es decir, no ponga ''proj1.git'' en la misma carpeta principal que ''proj1''). Le aconsejo que haga lo mismo, pero quería que los pasos anteriores sean lo más simples posible.
La mejor manera de hacer esto es:
mkdir ..../remote
cd ..../remote
git clone --bare .../currentrepo/
Esto clonará el repositorio, pero no hará ninguna copia de trabajo en .../remote
. Si observa el control remoto, verá un directorio creado, llamado currentrepo.git
, que es probablemente lo que desea.
Luego desde su repositorio local de Git:
git remote add remoterepo ..../remote/currentrepo.git
Después de hacer cambios, puedes:
git push remoterepo master
Mi solución (en uso)
- Checkout "master" en servidor remoto
- Trabajar localmente en la rama "dev"
- Empuje cambios a dev remoto
- Fusionar dev en maestro en control remoto
bingo
Necesitará cambiar el archivo de configuración en el servidor remoto una vez que haya creado un repositorio vacío (vacío), digamos
root@development:/home/git/repository/my-project# cat config
allí verás
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
Harás esto de falso a falso a verdadero y eliminé logallrefupdates = true (¡no estoy seguro de su uso!)
a
[core]
repositoryformatversion = 0
filemode = true
bare = true
Puedes probar siguiendo
$ git remote show origin
* remote origin
Fetch URL: my-portal@development:/home/XYZ/repository/XYZ
Push URL: my-portal@development:/home/XYZ/repository/XYZ
HEAD branch: (unknown)
Esta rama HEAD: (desconocido) se mostrará si no puede presionar. Por lo tanto, si no se conoce la rama HEAD, debe cambiar de desnudo a verdadero y después de presionar con éxito puede reutilizar el
git remote show origin
y tu verás
HEAD branch: master
Para mi solución de trabajo es:
A DISTANCIA:
git checkout -b some_tmp_name
EN LOCAL:
git push
A DISTANCIA:
git checkout master
git branch -d some_tmp_name
Pero esta no es la solución real, es solo una solución.
Usando esto para enviarlo a la rama ascendente remota, resolví este problema para mí:
git push <remote> master:origin/master
El control remoto no tenía acceso al repositorio anterior, por lo que esta era una buena manera de incluir los últimos cambios en ese control remoto.
Acabo de encontrarme con este problema con un repositorio git de implementación en Heroku .
No sé por qué Heroku tiene un repositorio no desnudo de su lado, pero como solución pude reiniciar el repositorio remoto y volver a cargarlo.
No debe usar la copia de Heroku de su repositorio como su único repositorio git para la colaboración, pero por si acaso, le diré claramente: No haga esto a menos que esté seguro de que tiene una copia completa de su repositorio almacenada de forma segura en otro lugar que no sea Heroku. Al hacer un reinicio se eliminarán los contenidos del repositorio.
Reiniciar:
- Instale el cinturón de herramientas Heroku (que contiene el cliente de línea de comandos) si aún no lo ha hecho.
Instala el plugin heroku-repo si aún no lo has hecho.
heroku plugins:install https://github.com/heroku/heroku-repo.git
Realice el restablecimiento, que elimina el repositorio y crea uno nuevo, vacío
heroku repo:reset
Empuje a su control remoto Heroku como lo haría normalmente; Se reupload todo.
Con Git, dos repositorios regulares (no desnudos) no pueden enviar / extraer archivos directamente de un lado a otro. Debe haber un repositorio desnudo intermediario. Aparentemente, es como una pareja casada que tiene un hijo, y la pareja se está divorciando. Los padres no se hablan, pero se comunicarán a través del niño.
Entonces, tienes un repositorio, clonas este repositorio a un repositorio simple, y luego clonas eso a un tercero. El primero y el tercero pueden intercambiar información a través del segundo repositorio, el simple. Supongo que esto tiene sentido, ya que no querría que alguien pueda registrar cosas en su repositorio sin su consentimiento, ya que eso podría causar conflictos de fusión y cosas por el estilo.
Entonces, aquí hay un ejemplo:
En PC, en ~ / espacio de trabajo
git init
echo "line 1" > afile.txt
git add .
git commit -m ‘initial import’
git clone --bare . ../remote-repository.git
git remote add origin ../remote-repository.git
git push --set-upstream origin master
En la computadora portátil, en ~ / espacio de trabajo (no haga git init, etc.)
git clone //LJZ-DELLPC/remote-repository.git/ .
// Luego haz varias confirmaciones, y presionalas:
echo "line 2" > afile.txt
git add afile.txt
git commit -m ''added line 2''
git push
Luego vuelve a la PC, en ~ / espacio de trabajo
git pull
// Luego haz varias confirmaciones, y presionalas:
git push
En la computadora portátil git pull
Etcétera..
Aquí hay un ejemplo concreto absoluto, todo en una máquina, copiado directamente desde la ventana de comandos, para que sepamos que no se han omitido pasos, que realmente funcionó, etc.
lylez@LJZ-DELLPC ~
$ cd gitdir
/home/lylez/gitdir
lylez@LJZ-DELLPC ~/gitdir
$ ls
lylez@LJZ-DELLPC ~/gitdir
$ mkdir repo1
lylez@LJZ-DELLPC ~/gitdir
$ cd repo1
/home/lylez/gitdir/repo1
lylez@LJZ-DELLPC ~/gitdir/repo1
$ git init
Initialized empty Git repository in /home/lylez/gitdir/repo1/.git/
lylez@LJZ-DELLPC ~/gitdir/repo1
$ echo "line 1" > afile.txt
lylez@LJZ-DELLPC ~/gitdir/repo1
$ git add afile.txt
lylez@LJZ-DELLPC ~/gitdir/repo1
$ git commit -m ''initial import''
[master (root-commit) f407e12] initial import
1 file changed, 1 insertion(+)
create mode 100644 afile.txt
lylez@LJZ-DELLPC ~/gitdir/repo1
$ git clone --bar . ../repo1-bare-clone
Cloning into bare repository ''../repo1-bare-clone''...
done.
lylez@LJZ-DELLPC ~/gitdir/repo1
$ git remote add origin ../repo1-bare-clone
lylez@LJZ-DELLPC ~/gitdir/repo1
$ git push --set-upstream origin master
Branch master set up to track remote branch master from origin.
Everything up-to-date
lylez@LJZ-DELLPC ~/gitdir/repo1
$ cd ..
lylez@LJZ-DELLPC ~/gitdir
$ ls
repo1 repo1-bare-clone
lylez@LJZ-DELLPC ~/gitdir
$ mkdir repo1-remote
lylez@LJZ-DELLPC ~/gitdir
$ cd repo1-remote
/home/lylez/gitdir/repo1-remote
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git clone ../repo1-bare-clone .
Cloning into ''.''...
done.
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ ls
afile.txt
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ echo "line 2" >> afile.txt
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git add afile.txt
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git commit -m ''added line 2''
[master 5ad31e0] added line 2
1 file changed, 1 insertion(+)
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 260 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
f407e12..5ad31e0 master -> master
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cd ../repo1
lylez@LJZ-DELLPC ~/gitdir/repo1
$ ls
afile.txt
lylez@LJZ-DELLPC ~/gitdir/repo1
$ cat afile.txt
line 1
lylez@LJZ-DELLPC ~/gitdir/repo1
$ git pull
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From ../repo1-bare-clone
f407e12..5ad31e0 master -> origin/master
Updating f407e12..5ad31e0
Fast-forward
afile.txt | 1 +
1 file changed, 1 insertion(+)
lylez@LJZ-DELLPC ~/gitdir/repo1
$ cat afile.txt
line 1
line 2
lylez@LJZ-DELLPC ~/gitdir/repo1
$ echo "line 3" >> afile.txt
lylez@LJZ-DELLPC ~/gitdir/repo1
$ git add afile.txt
lylez@LJZ-DELLPC ~/gitdir/repo1
$ git commit -m ''added line 3''
[master 3fa569e] added line 3
1 file changed, 1 insertion(+)
lylez@LJZ-DELLPC ~/gitdir/repo1
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 265 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../repo1-bare-clone
5ad31e0..3fa569e master -> master
lylez@LJZ-DELLPC ~/gitdir/repo1
$ cd ../repo1-remote/
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ ls
afile.txt
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
line 2
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git pull
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
5ad31e0..3fa569e master -> origin/master
Updating 5ad31e0..3fa569e
Fast-forward
afile.txt | 1 +
1 file changed, 1 insertion(+)
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
line 2
line 3
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git --version
git version 2.1.1
lylez@LJZ-DELLPC ~/gitdir/repo1-remote
Por si alguien lo encuentra útil. Para mi fue un problema de permisos de servidor git. Revisé el proyecto desde el principio y presioné un archivo simple y luego obtuve el mensaje "Push rechazado: Push to origin / master fue rechazado"
revisa tu .git/config
en el proyecto de destino:
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[receive]
denyCurrentBranch = updateInstead
Si el core. bare
es falso, puedes configurarlo en verdadero:
$ git config core.bare true
y luego en tu local push a control remoto:
git push remote_repo // suppose the destination repo is remote_repo
será un éxito, en el control remoto puede comprobar la versión de git.
$ git log -1
commit 0623b1b900ef7331b9184722a5381bbdd2d935ba
Author: aircraft < [email protected]>
Date: Thu May 17 21:54:37 2018 +0800
y ahora no puedes usar git en tu "área de trabajo":
$ git status
fatal: This operation must be run in a work tree
usted debe bare.bare
volver a falso.
$ git config core.bare false