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.defaultopción de configuración). - Si ambos
behind_countyahead_countson 0, entonces la rama actual está actualizada. - Si
behind_countes 0 yahead_countes mayor que 0, entonces la rama actual está por delante. - Si
behind_countes mayor que 0 yahead_countes 0, entonces la rama actual está atrasada. - Si ambos
behind_countyahead_countson mayores que 0, entonces la rama actual diverge.
Explicación:
git rev-listenumere todas las confirmaciones de dar rango de confirmaciones.--countla opción muestra cuántas confirmaciones se habrían enumerado y suprime todos los demás resultados.HEADnombra la rama actual.@{u}se refiere al local aguas arriba de la rama actual (configurado conbranch.<name>.remoteybranch.<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:
currentBranchobtiene la salida de la consola, que es una cadena del nombre de la rama actualcanCommitobtiene si la consola genera algo (diferencia entre los cambios actuales y HEAD, ignorando los submódulos)canPushobtiene el recuento de cambios entre origin/currentBranchy 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