ver tipos tag remove modificados log etiquetas crear archivos git

tipos - Encontrar de qué rama proviene un git commit



git ver archivos modificados (12)

¿Hay alguna manera de averiguar de qué rama proviene un commit dado su sha1?

Puntos de bonificación si puedes decirme cómo lograr esto usando Ruby Grit.


TL; DR:

Use lo siguiente si le interesan los estados de salida de shell:

  • branch-current - el nombre de la rama actual
  • branch-names - limpiar nombres de rama (uno por línea)
  • branch-name : asegúrese de que solo se devuelva una branch-names de branch-names

Tanto branch-name branch-names aceptan una confirmación como argumento, y se establecen de forma predeterminada en HEAD si no se proporciona.

Alias ​​útiles en scripting

branch-current = "symbolic-ref --short HEAD" # https://.com/a/19585361/5353461 branch-names = !"[ -z /"$1/" ] && git branch-current 2>/dev/null || git branch --format=''%(refname:short)'' --contains /"${1:-HEAD}/" #" # https://.com/a/19585361/5353461 branch-name = !"br=$(git branch-names /"$1/") && case /"$br/" in *$''//n''*) printf /"Multiple branches://n%s/" /"$br/">&2; exit 1;; esac; echo /"$br/" #"

Compromiso solo accesible desde una sola rama

% git branch-name eae13ea master % echo $? 0

  • La salida es para RETIRAR
  • El valor de salida es 0 .

Compromiso accesible desde múltiples sucursales.

% git branch-name 4bc6188 Multiple branches: attempt-extract master% % echo $? 1

  • La salida es a STDERR
  • El valor de salida es 1 .

Debido al estado de salida, estos pueden ser construidos de forma segura. Por ejemplo, para obtener el control remoto utilizado para buscar:

remote-fetch = !"branch=$(git branch-name /"$1/") && git config branch./"$branch/".remote || echo origin #"


Actualización diciembre 2013:

sschuberth comments

git-what-branch (el script de Perl, ver más abajo) parece que ya no se mantiene.
git-when-merged es una alternativa escrita en Python que funciona muy bien para mí.

Se basa en " Buscar confirmación de fusión que incluye una confirmación específica ".

git when-merged [OPTIONS] COMMIT [BRANCH...]

Averigüe cuándo se ha fusionado una confirmación en una o más ramas.
Encuentre la confirmación de fusión que llevó a COMMIT a la (s) sucursal (es) especificada (s).

Específicamente, busque el compromiso más antiguo en el historial del primer padre de BRANCH que contiene el COMMIT como un antepasado.

Respuesta original de septiembre de 2010:

Sebastien Douche acaba de twitted (16 minutos antes de esta respuesta):

git-what-branch : descubre en qué rama está un commit, o cómo llegó a una rama con nombre

Este es un git-what-branch de Seth Robertson que parece muy interesante:

SINOPSIS

git-what-branch [--allref] [--all] [--topo-order | --date-order ] [--quiet] [--reference-branch=branchname] [--reference=reference] <commit-hash/tag>...

VISIÓN GENERAL

Díganos (de forma predeterminada) la ruta causal más temprana de confirmaciones y fusiones para hacer que la confirmación solicitada llegue a una rama nombrada.
Si se realizó una confirmación directamente en una rama nombrada, obviamente esa es la ruta más antigua.

Por primera ruta causal, nos referimos a la ruta que se fusionó en una rama con nombre la primera, por tiempo de confirmación (a menos que se especifique --topo-order ).

ACTUACIÓN

Si muchas ramas (p. Ej., Cientos) contienen la confirmación, el sistema puede tardar mucho tiempo (para una confirmación en particular en el árbol de Linux, tomó 8 segundos explorar una rama, pero había más de 200 ramas candidatas) para rastrear el camino a cada cometer
La selección de una --reference-branch --reference tag particular --reference-branch --reference tag para examinar será cientos de veces más rápida (si tiene cientos de ramas candidatas).

EJEMPLOS

# git-what-branch --all 1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4 1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4 first merged onto master using the following minimal temporal path: v2.6.12-rc3-450-g1f9c381 merged up at v2.6.12-rc3-590-gbfd4bda (Thu May 5 08:59:37 2005) v2.6.12-rc3-590-gbfd4bda merged up at v2.6.12-rc3-461-g84e48b6 (Tue May 3 18:27:24 2005) v2.6.12-rc3-461-g84e48b6 is on master v2.6.12-rc3-461-g84e48b6 is on v2.6.12-n [...]

Este programa no tiene en cuenta los efectos de elegir el compromiso de interés, solo operaciones de fusión.


Aparte de buscar en todo el árbol hasta que encuentre un hash coincidente, no.


Como experimento, hice un enlace posterior a la confirmación que almacena información sobre la rama actualmente activada en los metadatos de confirmación. También modifiqué ligeramente gitk para mostrar esa información.

Puede verlo aquí: https://github.com/pajp/branch-info-commits


Este simple comando funciona como un amuleto:

git name-rev <SHA>

Por ejemplo (donde prueba-rama es el nombre de la rama):

git name-rev 651ad3a 251ad3a remotes/origin/test-branch

Incluso esto funciona para escenarios complejos como: origin/branchA/ /branchB /commit<SHA1> /commit<SHA2>

Aquí git name-rev commit<SHA2> devuelve branchB


La opción del hombre pobre es usar la herramienta tig 1 en HEAD , buscar el compromiso y luego seguir visualmente la línea desde ese compromiso hasta que se vea un compromiso de fusión. El mensaje de combinación predeterminado debe especificar qué rama se fusiona con dónde :)

1 Tig es una interfaz de modo de texto basada en ncurses para git. Funciona principalmente como un navegador de repositorio Git, pero también puede ayudar en la preparación de cambios para la confirmación a nivel de trozos y actuar como un paginador para la salida de varios comandos Git.


Para encontrar la sucursal local

grep -lR YOUR_COMMIT .git/refs/heads | sed ''s/.git//refs//heads////g''

Para encontrar una sucursal remota

grep -lR $commit .git/refs/remotes | sed ''s/.git//refs//remotes////g''


Por ejemplo, para encontrar que c0118fa commit proviene de redesign_interactions

* ccfd449 (HEAD -> develop) Require to return undef if no digits found * 93dd5ff Merge pull request #4 from KES777/clean_api |/ | * 39d82d1 Fix tc0118faests for debugging debugger internals | * ed67179 Move &push_frame out of core | * 2fd84b5 Do not lose info about call point | * 3ab09a2 Improve debugger output: Show info about emitted events | * a435005 Merge branch ''redesign_interactions'' into clean_api | |/ | | * a06cc29 Code comments | | * d5d6266 Remove copy/paste code | | * c0118fa Allow command to choose how continue interaction | | * 19cb534 Emit &interact event

Deberías correr:

git log c0118fa..HEAD --ancestry-path --merges

Y desplácese hacia abajo para encontrar el último comando de fusión . Cual es:

commit a435005445a6752dfe788b8d994e155b3cd9778f Merge: 0953cac a06cc29 Author: Eugen Konkov Date: Sat Oct 1 00:54:18 2016 +0300 Merge branch ''redesign_interactions'' into clean_api

UPD
O simplemente un comando:

git log c0118fa..HEAD --ancestry-path --merges --oneline --color | tail -n 1


Si bien Dav tiene razón al afirmar que la información no se almacena directamente, eso no significa que nunca pueda averiguarlo. Aquí hay algunas cosas que puedes hacer.

Encuentra las ramas en las que está comprometido

git branch --contains <commit>

Esto le dirá todas las ramas que tienen el compromiso dado en su historia. Obviamente, esto es menos útil si el compromiso ya se ha fusionado.

Busca los reflogs

Si está trabajando en el repositorio en el que se realizó la confirmación, puede buscar en los reflogs la línea para esa confirmación. Los reflogs con más de 90 días se eliminan mediante git-gc, por lo que si el compromiso es demasiado antiguo, no lo encontrará. Dicho esto, puedes hacer esto:

git reflog show --all | grep a871742

para encontrar commit a871742. La salida debería ser algo como esto:

a871742 refs/heads/completion@{0}: commit (amend): mpc-completion: total rewrite

lo que indica que el compromiso se realizó en la rama "finalización". La salida predeterminada muestra hashes de confirmación abreviados, así que asegúrese de no buscar el hash completo o no encontrará nada.

git reflog show es en realidad solo un alias para git log -g --abbrev-commit --pretty=oneline , así que si quieres jugar con el formato de salida para hacer diferentes cosas disponibles para grep, ¡ese es tu punto de partida!

Si no está trabajando en el repositorio donde se realizó la confirmación, lo mejor que puede hacer en este caso es examinar los registros y encontrar cuándo se introdujo por primera vez la confirmación en su repositorio; Con un poco de suerte, conseguiste la rama con la que estaba comprometido. Esto es un poco más complejo, porque no se puede caminar simultáneamente el árbol de confirmación y los reflogs. Usted querría analizar la salida de reflog, examinando cada hash para ver si contiene la confirmación deseada o no.

Encuentra un subsiguiente merge commit

Esto depende del flujo de trabajo, pero con buenos flujos de trabajo, las confirmaciones se realizan en las ramas de desarrollo que luego se fusionan. Usted podría hacer esto:

git log --merges <commit>..

para ver las combinaciones de combinaciones que tienen la confirmación dada como un antepasado. (Si la confirmación solo se fusionó una vez, la primera debería ser la combinación que está buscando; de lo contrario, tendrá que examinar algunas, supongo). El mensaje de confirmación de combinación debe contener el nombre de la rama que se fusionó.

Si desea poder contar con hacer esto, puede usar la --no-ff para git merge para forzar la creación de un compromiso de fusión incluso en el caso de avance rápido. (Sin embargo, no se ponga demasiado ansioso, eso podría volverse confuso si se usa en exceso). La respuesta de VonC a una pregunta relacionada explica con mucho detalle este tema.


Si el OP está tratando de determinar el historial que fue atravesado por una rama cuando se creó una confirmación en particular ("averiguar de qué rama proviene una confirmación dada su sha1"), entonces no hay registros en la base de datos de objetos git que muestra qué rama llamada estaba vinculada a lo que el historial de cometer.

(Publiqué esto como respuesta en respuesta a un comentario)

Esperemos que este guión ilustre mi punto:

rm -rf /tmp/r1 /tmp/r2; mkdir /tmp/r1; cd /tmp/r1 git init; git config user.name n; git config user.email [email protected] git commit -m"empty" --allow-empty; git branch -m b1; git branch b2 git checkout b1; touch f1; git add f1; git commit -m"Add f1" git checkout b2; touch f2; git add f2; git commit -m"Add f2" git merge -m"merge branches" b1; git checkout b1; git merge b2 git clone /tmp/r1 /tmp/r2; cd /tmp/r2; git fetch origin b2:b2 set -x; cd /tmp/r1; git log --oneline --graph --decorate; git reflog b1; git reflog b2; cd /tmp/r2; git log --oneline --graph --decorate; git reflog b1; git reflog b2;

La salida muestra la falta de alguna forma de saber si la confirmación con ''Agregar f1'' provino de la rama b1 o b2 del clon remoto / tmp / r2

(últimas líneas de la salida aquí)

+ cd /tmp/r1 + git log --oneline --graph --decorate * f0c707d (HEAD, b2, b1) merge branches |/ | * 086c9ce Add f1 * | 80c10e5 Add f2 |/ * 18feb84 empty + git reflog b1 f0c707d b1@{0}: merge b2: Fast-forward 086c9ce b1@{1}: commit: Add f1 18feb84 b1@{2}: Branch: renamed refs/heads/master to refs/heads/b1 18feb84 b1@{3}: commit (initial): empty + git reflog b2 f0c707d b2@{0}: merge b1: Merge made by the ''recursive'' strategy. 80c10e5 b2@{1}: commit: Add f2 18feb84 b2@{2}: branch: Created from b1 + cd /tmp/r2 + git log --oneline --graph --decorate * f0c707d (HEAD, origin/b2, origin/b1, origin/HEAD, b2, b1) merge branches |/ | * 086c9ce Add f1 * | 80c10e5 Add f2 |/ * 18feb84 empty + git reflog b1 f0c707d b1@{0}: clone: from /tmp/r1 + git reflog b2 f0c707d b2@{0}: fetch origin b2:b2: storing head


Trato con el mismo problema (jenkins multibranch pipeline): tener solo confirmar información y tratar de encontrar un nombre de sucursal de donde provino originalmente este compromiso. Debe funcionar para sucursales remotas, no hay copias locales disponibles.

Esto es con lo que trabajo:

git rev-parse HEAD | xargs git name-rev

Opcionalmente puedes despojar la salida:

git rev-parse HEAD | xargs git name-rev | cut -d'' '' -f2 | sed ''s/remotes//origin////g''


git branch --contains <ref> es el comando de "porcelana" más obvio para hacer esto. Si desea hacer algo similar con solo comandos de "fontanería":

COMMIT=$(git rev-parse <ref>) # expands hash if needed for BRANCH in $(git for-each-ref --format "%(refname)" refs/heads); do if $(git rev-list $BRANCH | fgrep -q $COMMIT); then echo $BRANCH fi done

(crosspost de esta respuesta SO )