tutorial remota rama origin example comandos cambiar and git word-count

remota - git push example



¿Cuantificando la cantidad de cambio en un git diff? (8)

Descubrí una manera de obtener números concretos construyendo sobre las otras respuestas aquí. El resultado es una aproximación, pero debe estar lo suficientemente cerca como para servir como un indicador útil de la cantidad de caracteres que se agregaron o eliminaron. Aquí hay un ejemplo con mi rama actual en comparación con el origen / maestro:

$ git diff --word-diff=porcelain origin/master | grep -e ''^+[^+]'' | wc -m 38741 $ git diff --word-diff=porcelain origin/master | grep -e ''^-[^-]'' | wc -m 46664

La diferencia entre los caracteres eliminados ( 46664 ) y los caracteres agregados ( 38741 ) muestra que mi rama actual ha eliminado aproximadamente 7923 caracteres. Esos recuentos individuales agregados / eliminados se inflan debido a los caracteres de diferencia / + y sangría, sin embargo, la diferencia debería cancelar una parte significativa de esa inflación en la mayoría de los casos.

Uso git para un propósito un poco inusual: almacena mi texto mientras escribo ficción. (Lo sé, lo sé ... geek).

Estoy tratando de hacer un seguimiento de la productividad, y quiero medir el grado de diferencia entre los compromisos posteriores. El poder del autor para "trabajo" es "palabras escritas", al menos durante la etapa de creación. No puedo usar el recuento de palabras rectas porque ignora la edición y la compresión, ambas partes vitales de la escritura. Creo que quiero rastrear:

(words added)+(words removed)

que contará dos veces (palabras cambiadas), pero estoy de acuerdo con eso.

Sería genial escribir algún conjuro mágico y que git informe esta métrica de distancia para cualquiera de las dos revisiones. Sin embargo, git diffs son parches, que muestran líneas completas incluso si solo has trenzado un carácter en la línea; No quiero eso, especialmente porque mis ''líneas'' son párrafos. Idealmente, incluso podría especificar lo que quiero decir con "palabra" (aunque / W + probablemente sería aceptable).

¿Hay una bandera para git-diff para dar diferencias palabra por palabra? Alternativamente, ¿existe una solución que use herramientas de línea de comandos estándar para calcular la métrica anterior?


Desde Git 1.6.3 también hay git difftool , que se puede configurar para ejecutar casi cualquier herramienta externa de diferencias. Esto es mucho más fácil que algunas de las soluciones que requieren la creación de scripts, etc. Si le gusta la salida de wdiff -s , puede configurar algo como:

git config --global difftool.wdiffs.cmd ''wdiff -s "$LOCAL" "$REMOTE"'' git config --global alias.wdiffs ''difftool -t wdiffs''

Ahora puede ejecutar git difftool -t wdiffs o su alias git wdiffs .

Si prefiere obtener estadísticas de todos los archivos modificados juntos, haga algo como:

git config --global difftool.wdiffs.cmd ''diff -pdrU3 "$LOCAL" "$REMOTE" | wdiff -sd'' git config --global alias.wdiffs ''difftool -d -t wdiffs''

Esto toma la salida de un diff unificado típico y la canaliza a wdiff con su opción -d configurada para interpretar la entrada. En contraste, el argumento extra -d para difftool en el alias le dice a git que copie todos los archivos modificados en un directorio temporal antes de hacer el diff.


Git ha tenido (durante mucho tiempo) la opción --color-words para git diff . Esto no te permite contar, pero te permite ver las diferencias.

La sugerencia de scompt.com de wdiff también es buena; es bastante fácil de empujar en una diferencia diferente (ver git-difftool ). Desde allí, solo tiene que ir desde la salida que wdiff puede dar al resultado que realmente desea.

Sin embargo, hay una cosa más emocionante que compartir de lo que se está cocinando de git:

* tr/word-diff (2010-04-14) 1 commit (merged to ''next'' on 2010-05-04 at d191b25) + diff: add --word-diff option that generalizes --color-words

Aquí está el commit introduciendo word-diff . Presumiblemente, pasará del siguiente al maestro en poco tiempo, y luego git podrá hacerlo todo internamente, ya sea produciendo su propio formato de diferencia de palabra o algo similar a wdiff. Si te atreves, puedes construir git a partir de la próxima, o simplemente fusionar ese compromiso en tu maestro local para construir.

Gracias al comentario de Jakub: puede personalizar aún más las diferencias de palabra si es necesario proporcionando una expresión regular de palabras (parámetro de configuración dif. *. WordRegex), documentada en gitattributes .


Las respuestas anteriores fallan en algunos casos de uso en los que necesita excluir el texto movido (por ejemplo, si muevo una función en el código o párrafo en el látex más abajo en el documento, ¡no quiero contar todos esos cambios!)

Para eso, también puede calcular el número de líneas duplicadas y excluirlas de su consulta si hay demasiados duplicados.

Por ejemplo, basándose en las otras respuestas, puedo hacer:

git diff $sha~1..$sha|grep -e"^+[^+]" -e"^-[^-]"|sed -e''s/.//''|sort|uniq -d|wc -w|xargs

calcula el número de palabras duplicadas en el diff, donde sha es tu confirmación.

Puede hacer esto para todas las confirmaciones en el último día (desde las 6 am) de la siguiente manera:

for sha in $(git rev-list --since="6am" master | sed -e ''$ d''); do echo $(git diff --word-diff=porcelain $sha~1..$sha|grep -e"^+[^+]"|wc -w|xargs),/ $(git diff --word-diff=porcelain $sha~1..$sha|grep -e"^-[^-]"|wc -w|xargs),/ $(git diff $sha~1..$sha|grep -e"^+[^+]" -e"^-[^-]"|sed -e''s/.//''|sort|uniq -d|wc -w|xargs) done

Impresiones: añadidas, eliminadas, duplicadas.

(Tomo la diferencia de línea para los duplicados, ya que excluye los tiempos en los que git diff intenta ser demasiado inteligente, y supone que en realidad ha cambiado el texto en lugar de moverlo. También descuenta las instancias en que una sola palabra se cuenta como un duplicado. )

O, si quiere ser sofisticado al respecto, puede excluir los compromisos por completo si hay más del 80% de duplicación, y resumir el resto:

total=0 for sha in $(git rev-list --since="6am" master | sed -e ''$ d''); do added=$(git diff --word-diff=porcelain $sha~1..$sha|grep -e"^+[^+]"|wc -w|xargs) deleted=$(git diff --word-diff=porcelain $sha~1..$sha|grep -e"^-[^-]"|wc -w|xargs) duplicated=$(git diff $sha~1..$sha|grep -e"^+[^+]" -e"^-[^-]"|sed -e''s/.//''|sort|uniq -d|wc -w|xargs) if [ "$added" -eq "0" ]; then changed=$deleted total=$((total+deleted)) echo "added:" $added, "deleted:" $deleted, "duplicated:"/ $duplicated, "changed:" $changed elif [ "$(echo "$duplicated/$added > 0.8" | bc -l)" -eq "1" ]; then echo "added:" $added, "deleted:" $deleted, "duplicated:"/ $duplicated, "changes counted:" 0 else changed=$((added+deleted)) total=$((total+changed)) echo "added:" $added, "deleted:" $deleted, "duplicated:"/ $duplicated, "changes counted:" $changed fi done echo "Total changed:" $total

Tengo este script para hacerlo aquí: https://github.com/MilesCranmer/git-stats .

Esto imprime:

➜ bifrost_paper git:(master) ✗ count_changed_words "6am" added: 38, deleted: 76, duplicated: 3, changes counted: 114 added: 14, deleted: 19, duplicated: 0, changes counted: 33 added: 1113, deleted: 1112, duplicated: 1106, changes counted: 0 added: 1265, deleted: 1275, duplicated: 1225, changes counted: 0 added: 4207, deleted: 4208, duplicated: 4391, changes counted: 0 Total changed: 147

Los compromisos en los que me muevo son obvias, así que no cuento esos cambios. Cuenta todo lo demás y me dice el número total de palabras cambiadas.


Me gustó la answer y quería hacerlo un poco más configurable para responder algunas de las preguntas de palabras que tenía. Terminé con la siguiente solución que funciona en ZSH y debería funcionar en Bash. Cada función toma cualquier revisión o diferencia de revisión , con el valor predeterminado de comparar el estado actual del mundo con el origin/master :

# Calculate writing word diff between revisions. Cribbed / modified from: # https://.com/questions/2874318/quantifying-the-amount-of-change-in-a-git-diff function git_words_added { revision=${1:-origin/master} git diff --word-diff=porcelain $revision | / grep -e "^+[^+]" | / wc -w | / xargs } function git_words_removed { revision=${1:-origin/master} git diff --word-diff=porcelain $revision | / grep -e "^-[^-]" | / wc -w | / xargs } function git_words_diff { revision=${1:-origin/master} echo $(($(git_words_added $1) - $(git_words_removed $1))) }

Entonces puedes usarlo así:

$ git_words_added # => how many words were added since origin/master $ git_words_removed # => how many words were removed since origin/master $ git_words_diff # => difference of adds and removes since origin/master (net words) $ git_words_diff HEAD # => net words since you last committed $ git_words_diff master@{yesterday} # => net words written today! $ git_words_diff HEAD^..HEAD # => net words in the last commit $ git_words_diff ABC123..DEF456 # => net words between two arbitrary commits

¡Espero que esto ayude a alguien!



git diff --word-diff funciona en la última versión estable de git (en git-scm.com)

Hay algunas opciones que le permiten decidir en qué formato lo desea, el valor predeterminado es bastante legible, pero es posible que desee --word-diff = porcelain si está introduciendo la salida en un script.


wdiff hace wdiff palabra por palabra. Git se puede configurar para usar un programa externo para hacer la diferencia. Basado en esos dos hechos y en esta publicación de blog , lo siguiente debería hacer más o menos lo que quieres.

Cree un script para ignorar la mayoría de los argumentos innecesarios que proporciona git-diff y wdiff a wdiff . Guarda lo siguiente como ~/wdiff.py o algo similar y ~/wdiff.py ejecutable.

#!/usr/bin/python import sys import os os.system(''wdiff -s3 "%s" "%s"'' % (sys.argv[2], sys.argv[5]))

Dile a git que lo use.

git config --global diff.external ~/wdiff.py git diff filename