¿Cómo ver cuántos commits una sucursal local está adelante / detrás de otra sucursal local en git?

Si estoy trabajando en una twig de características, me gustaría saber cuántos commits esta twig está por delante o por detrás de la twig principal. Parece que no puedo encontrar el command que hace esto.

Listado y conteo de commits: git rev-list

Una forma rápida es hacer lo que hace el git status cuando hay un "flujo ascendente". Específicamente, el git status simplemente count las revisiones que están en la twig actual que no están en la twig ascendente. Por ejemplo, considere branch foo que tiene un upstream de origin/foo , y supongamos que ha realizado tres commits locales y luego ha usado git fetch para traer una confirmación upstream:

  L - L - L <-- foo / ... - C - C \ U <-- origin/foo 

Aquí C s son confirmaciones comunes, L s son confirmaciones locales y U es una confirmación ascendente. Si estás en la twig foo y ejecutas el git status , verás "adelante 3, detrás de 1".

Así es como git obtiene esos numbers:

  1. git rev-list foo --not origin/foo : esto produce una list de todos los commits en foo pero no en origin/foo . Es decir, comenzando en origin/foo (que es commit U ), ponche el commit y todos los commit anteriores disponibles: eso es U y todos los C commits. Luego, comience en foo y encuentre todas las confirmaciones alcanzables que aún no están tachadas: son solo las tres confirmaciones de L

  2. Agregue --count a los arguments de git rev-list para que imprima un recuento en lugar de los valores RAW de identificación de compromiso sin formatting.

  3. Repita para git rev-list origin/foo --not foo : esto es todos los commits que son accesibles desde origin/foo pero no desde foo , que en este ejemplo es solo commit U (De nuevo, agregue --count para get solo el recuento, en lugar de los ID de confirmación reales).

Tenga en count que foo --not origin/foo también se deletrea origin/foo..foo en la syntax de gitrevisions . (En el caso del git status de git status , siempre se está buscando en la twig actual , que se denomina mediante HEAD y en sentido ascendente. Puede usar la syntax de @{upstream} para get el nombre de la cadena ascendente, o acortarla a @{u} ; y HEAD es el valor pnetworkingeterminado si no enumeras ningún nombre, por lo que para volver a implementar el git status puedes simplemente mirar git rev-list --count ..@{u} y git rev-list --count @{u}.. )

Usando rev-list en las sucursales locales, vs usando git cherry

Por lo tanto, si desea contar confirmaciones accesibles desde la feature sucursal pero no desde la sucursal master , puede hacer lo mismo pero con la feature nombres y el master . El master..feature syntax git rev-list master..feature nombres de todas las identificaciones de compromiso accesibles desde la feature pero no desde el master , y – la --count te dará un conteo:

 git rev-list --count master..feature 

Sin embargo, si ha elegido cuidadosamente algunas confirmaciones de una twig a otra, para que tengan diferentes ID de compromiso pero la misma diferencia, esto "contará demasiado". Por ejemplo, supongamos que la feature tiene cinco confirmaciones que el master no hizo, pero luego usted (o alguien) decidió que una de esas cinco confirmaciones debería ser elegida como master , ahora puede tener esto:

  D - E - F - G - H <-- feature / ... - C - C \ F' <-- master 

donde F' es básicamente solo una copy de commit F Si le pides a git rev-list que cuente commits en la feature que no está en master , obtendrás 5; pero si le pides a git cherry que busque commits en la feature que no está en master , eliminará el commit F de su list, porque verá que F' es una copy de F Si counts los commits listdos por git cherry obtendrás 4, no 5.

Usa git cherry para encontrar las confirmaciones presentes en una twig y no presentes en otra

 git cherry -v master feature 

Enumerará todas las confirmaciones presentes en la twig de características que no están presentes en el maestro.

Similar,

 git cherry -v feature master 

listrá todas las confirmaciones presentes en la twig maestra que no están presentes en la característica.

También puede proporcionar un tercer parámetro adicional para elegir un punto de inicio.

 git cherry -v feature master 1b219e 

ACTUALIZAR:

Puede crear un alias para combinar los dos

 [alias] mydiff = !sh -c 'echo "Commits in $2 not in $1" && git cherry -v $1 $2 && echo "Commits in $1 not in $2" && git cherry -v $2 $1' - 

Utilizar,

 git mydiff master feature