2012-03-08 12 views
5

Tenemos un flujo de trabajo donde otros desarrolladores deben revisar el código comprometido. En casos simples, esto se puede hacer con "git diff oldhash newhash> diff.txt" y subirlo a nuestro panel de revisión.herramienta Git diff durante varias confirmaciones con commit de otros entre

Pero, ¿hay alguna manera de crear un diff en varias confirmaciones y excluir las confirmaciones hechas entre otras por alguien más? Por ejemplo, yo quiero crear diff sobre mine1 a mine4 pero excluyo Joe de comprometerse:

mine4 
mine3 
joe's 
mine2 
mine1 

Alguna idea de cómo hacer esto en línea de comando git o con alguna otra herramienta?

Editar: Las confirmaciones hechas por otros afectan a archivos diferentes a mis confirmaciones, por lo que en este caso se trata simplemente de excluir los cambios realizados por otros.

+0

Eso realmente no tiene sentido. 'mine4' depende de' mine3', 'joe's' y' mine2' (y 'mine1' por supuesto) – knittl

+0

Puede ser dependiente al mirar los objetos de git, pero pueden tocar partes completamente independientes del código fuente. – Bombe

+0

@Bombe: puede - o no. No hay una representación correcta si las confirmaciones intermedias tocan el mismo fragmento de código (también se pueden mover/renombrar los archivos) – knittl

Respuesta

5

Usted puede lograr esto mediante la creación de una nueva rama combinada con la cereza-escoge:

git checkout -b mine_diffs 
git cherry-pick mine1 
git cherry-pick mine2 
git cherry-pick mine3 
git cherry-pick mine4 
git diff mine1_ mine4_ 

Cuando haya terminado, simplemente borre la rama. Tenga en cuenta que los valores hash sha1 serán diferentes al diferir, que es lo que mine1_ y mine4_ indican.

3

De acuerdo, tal vez no sea así, pero crearía una nueva sucursal, eliminaría las confirmaciones innecesarias y compararía dos ramas.

4

No estoy muy seguro de lo que quiere decir con "over mine1 to mine4". Diffs son siempre pairwise (a excepción de mid-merge); "git diff mine1 mine4" te dará todos los cambios entre esos dos árboles. Dado el ejemplo anterior, puede obtener cuatro parches separados: mine1-> mine2, mine2-> joes, joes-> mine3, mine3-> mine4. Si hicieras mine1-> mine2, mine2-> mine3, mine3-> mine4, seguirías "viendo" los cambios de Joe.

Quizás lo que quieres es (como se sugirió @OleksandrKravchuk) "una diferencia de lo que uno podría tener, si se seleccionan los cambios en mine2, mine3 y mine4 en una rama que comenzó desde mine1". En ese caso, tendrá que hacer justamente eso: crear dicha rama, elegir esos cambios para aplicar, y luego generar la diferencia.

Puede automatizar esto bastante fácilmente creando la rama temporal y haciendo la secuencia de "git cherry-pick" s, omitiendo la (s) confirmación (es) que desea omitir.

1
  1. Revisión de un paquete de confirmaciones como un diff es mal estilo: codereview (si existen) deben trabajar on-commit solo nivel
  2. no se puede tener diffs "dispersos"
  3. Tal vez las herramientas adecuadas se ser el camino correcto? Para Git es Gerrit
+0

En cuanto a 1 - Hay desarrolladores que se comprometen y presionan con frecuencia. ¿Supongo que tenemos que educarlos para que hagan una nueva versión del squash? –

+0

@PetteriHietavirta: el compromiso a menudo es bueno, pero no está relacionado con la misión CodeReview: "cometer un buen código".Los commit frecuentes son un dolor de cabeza de revisor, no codificador –

+2

La forma en que hacemos las revisiones con Git es que: (1) todo el desarrollo ocurre en feature-branches (2) un desarrollador por feature-branch (3) cuando branch está listo, es aplastado y re-cometido por lo que cada parche representa una unidad lógica de cambio mínima razonable (4) las ramas se fusionan después de que pasan la revisión. Ver también documentos sobre el proceso de desarrollo de Git (es decir, sobre el desarrollo de Git). –