2008-09-10 15 views
225

¿Cuál es la mejor forma de obtener un registro de confirmaciones en una sucursal desde el momento en que se ramificó desde la sucursal actual? Mi solución hasta ahora es:Cómo obtener los cambios en una sucursal en Git

git log $(git merge-base HEAD branch)..branch 

La documentación para git-diff indica que git diff A...B es equivalente a git diff $(git-merge-base A B) B. Por otro lado, la documentación para git-rev-parse indica que r1...r2 se define como r1 r2 --not $(git merge-base --all r1 r2).

¿Por qué son diferentes? Tenga en cuenta que git diff HEAD...branch me da los diffs que quiero, pero el comando de registro git correspondiente me da más de lo que quiero.

En imágenes, supongamos lo siguiente:

 
     x---y---z---branch 
     /
---a---b---c---d---e---HEAD 

me gustaría obtener un registro que contiene la confirmación se x, y, z.

  • git diff HEAD...branch da estas commit
  • sin embargo, git log HEAD...branch da x, y, z, c, d, e.
+0

Estás utilizando "git log" incorrectamente para tus propósitos según lo que puedo ver. He agregado mi respuesta a continuación. – PlagueHammer

Respuesta

161

En el contexto de una lista de revisión, A...B es como lo define git-rev-parse. git-log toma una lista de revisión. git-diff no toma una lista de revisiones; lleva una o dos revisiones, y ha definido la sintaxis A...B para indicar cómo se define en la página de manual git-diff. Si git-diff no definió explícitamente A...B, entonces esa sintaxis no sería válida. Tenga en cuenta que la página de manual git-rev-parse describe A...B en la sección "Especificación de rangos", y todo en esa sección solo es válido en situaciones donde un rango de revisión es válido (es decir, cuando se desea una lista de revisión).

Para obtener un registro que contenga solo x, y y z, pruebe git log HEAD..branch (dos puntos, no tres). Esto es idéntico a git log branch --not HEAD, y significa todos los commits en la rama que no están en HEAD.

+26

Guau, eso es confuso. Resulta que usar "git diff HEAD..branch" muestra todos los commits (x, y, z, c, d, e), pero "git log HEAD..branch" hace exactamente lo que quiero y solo muestra x, y , z! Esto es exactamente lo contrario de usar "...". –

+20

'git diff HEAD..branch' es idéntico a' git diff HEAD branch'. La clave para recordar aquí es que el registro toma una lista/rango de revisiones, mientras que diff no lo hace. Es por eso que tratan sus args de manera diferente. –

60
git cherry branch [newbranch] 

hace exactamente lo que estás preguntando, cuando estás en la rama master.

También soy muy aficionado a:

git diff --name-status branch [newbranch] 

que no es exactamente lo que estás pidiendo, pero sigue siendo muy útil en el mismo contexto.

+0

¡Ah, eso también es bueno! –

+7

'git cherry' genera una lista de ID de confirmación. ¿Puedo convertir estos en un solo diff que combine todos los cambios en cada commit? –

+1

'git cherry' es muy útil. Gracias :) – jkp

22

Esto es similar a la respuesta que he publicado en: Preview a Git push

Caída de estas funciones en su perfil de Bash:

  • gbout - git rama saliente
  • gbin - git branch entrante

Puede usar esto como:

  • Si el maestro: BRANCH1 gbin < - esto le mostrará lo que está en BRANCH1 y no en master
  • Si el maestro: gbout BRANCH1 < - esto le mostrará lo que es en el maestro que no está en la rama 1

Esto funcionará con cualquier rama.

function parse_git_branch { 
    git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/' 
} 

function gbin { 
    echo branch \($1\) has these commits and \($(parse_git_branch)\) does not 
    git log ..$1 --no-merges --format='%h | Author:%an | Date:%ad | %s' --date=local 
} 

function gbout { 
    echo branch \($(parse_git_branch)\) has these commits and \($1\) does not 
    git log $1.. --no-merges --format='%h | Author:%an | Date:%ad | %s' --date=local 
} 
4
git log --cherry-mark --oneline from_branch...to_branch 

(3dots), pero a veces se muestra '+' en lugar de '='

+0

3 puntos muestra la primera confirmación en la rama dos veces y dos no. –

30

Lo que se quiere ver es la lista de confirmaciones salientes. Esto se puede hacer usando

git log master..branchName 

o

git log master..branchName --oneline 

Donde supongo que "BRANCHNAME" se ha creado como una rama de seguimiento de "maestro".

Del mismo modo, para ver los cambios entrantes que puede utilizar:

git log branchName..master 
+1

@ A-B-B, si se omite branchName, por defecto es "head", que es efectivamente branchName en el ejemplo anterior. – PlagueHammer

7

Lanzar un -p allí para ver algunos cambios en los archivos

git log -p master..branch 

hacer algo de alias:

alias gbc="git branch --no-color | sed -e '/^[^\*]/d' -e 's/* \\(.*\\)/\1/'" 

alias gbl='git log -p master..\`gbc\`' 

Ver compromisos únicos de una sucursal:

gbl 
+0

Me encanta alias simple impresionante gracias! –

2

He encontrado

git diff <branch_with_changes> <branch_to_compare_to> 

más útil, ya que no sólo obtener los mensajes sino a todo el diff confirmación.Si ya está en la rama desea ver los cambios y (por ejemplo) a querer ver lo que ha cambiado con el maestro, puede utilizar:

git diff HEAD master 
6

Para ver el registro de la rama actual ya ramificación maestro de apagado:

git log master...

Si se encuentra en la principal, para ver el registro de una rama diferente ya que bifurca principal:

git log ...other-branch

8

Similar a varias respuestas como Alex V y NDavis, pero ninguna de ellas es la misma.

Cuando ya en la rama en cuestión

Usando:

git diff master... 

que combina varias características:

  • Es súper corto
  • muestra los cambios reales

Actualización:

Esto probablemente debería ser git diff master, pero también muestra el diff, no los commits como la pregunta especificada.

+0

Si tienes 'git co master; git pull' desde que creó la rama, 'git diff master' no será de mucha utilidad para obtener las diferencias SOLO introducidas por confirmaciones en la rama especificada. – guival

Cuestiones relacionadas