De esta respuesta.
- Haz una búsqueda:
git fetch
. - Obtener cuántas confirmaciones está detrás de la rama actual:
behind_count = $(git rev-list --count [email protected]{u})
. - Obtener cuántos compromisos tiene la rama actual:
ahead_count = $(git rev-list --count @{u}..HEAD)
. (Asume que desde donde obtienes es hacia donde empujas, consultapush.default
opción de configuración). - Si ambos
behind_count
yahead_count
son 0, entonces la rama actual está actualizada. - Si
behind_count
es 0 yahead_count
es mayor que 0, entonces la rama actual está por delante. - Si
behind_count
es mayor que 0 yahead_count
es 0, entonces la rama actual está atrasada. - Si ambos
behind_count
yahead_count
son mayores que 0, entonces la rama actual diverge.
Explicación:
git rev-list
enumere todas las confirmaciones de dar rango de confirmaciones.--count
la opción muestra cuántas confirmaciones se habrían enumerado y suprime todos los demás resultados.HEAD
nombra la rama actual.@{u}
se refiere al local aguas arriba de la rama actual (configurado conbranch.<name>.remote
ybranch.<name>.merge
). También hay@{push}
, por lo general apunta a lo mismo que@{u}
.<rev1>..<rev2>
especifica el rango de confirmaciones que incluye confirmaciones a las que se puede acceder desde pero excluye aquellas a las que se puede acceder desde . Cuando se omite o, el valor predeterminado es HEAD.
Puedes hacer esto con una combinación de git merge-base
y git rev-parse
. Si git merge-base <branch> <remote branch>
devuelve lo mismo que git rev-parse <remote branch>
, entonces su sucursal local está por delante. Si devuelve lo mismo que git rev-parse <branch>
, entonces su sucursal local está detrás. Si merge-base
devuelve una respuesta diferente a rev-parse
, entonces las ramas se han separado y tendrás que hacer una fusión.
Sería mejor hacer un git fetch
Sin embargo, antes de verificar las ramas, de lo contrario, su determinación de si necesita o no tirar estará desactualizada. También querrá verificar que cada sucursal que verifique tenga una sucursal de seguimiento remoto. Puedes usar git for-each-ref --format='%(upstream:short)' refs/heads/<branch>
Para hacer eso. Ese comando devolverá la rama de seguimiento remoto de <branch>
o la cadena vacía si no tiene una. En algún lugar de SO hay una versión diferente que devolverá un error si la sucursal no tiene una sucursal de seguimiento remoto, lo que puede ser más útil para su propósito.
Al final, implementé esto en mi complemento C++11 git-ws.
string currentBranch = run("git rev-parse --abbrev-ref HEAD");
bool canCommit = run("git diff-index --name-only --ignore-submodules HEAD --").empty();
bool canPush = stoi(run("git rev-list HEAD...origin/" + currentBranch + " --ignore-submodules --count")[0]) > 0;
Parece funcionar hasta ahora. canPull
aún debe probarse e implementarse.
Explicación:
currentBranch
obtiene la salida de la consola, que es una cadena del nombre de la rama actualcanCommit
obtiene si la consola genera algo (diferencia entre los cambios actuales y HEAD, ignorando los submódulos)canPush
obtiene el recuento de cambios entre origin/currentBranch
y el repositorio local - si> 0
, el repositorio local se puede enviar
Para futura referencia. A partir de Git v2.17.0
git status -sb
contiene la palabra detrás .Para que se pueda usar directamente para verificar si hay tirones.
Nota:Recuerda ejecutar git fetch
antes de ejecutar git status -sb