¿Cómo verifico si el repositorio remoto ha cambiado y necesito extraer?
Ahora uso este simple script:
git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1
Pero es bastante pesado.
¿Hay una mejor manera? La solución ideal verificaría todas las ramas remotas y devolvería los nombres de las ramas modificadas y el número de nuevas confirmaciones en cada una.
git fetch -v --dry-run
es lo que necesitas.Respuestas:
Primer uso
git remote update
, para actualizar sus referencias remotas. Luego puede hacer una de varias cosas, como:git status -uno
le dirá si la rama que está rastreando está adelante, atrás o ha divergido. Si no dice nada, lo local y lo remoto son lo mismo.git show-branch *master
le mostrará las confirmaciones en todas las ramas cuyos nombres terminan en 'maestro' (por ejemplo, maestro y origen / maestro ).Si usa
-v
congit remote update
(git remote -v update
) puede ver qué ramas se actualizaron, por lo que realmente no necesita más comandos.Sin embargo, parece que desea hacer esto en un script o programa y terminar con un valor verdadero / falso. Si es así, hay formas de verificar la relación entre su compromiso HEAD actual y el jefe de la rama que está rastreando, aunque dado que hay cuatro resultados posibles, no puede reducirlo a una respuesta sí / no. Sin embargo, si está preparado para hacer un
pull --rebase
ejercicio, entonces puede tratar "lo local está detrás" y "lo local ha divergido" como "necesidad de tirar", y los otros dos como "no es necesario tirar".Puede obtener la identificación de confirmación de cualquier referencia usando
git rev-parse <ref>
, por lo que puede hacer esto para master y origin / master y compararlos. Si son iguales, las ramas son iguales. Si son desiguales, desea saber cuál está por delante del otro. El usogit merge-base master origin/master
le dirá el antepasado común de ambas ramas, y si no han divergido, será lo mismo que una u otra. Si obtienes tres identificadores diferentes, las ramas se han separado.Para hacerlo correctamente, por ejemplo, en un script, debe poder hacer referencia a la rama actual y a la rama remota que está rastreando. La función bash prompt-setting
/etc/bash_completion.d
tiene un código útil para obtener nombres de sucursales. Sin embargo, probablemente no necesite obtener los nombres. Git tiene algunas ordenadas shorthands para referirse a ramas y commits (como se documenta engit rev-parse --help
). En particular, puede usarlo@
para la rama actual (suponiendo que no esté en un estado de cabeza separada) y@{u}
para su rama ascendente (por ejemploorigin/master
). Porgit merge-base @ @{u}
lo tanto , devolverá el (hash del) commit en el que la rama actual y su flujo ascendente divergengit rev-parse @
ygit rev-parse @{u}
le dará los hash de los dos consejos. Esto se puede resumir en el siguiente script:Nota: las versiones anteriores de git no permitían
@
por sí mismas, por lo que es posible que deba usarlas@{0}
.La línea le
UPSTREAM=${1:-'@{u}'}
permite opcionalmente pasar una rama ascendente explícitamente, en caso de que desee verificar con una rama remota diferente a la configurada para la rama actual. Esto normalmente sería de la forma remotename / branchname . Si no se proporciona ningún parámetro, el valor predeterminado es@{u}
.La secuencia de comandos asume que has hecho uno
git fetch
ogit remote update
primero, para actualizar las ramas de seguimiento. No incluí esto en el script porque es más flexible poder realizar la recuperación y la comparación como operaciones separadas, por ejemplo, si desea comparar sin recuperar porque ya obtuvo recientemente.fuente
git status -s -u no
, lo que da un resultado más corto quegit status -u no
.git remote -v update
. Mira la salida degit remote --help
para una explicación más completa.@{u}
funciona con git 1.8.3.2 pero@
no funciona. Sin embargo@
funciona con1.8.5.4
. Moraleja de la historia: git sigue mejorando y vale la pena tener la versión más reciente que puedas.Si tienes una rama aguas arriba
Si no tienes una rama aguas arriba
Compara las dos ramas:
Por ejemplo:
(Supongo que
origin/master
es su rama de seguimiento remoto)Si hay confirmaciones enumeradas en el resultado anterior, entonces tiene cambios entrantes: debe fusionar. Si no se enumeran confirmaciones,
git log
entonces no hay nada que fusionar.Tenga en cuenta que esto funcionará incluso si está en una rama de características, que no tiene un control remoto de seguimiento, ya que se refiere explícitamente en
origin/master
lugar de usar implícitamente la rama ascendente recordada por Git.fuente
git fetch; git log HEAD.. --oneline
se puede usar una notación más corta si hay una rama remota predeterminada para la local.git rev-list HEAD...origin/master --count
le dará el número total de confirmaciones "diferentes" entre los dos.Si esto es para un script, puede usar:
(Nota: el beneficio de esta respuesta frente a las respuestas anteriores es que no necesita un comando separado para obtener el nombre actual de la sucursal. "git rev-parse --help" para más detalles).
fuente
git rev-parse @{u}
realmente el último commit sin ungit fetch
?==
embargo , su lógica está usando lo que significa "si NO hay cambios desde la parte superior". Solía!=
buscar "si HAY cambios desde la parte superior" para mi aplicación. ¡No te olvides degit fetch
primero!@
Es la abreviatura deHEAD
BTW.@{u}
por ejemplogit rev-parse '@{u}'
El comando
enumerará el encabezado actual en el control remoto; puede compararlo con un valor anterior o ver si tiene el SHA en su repositorio local.
fuente
git rev-list HEAD...origin/master --count
le dará el número total de confirmaciones "diferentes" entre los dos.git fetch
o elgit remote update
primero.git status
También muestra un recuento, por cierto...
es "commits en origen / master, restando HEAD" (es decir, número de commits detrás). Considerando que,...
es la diferencia simétrica (es decir, adelante y atrás)fetch
.He aquí un golpe de una sola línea que compara CABEZA de la rama actual de hash cometen en contra de su rama ascendente a distancia, sin pesada
git fetch
ogit pull --dry-run
las operaciones necesarias:Así es como esta línea algo densa se divide:
$(x)
Bash .git rev-parse --abbrev-ref @{u}
devuelve una referencia ascendente abreviada (porigin/master
. ej. ), que luego se convierte en campos separados por espacios mediante elsed
comando canalizado , porigin master
. ej .git ls-remote
que devuelve el commit principal de la rama remota. Este comando se comunicará con el repositorio remoto. Elcut
comando canalizado extrae solo el primer campo (el hash de confirmación), eliminando la cadena de referencia separada por tabulaciones.git rev-parse HEAD
devuelve el hash de confirmación local.[ a = b ] && x || y
completa la línea única: esta es una comparación de cadenas de Bash=
dentro de una construcción de prueba[ test ]
, seguida de las construcciones de lista y lista&& true || false
.fuente
Te sugiero que veas el script https://github.com/badele/gitcheck . He codificado este script para verificar de una sola vez todos sus repositorios Git, y muestra quién no se ha comprometido y quién no ha empujado / retirado.
Aquí un resultado de muestra:
fuente
git mrepo -c
Esto mostrará todas las confirmaciones pendientes.Basé esta solución en los comentarios de @jberger.
fuente
...
parece ser una parte válida de su solución.Ya hay muchas respuestas ricas en funciones e ingeniosas. Para proporcionar un poco de contraste, podría conformarme con una línea muy simple.
fuente
Creo que la mejor manera de hacer esto sería:
Suponiendo que tiene registrada esta especificación de referencia. Debería, si ha clonado el repositorio, de lo contrario (es decir, si el repositorio se creó localmente de novo y se envió al control remoto), debe agregar la especificación de referencia explícitamente.
fuente
El siguiente script funciona perfectamente.
fuente
Haría el camino sugerido por brool. El siguiente script de una línea toma el SHA1 de su última versión confirmada y lo compara con el del origen remoto, y extrae los cambios solo si difieren. Y es aún más ligero de las soluciones basadas en
git pull
ogit fetch
.fuente
git rev-parse --verify HEAD
git log --pretty=%H ...refs/heads/master^
para obtener el SHA1 de su última versión confirmada, y luego ejecutegit ls-remote origin -h refs/heads/master |cut -f1
para obtener el SHA1 del origen remoto. Estos dos son comandos git y no tienen nada que ver con bash. Lo que hace bash dentro de los corchetes es comparar la salida del primer comando con el segundo, y si son iguales, devuelve verdadero y se ejecutagit pull
.git pull
". Sé que estoy siendo quisquilloso, pero solo para salvar a alguien de la confusión, eso debería ser "y si no son iguales". Además, por cualquier razón, el primer comando git no funciona para mí. (Estoy en git2.4.1
.) Así que solo estoy usando en sugit log --pretty=%H master | head -n1
lugar. Pero no estoy seguro si eso es exactamente lo mismo.Si ejecuta este script, probará si la rama actual necesita un
git pull
:Es muy conveniente ponerlo como un compromiso previo de gancho Git para evitar
cuando tu
commit
antespulling
.Para usar este código como un enlace, simplemente copie / pegue el script en
y
fuente
Solo quiero publicar esto como una publicación real, ya que es fácil pasarlo por alto en los comentarios.
La respuesta correcta y mejor para esta pregunta fue dada por @Jake Berger, muchas gracias amigo, todos necesitan esto y todos pierden esto en los comentarios. Entonces, para todos los que luchan con esto, esta es la respuesta correcta, solo use la salida de este comando para saber si necesita hacer un git pull. si la salida es 0, entonces obviamente no hay nada que actualizar.
@stackoverflow, dale unas campanas a este tipo. Gracias @ Jake Berger
fuente
Ejecute
git fetch (remote)
para actualizar sus referencias remotas, le mostrará las novedades. Luego, cuando finalice la compra de su sucursal local, le mostrará si está detrás del flujo ascendente.fuente
git status
lo mostrará.git pull --dry-run
, pero creo que es demasiado pesado para que se ejecute un script cron cada minuto.fetch
, no va a hacer mucho más que verificar el estado. Si necesita una reacción muy rápida y liviana en las actualizaciones remotas, es posible que desee considerar enganchar algún tipo de notificaciones al repositorio remoto.Todas esas sugerencias complejas mientras la solución es tan corta y fácil:
fuente
git remote update
ejecutarse antes de su código, para obtener la última información de confirmación de origengit remote update
No debería agregarse antes de losgit show
comandos?Aquí está mi versión de un script Bash que verifica todos los repositorios en una carpeta predefinida:
https://gist.github.com/henryiii/5841984
Puede diferenciar entre situaciones comunes, como tirar necesario y empujar necesario, y es multiproceso, por lo que la búsqueda ocurre de una vez. Tiene varios comandos, como extracción y estado.
Coloque un enlace simbólico (o el script) en una carpeta en su ruta, luego funciona como
git all status
(, etc.). Solo admite origen / maestro, pero se puede editar o combinar con otro método.fuente
enumerará todo lo referenciado en cualquier control remoto que no esté en su repositorio. Tomar un poco los cambios de referencia remotos a cosas que ya tenía (por ejemplo, restablecimientos a confirmaciones anteriores) toma un poco más:
fuente
Tal vez esto, si desea agregar una tarea como crontab:
fuente
Usando regexp simple:
fuente
Utilizo una versión de un script basada en la respuesta de Stephen Haberman:
Suponiendo que se llama a este script
git-fetch-and-rebase
, se puede invocar con un argumento opcionaldirectory name
del repositorio Git local para realizar la operación. Si se llama al script sin argumentos, se supone que el directorio actual es parte del repositorio de Git.Ejemplos:
Está disponible aquí también.
fuente
Después de leer muchas respuestas y múltiples publicaciones, y pasar medio día probando varias permutaciones, esto es lo que se me ocurrió.
Si está en Windows, puede ejecutar este script en Windows utilizando Git Bash proporcionado por Git para Windows (instalación o portátil).
Este script requiere argumentos
El guión
Si hay un cambio tal como lo imprime el script, puede proceder a buscar o extraer. El script puede no ser eficiente, pero hace el trabajo por mí.
Actualización - 2015-10-30: stderr a dev nulo para evitar imprimir la URL con la contraseña en la consola.
fuente
Para los usuarios de Windows que terminan en esta pregunta buscando esto, he modificado algunas de las respuestas en un script de PowerShell. Ajuste según sea necesario, guárdelo en un
.ps1
archivo y ejecútelo a pedido o programado si lo desea.fuente
Debido a que la respuesta de Neils me ayudó mucho, aquí hay una traducción de Python sin dependencias:
hth
fuente
También puede encontrar un guión de Phing que hace eso ahora.
Necesitaba una solución para actualizar mis entornos de producción automáticamente y estamos muy contentos gracias a este script que estoy compartiendo.
El script está escrito en XML y necesita Phing .
fuente