¿Qué hace que C y R filtren en git diff –diff-filter = command CR?

No puedo entender lo que significa "Copiado" y "Renombrado" para git diff-filter, de acuerdo con esta respuesta: https://stackoverflow.com/a/6879568/2039203 . Cuando renombro / muevo algún file, este file se maneja como "Agregado" y "Eliminado".

Entonces la pregunta es: ¿qué debo hacer para get algunos files filtrados con los dos commands siguientes? ¿Necesito estas opciones de filter para get la list de los files agregados / eliminados?

git diff --diff-filter=C --name-only 

y

 git diff --diff-filter=R --name-only 

Solutions Collecting From Web of "¿Qué hace que C y R filtren en git diff –diff-filter = command CR?"

git diff mostrará un file como "renombrado" si pasa una "testing de similitud". Para asegurarse de que está ocurriendo, especifique la opción -M (lo haré a continuación). 1

 $ mkdir /tmp/temprepo && cd /tmp/temprepo && git init $ cat << end > file > Here is some text for a file. > We want it to be long enough > that renames and copies can > be detected fairly easily. > If we put ten lines into the > file, then each percent of > similarity is one tenth of > each of the lines, ie, each > line represents 10% similarity > to the earlier file. > end $ git commit -m initial [master (root-commit) 842824a] initial 1 file changed, 10 insertions(+) create mode 100644 file $ git mv file newname $ git diff --cached --name-status R100 file newname 

Avancemos y hagamos esto para poder hacer dos cambios, en lugar de la confirmación y el índice:

 $ git commit -m B [master a2380eb] B 1 file changed, 0 insertions(+), 0 deletions(-) rename file => newname (100%) 

Solo para ver lo que hizo:

 $ git diff --name-status -M HEAD^ HEAD R100 file newname 

Ahora hagamos un cambio menor:

 $ ed newname 279 9s/10/about 10/p line represents about 10% similarity w 285 q $ git commit -a -m C [master 57fce41] C 1 file changed, 1 insertion(+), 1 deletion(-) $ git diff --name-status -M HEAD~2 HEAD R087 file newname 

El diff (con --name-status mode selected) entre HEAD~2 (la confirmación inicial) y la última confirmación ahora muestra que el file se renombró a nombre newname con solo 87% de similitud, en lugar de 100% de similitud (como se ve ahora entre HEAD~2 y HEAD~1 ). 2

Para ver las copys, generalmente debe ejecutar git diff con -C y / o --find-copies-harder .

Puede controlar qué tan similares deben ser los files para cambiar el nombre (y las copys) con valores numéricos después de -M (y -C ), por ejemplo, -M90% hace que el git diff --name-status anterior git diff --name-status trate el cambio de nombre como un agregado -y eliminar par:

 $ git diff --name-status -M90% HEAD~2 HEAD D file A newname 

La opción -B también afecta la detección de cambio de nombre, al igual que las git config configuration de git config diff.renameLimit y diff.renames (ver la documentation). Para vencer por completo la detección de renombrados, lo que hace que escribir guiones de git hook con --diff-filter sea ​​mucho más fácil en muchos casos-use --diff-filter .


1 Esta testing de similitud tiene un valor pnetworkingeterminado de "50% similar" si establece diff.renames en true en su configuration de git config --global diff.renames true ( git config --global diff.renames true ), pero "solo coincidencia exacta" en caso contrario (la detección de coincidencia exacta es fácil porque de cómo git almacena datos). Cuando escribí los ejemplos, había olvidado que la detección de cambio de nombre estaba activada de forma pnetworkingeterminada.

2 Anteriormente, utilizamos HEAD^ y HEAD , pero hemos agregado commit C desde entonces, por lo que la confirmación inicial ahora es HEAD^^ o HEAD~2 .

Necesita un poco más que eso ya que la detección de copy y renombrado no está habilitada de forma pnetworkingeterminada.

Prueba esto:

 git init example cd example echo foo > foo.txt echo baz > baz.txt git add . git commit -m "add foo and baz" cp baz.txt other-baz.txt git mv foo.txt bar.txt git add other-baz.txt 

En este punto, debería ver algo así en git status -s :

 ## master R foo.txt -> bar.txt A other-baz.txt 

Dos cosas para tener en count aquí: el git status renombra la detección, pero no está haciendo la detección de copy. Por lo tanto, le informa sobre el cambio de nombre, pero muestra la copy como un agregado. Además, los cambios se escenifican . Entonces un simple git diff no va a mostrar nada.

Para ver que --diff-filter=C y --diff-filter=R funcionan, necesita decirle a git diff que copie y cambie el nombre de detección, y necesita permitir que vea el área de ensayo (llamado el "índice" en la documentation de git). Prueba esto:

 $ git diff --staged -C -C --diff-filter=C --name-only other-baz.txt $ git diff --staged -C --diff-filter=R --name-only bar.txt 

En este caso, la copy requiere especificar -C dos veces para que Git vea las confirmaciones previas cuando realiza la detección de copy (ya que es la copy de un file previamente confirmado). También puede usar --find-copies-harder para habilitar este comportamiento.