2010-05-06 7 views
6

¿Hay un comando git para agregar las diferencias dentro del rango de los números de línea al índice?Git: Agregue una parte del archivo (cambiado) al índice * por números de línea *

Quiero ser capaz de seleccionar líneas en mi editor y ejecutar una macro para agregar cualquier cambio en la selección al índice.

+0

¿Qué tan apegado está a la idea de hacer esto desde el editor en lugar de a través de 'git add -i'? Probablemente puedas encontrar algo que pueda llamar '' git diff', sacar los trozos que tocan las líneas que has seleccionado, y aplicar ese parche al índice, si realmente quisieras ... – Cascabel

Respuesta

17

Si puede convencer a su editor para que escriba una versión del archivo que desea que se organice, puede usar los comandos de git de nivel de plomería para agregarlo al índice con el nombre correcto. Debe omitir "git add", que siempre asociará la ruta X en el árbol de trabajo con la ruta X en el índice (hasta donde yo sé).

Una vez que tenga el contenido que desea representar en un archivo temporal $ archivo_temporal, ejecute git hash-object -w $tempfile - esto escribirá el objeto en .git/objects y dará salida a la id de blob. A continuación, introduzca este identificador de blob en el índice usando git update-index --cacheinfo 100644 $blobid $path para asociar la ruta $ path con ese objeto.

He aquí un ejemplo que pone en escena un cambio a un script llamado "post_load" en mi repo sin sobrescribir el archivo en sí (que demuestra también se puede prescindir de un archivo temporal):

git update-index --cacheinfo 100755 $(perl -lne 'print unless (/^#/)' post_load \ 
             | git hash-object -w --stdin) post_load 

Usted no menciona de qué editor está planeando hacer esto, por lo que es difícil aconsejarle sobre cómo integrar esto. Como mencioné, necesitas presentar git de alguna manera como quieras que sea el escenario (recuerda, git no se ocupa de almacenar cambios). Si puede escribir una macro para guardar el archivo como "$ file.tmp", utilice algo como lo anterior en git update-index --cacheinfo $the_mode $(git hash-object -w $file.tmp) $file (obtener $ the_mode se deja como un ejercicio: p), eliminar $ file.tmp y revertir el buffer del editor Regrese a $ archivo que básicamente haría lo que está pidiendo.

Por ejemplo, el siguiente script toma tres argumentos: M N path. Se actualizará el contenido de índice para el archivo en "camino" de modo que M líneas a través de N (inclusive) se sustituyen con el contenido de la entrada estándar:

#!/bin/sh 

start_line=$1 
end_line=$2 
path=$3 

mode=$(git ls-files -s $path | awk '{print $1}') 
blob_id=$(
    (
     head -n $(expr $start_line - 1) $path 
     cat 
     tail -n +$(expr $end_line + 1) $path 
     ) | git hash-object -w --stdin 
    ) 
exec git update-index --cacheinfo $mode $blob_id $path 

por ejemplo echo "HELLO WORLD" | ./stage-part 8 10 post_load reemplazará las tres líneas de 8-10 con solo "HOLA MUNDO".

3

La forma más fácil de hacerlo actualmente es con git add en modo interactivo:

git add -i path/to/file 

Se pondrá en marcha la interfaz de usuario sencilla, donde se puede elegir trozos que desea poner en escena y permitirá editar cualquier trozo para eliminar las líneas que Don no quiero comprometer

+0

Esa es mi práctica actual, pero cuando hay mucho "ruido" en el diff que quiero probar/comprometer, me confundo (debido a la falta de líneas de contexto, etc.). Realmente quiero ser capaz de conducir esto desde mi editor en tales situaciones. – RobM

0

La herramienta preconstruida más cercana que hace algo como esto es git gui citool. No funciona directamente en su editor (no todos los editores tienen vistas diff útiles y sospecho que a la mayoría de las personas probablemente no les importa recordar exactamente qué líneas han cambiado desde el último commit, por lo que una vista diff es muy útil), pero parece como si estuviera cerca de lo que quieres.

git gui citool le permite revisar los cambios por etapas y sin escena en las vistas que son equivalentes a git diff --cached y git diff, respectivamente.

Al revisar los cambios no registrados, el menú contextual (clic derecho) tiene opciones para representar las líneas seleccionadas (o la línea cliqueada si no hay selección) y una opción para representar un trozo completo. Del mismo modo, al revisar los cambios por etapas, el menú contextual tiene opciones para dejar de grabar líneas o un hunk.

Para obtener más contexto, puede usar el elemento de menú "Mostrar más contexto" (o "Mostrar menos contexto" si desea reducir el tamaño).

Una vez que tenga su nuevo contenido en etapas, también puede redactar su mensaje de confirmación y realizar la confirmación desde la GUI.

Me imagino que algunas personas usan git gui en un flujo de trabajo de la siguiente manera:

  1. utilizar la CLI para añadir nuevos archivos de orugas y eliminar archivos viejos (las diversas opciones para git add).
  2. Edite los archivos rastreados en su editor/entorno favorito.
  3. En git gui, seleccione "Volver a explorar", revise los cambios, etapas/fuera de escena algunos, y eventualmente los confirme.
  4. [repetir]
2

En mi propia experiencia, git-cola hace un trabajo excelente en esto. Desearía que admitiera la integración de Atom ...

+0

Si bien esto puede responder teóricamente a la pregunta, [sería preferible] (// meta.stackoverflow.com/q/8259) incluir aquí las partes esenciales de la respuesta y proporcionar el enlace de referencia. – manetsus

+0

En git-cola, seleccione las líneas y seleccione 'Etapa de líneas seleccionadas' en el menú desplegable, o presione' H'. Requiere cambio del editor regular a git-cola para la puesta en escena, pero ambos pueden ejecutarse al mismo tiempo y no me pareció inconveniente. –

Cuestiones relacionadas