Confirmar solo parte de un archivo en Git


2766

Cuando realizo cambios en un archivo en Git, ¿cómo puedo confirmar solo algunos de los cambios?

Por ejemplo, ¿cómo podría confirmar solo 15 líneas de 30 líneas que se han cambiado en un archivo?


3
stackoverflow / q / 34609924 / 52074 relacionado : si necesita dividir un trozo en trozos más pequeños.
Trevor Boyd Smith

Resumen: en términos de capacidad: git gui= git add -e> git add -i -p; en términos de conveniencia: git gui> git add -i -p> git add -e. Entonces: elija git guicuando tenga acceso a X. elija git add -i -pcosas simples y cuando no tenga o quiera usar X. git add -epara una puesta en escena compleja sin X.
Penghe Geng

Respuestas:


3689

Puede usar git add --patch <filename>(o -ppara abreviar), y git comenzará a dividir su archivo en lo que cree que son "trozos" razonables (partes del archivo). Luego le indicará esta pregunta:

Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]?

Aquí hay una descripción de cada opción:

  • y organizar este trozo para la próxima confirmación
  • n no organices este trozo para el próximo commit
  • qdejar; no pongas en escena este trozo ni ninguno de los trozos restantes
  • a escenifique este trozo y todos los trozos posteriores en el archivo
  • d no ponga en escena este trozo ni ninguno de los trozos posteriores en el archivo
  • g seleccione un trozo para ir a
  • / buscar un trozo que coincida con la expresión regular dada
  • j deja este trozo indeciso, mira el siguiente trozo indeciso
  • J deja este trozo indeciso, mira el siguiente trozo
  • k deja este trozo indeciso, mira el trozo indeciso anterior
  • K deja este trozo indeciso, mira el trozo anterior
  • s dividir el trozo actual en trozos más pequeños
  • e editar manualmente el trozo actual
  • ? ayuda de impresión hunk

Si el archivo aún no está en el repositorio, primero puede hacerlo git add -N <filename>. Después puedes continuar git add -p <filename>.

Después, puedes usar:

  • git diff --staged para comprobar que realizaste los cambios correctos
  • git reset -p para desentrañar trozos añadidos por error
  • git commit -v para ver su confirmación mientras edita el mensaje de confirmación.

Tenga en cuenta que esto es muy diferente al git format-patchcomando, cuyo propósito es analizar los datos de confirmación en un .patcharchivo.

Referencia para el futuro: Git Tools - Puesta en escena interactiva


83
Puede ser útil tener en cuenta que -p/--patches un acceso directo a la acción del parche dentro del -i/--interactivecomando que inicia el modo interactivo útil .
tutuDajuju

55
> ¿Qué sucede si ese archivo ya está preparado? Solo mostrará los cambios no organizados. Igual que lo git diffhace.
Eugen Konkov

3
¿Cómo puedo editar el trozo actual manualmente? No sé qué hacer después de escribir e.
Hunsu 01 de

23
Después de presionar e, puede editar el trozo manualmente reemplazando +o -por#
veksen

1
esto es genial, pero ahora, ¿cómo lo presiono realmente? si lo hago git pushdice ya actualizado. y si lo hago, git diffveo a los tíos que le dije n. si lo hago, git diff --stagedveo el commit que quiero presionar. Suponiendo que puedo empujar el commit, ¿cómo elimino los trozos que dije no?
chovy

250

Puede usar git add --interactiveo , y luego ( no ); vea Modo interactivo en la página de manual de git-add , o simplemente siga las instrucciones.git add -p <file>git commit git commit -a

Modern Git también tiene git commit --interactive(y git commit --patch, que es la opción de acceso directo a parche en confirmación interactiva).

Si prefiere hacerlo desde la GUI, puede usar git-gui . Simplemente puede marcar fragmentos que desea incluir en commit. Personalmente me resulta más fácil que usar git add -i. Otras GUI de git, como QGit o GitX, también pueden tener esta funcionalidad.


1
Curiosamente, windows.github.com tenía soporte para confirmaciones de archivos parciales, pero parece haberlo eliminado recientemente ...
Juri

1
@Juri Creo que el soporte para las confirmaciones de archivos parciales está de vuelta.
Ela782

@Juri De nada. De hecho, nunca me di cuenta de que había estado allí antes, lo vi la semana pasada y pensé "¡Oh, qué nueva característica increíble"! :-)
Ela782

1
Hoy en día, windows.github.com redirige al renombrado Escritorio GitHub, que es mejor que la GUI de Git y admite confirmaciones parciales ... pero no admite la firma de confirmaciones. Suspiro.

147

git gui proporciona esta funcionalidad en la vista de diferencias. Simplemente haga clic con el botón derecho en la (s) línea (s) que le interese y debería ver un elemento de menú "organizar esta línea para confirmar".


13
para parches complejos, este suele ser el enfoque más rápido para mí.
hochl

77
Esta es una forma muy eficiente e intuitiva de agregar cambios al área de preparación de una manera fina. También se pueden seleccionar varias líneas y se agregarán todos los cambios dentro de esa selección.
jox

Tenga en cuenta que esto no es así gitk, pero se incluye con Git Bash para Windows; debe tener una entrada de menú de inicio o puede iniciarlo con el comando git gui. También hay stage this hunkcuál es probablemente más útil que stage this line. Puede ser nuevo ya que esta respuesta fue creada hace 10 años.
Chris

82

Creo que esa git add -e myfilees la forma más fácil (mi preferencia al menos) ya que simplemente abre un editor de texto y le permite elegir qué línea desea poner en escena y qué línea no. En cuanto a los comandos de edición:

contenido agregado:

El contenido agregado está representado por líneas que comienzan con "+". Puede evitar la organización de las líneas de adición eliminándolas.

contenido eliminado:

El contenido eliminado se representa con líneas que comienzan con "-". Puede evitar que su eliminación se convierta en etapas convirtiendo el "-" en un "" (espacio).

contenido modificado:

El contenido modificado se representa con líneas "-" (eliminando el contenido anterior) seguido de líneas "+" (agregando el contenido de reemplazo). Puede evitar organizar la modificación al convertir las líneas "-" en "" y eliminar las líneas "+". Tenga en cuenta que modificar solo la mitad del par probablemente introducirá cambios confusos en el índice.

Todos los detalles sobre git addestán disponibles engit --help add


77
Esto sería más útil si hubiera una explicación clara en algún lugar sobre cómo elegir realmente esas líneas (es decir, los comandos reales para ingresar). No pude encontrar uno en la documentación. ¿Podría agregar una referencia?
Alex

44
Para aquellos que no les gustan las opciones abreviadas, -ees --edit.
Kolyunya

2
@Alex Las citas de referencia agregadas por TheFreedomBanana son de la sección EDICIÓN DE PARCHES engit --help add
Randall

8
Esta es la única respuesta (que requiere solo git) que resuelve el problema de agregar / quitar líneas sabias cuando no se pueden hacer trozos más pequeños con el smodo de parche interactivo.
cdosborn

3
Puede ser útil comprender que este comando ( git add -e) * no * cambia el contenido del archivo en el disco. Simplemente mueve parte de los cambios de unstaged a staged (index).
Penghe Geng

44

Si está utilizando vim, es posible que desee probar el excelente complemento llamado fugitivo .

Puede ver la diferencia de un archivo entre la copia de trabajo y el índice con :Gdiff, y luego agregar líneas o trozos al índice usando los comandos clásicos de vim diff como dp. Guarde las modificaciones en el índice y confirme con :Gcommit, y ya está.

Muy buenas presentaciones introductorias aquí (ver especialmente la parte 2 ).


Muchas gracias por estos enlaces. Exactamente lo mismo que necesito. Especialmente :diffget/:diffputen modo visual, donde puedo elegir líneas específicas, que quiero restablecer / confirmar. Entonces, asegúrate de nuevo: vim es increíble.
goodniceweb

30

Recomiendo encarecidamente usar SourceTree de Atlassian. (Es gratis.) Hace que esto sea trivial. Puede organizar trozos de código individuales o líneas de código individuales rápida y fácilmente.

ingrese la descripción de la imagen aquí


1
Estoy de acuerdo en que SourceTree es una buena herramienta para este propósito, ya que le brinda un control más detallado que lo que es posible a través de la línea de comando.

19
@cupcake Yo diría lo contrario, ya que SourceTree probablemente usa esos ejecutables git de línea de comando, inherentemente siempre será posible hacer las mismas (o más) acciones detalladas a través de la "línea de comando".
tutuDajuju

2
Independientemente del argumento detallado , recomiendo encarecidamente SourceTree, ya que organizar trozos y líneas individuales es muy fácil: i.imgur.com/85bNu4C.png
Mars Robertson

1
@tutuDajuju En este caso, no estoy seguro de que sea cierto. SourceTree tiene la capacidad de elegir qué partes organizar etapa por línea . No tienes que poner en escena un trozo entero; puedes colocar 2 líneas en el medio de un trozo. Sin embargo, no tengo idea de cómo lo logra. (Por el momento, estoy tratando de evitar la incapacidad de SourceTree para organizar líneas particulares para un archivo sin seguimiento. Llegué aquí buscando una solución alternativa, solo para encontrar que git aparentemente no parece ofrecer la capacidad línea por línea en absoluto. Al menos no de una manera directa.)
jpmc26

1
@ Sol, puede hacer clic en la línea 50 y hacer clic en Mayús + clic en la línea 100 y luego en la etapa. Puede organizar fácilmente la línea 50-100 en Sourcetree :)
ryan123

26

Vale la pena señalar que para usar git add --patchpara un nuevo archivo , primero debe agregar el archivo para indexar con git add --intent-to-add:

git add -N file
git add -p file

23

Cuando tenga muchos cambios y termine creando algunas confirmaciones a partir de los cambios, entonces quiero guardar mi punto de partida temporalmente antes de organizar las cosas.

Me gusta esto:

$ git stash -u
Saved working directory and index state WIP on master: 47a1413 ...
$ git checkout -p stash
... step through patch hunks
$ git commit -m "message for 1st commit"
$ git checkout -p stash
... step through patch hunks
$ git commit -m "message for 2nd commit"
$ git stash pop

La respuesta de Whymarrh es lo que suelo hacer, excepto que a veces hay muchos cambios y puedo decir que podría cometer un error al organizar las cosas, y quiero un estado comprometido al que pueda recurrir para un segundo pase.


12

Si usa emacs, eche un vistazo a Magit , que proporciona una interfaz git para emacs. Es compatible con la organización de trozos (partes de archivos) bastante bien.


A menudo me tropiezo con un comando git que quiere abrir un editor, cuando lo ejecuto desde una ventana de shell Mx. ¿Magit intercepta esa locura y abre solo un nuevo amortiguador para eso? (por favor, no hay pistas de background-emacs-daemon; gracias de todos modos, pero la vida es demasiado corta).
user2066657

No, por lo que puedo decir, no intercepta esto. Pero no solo tome mi palabra porque (1) casi nunca uso la ventana de shell en Emacs, y (2) normalmente uso emacsclient. Dicho esto, si emacsclient es una opción para usted, eso al menos evitó que se abriera una ventana adicional con emacs y se abrió el búfer "COMMIT_EDITMSG" en mi ventana Emacs existente.
Mark van Lent


9

Para aquellos que usan extensiones Git :

En la ventana Confirmar, seleccione el archivo que desea confirmar parcialmente, luego seleccione el texto que desea confirmar en el panel derecho, luego haga clic derecho en la selección y elija 'Etapa de líneas seleccionadas' en el menú contextual.


2
El método abreviado de teclado en Git Extensions para 'Etapa de líneas seleccionadas' es smuy útil para organizar rápidamente partes de archivos para una confirmación.
Alchemistmatt

8

Al igual que la respuesta de jdsumsion, también puede esconder su trabajo actual, pero luego usar una herramienta difftool como meld para extraer los cambios seleccionados del alijo. De esa manera, incluso puede editar los trozos manualmente de manera muy fácil, lo que es un poco molesto cuando está en git add -p:

$ git stash -u
$ git difftool -d -t meld stash
$ git commit -a -m "some message"
$ git stash pop

El uso del método de ocultación le brinda la oportunidad de probar, si su código aún funciona, antes de confirmarlo.


esto funciona bien, pero si lo usa git commit --amend, parece que no puede abrir el alijo después, ¿o hay alguna forma de hacerlo?
Marcar el

7

Agregando una respuesta anterior, si prefiere usar la línea de comando, ingresar git add -e myfilele da la opción de elegir línea por línea lo que desea confirmar porque este comando abrirá un editor con las diferencias, así:

ingrese la descripción de la imagen aquí

Como puede saber, las líneas que comienzan con +son adiciones, las líneas que comienzan con -son eliminaciones. Entonces:

  • Para no realizar una adición, simplemente elimine esa línea.
  • Para no organizar una eliminación, simplemente reemplácela -con espacio .

Esto es lo que git add -hdice acerca de agregar archivos de esta manera (parchear archivos):

contenido agregado El contenido agregado se representa mediante líneas que comienzan con "+". Puede evitar la organización de las líneas de adición eliminándolas.

contenido eliminado: el contenido eliminado se representa mediante líneas que comienzan con "-". Puede evitar que su eliminación se convierta en etapas convirtiendo el "-" en un "" (espacio).

contenido modificado: el contenido modificado se representa con líneas "-" (eliminando el contenido anterior) seguido de líneas "+" (agregando el contenido de reemplazo). Puede evitar organizar la modificación convirtiendo las líneas "-" en "" y eliminando las líneas "+". Tenga en cuenta que modificar solo la mitad del par probablemente introducirá cambios confusos en el índice.

Precaución: no cambie el contenido del archivo, este no es un buen lugar para hacerlo. Simplemente cambie los operadores de las líneas eliminadas o agregadas.


¿Qué respuesta anterior? Las respuestas se almacenan en función de la cantidad de puntos que tienen. Entonces, su respuesta está en un lugar diferente ahora que cuando la escribió en comparación con otras respuestas.
KulaGGin

Creo que la respuesta referenciada es de @theFreedomBanana
K. Symbol

6

El complemento vim-gitgutter puede organizar a los trozos sin salir del editor vim usando

:GitGutterStageHunk

Además de esto, proporciona otras características interesantes como una columna de signo de diferencia como en algunos IDE modernos

Si solo una parte del trozo se escenificara vim-fugitiva

:Gdiff

permite la selección del rango visual en ese momento :'<,'>diffputo :'<,'>diffgetpara organizar / revertir cambios de línea individuales.



4

Con TortoiseGit:

haga clic derecho sobre el archivo y úselo Context Menu → Restore after commit. Esto creará una copia del archivo tal como está. Luego puede editar el archivo, por ejemplo, en TortoiseGitMerge y deshacer todos los cambios que no desea confirmar. Después de guardar esos cambios, puede confirmar el archivo.


4

Han pasado 10 años desde que se hizo esta pregunta. Y espero que esta respuesta sea útil para alguien. Como se menciona en la respuesta aquí , donde GUI no es una opción, la extensión de crecord de Andrew Shadura ayuda a abrir una ventana ncurses en la que podemos seleccionar las líneas para confirmar.

Configure la extensión de la siguiente manera:

git clone https://github.com/andrewshadura/git-crecord
cd git-crecord
./setup.py install
ln -s $PWD/git-crecord ~/.local/bin/git-crecord

cd a su repositorio git e invocarlo de la siguiente manera:

git crecord

Esto abriría la interfaz ncurses que se puede usar como se muestra a continuación. Al presionar las siguientes teclas en la ventana ncurses se realizarán ciertas acciones:

f       hunk toggle fold (arrow keys can also be used)
space   toggle hunk selection
a       toggle commit or amend
c       confirm and open commit window

Screencast que muestra un uso de muestraEjemplo


3

Para los usuarios de Atom , el paquete github incluye puesta en escena interactiva, al estilo de git gui. Para accesos directos, consulte la documentación del paquete .

El uso de Atom permite trabajar con un tema que tiene un fondo oscuro (de forma predeterminada, git guitiene un fondo blanco).



2

git-meld-index - citando del sitio web:

git-meld-index ejecuta meld, o cualquier otro git difftool (kdiff3, difuso, etc.), para permitirle organizar de manera interactiva los cambios en el índice git (también conocido como el área de preparación de git).

Esto es similar a la funcionalidad de git add -p y git add --interactive. En algunos casos, meld es más fácil / rápido de usar que git add -p. Esto se debe a que meld te permite, por ejemplo:

  • ver más contexto
  • ver diferencias entre líneas
  • edite a mano y vea actualizaciones de diferencias 'en vivo' (actualizadas después de cada pulsación de tecla)
  • navegue a un cambio sin decir 'n' a cada cambio que desee omitir

Uso

En un repositorio de git, ejecute:

git meld-index

Verás meld (o tu git difftool configurado) emergente con:

IZQUIERDA : directorio temporal que continúa archivos copiados de su árbol de trabajo

DERECHA : directorio temporal con el contenido del índice. Esto también incluye archivos que aún no están en el índice pero que están modificados o no se encuentran en la copia de trabajo; en este caso, verá el contenido del archivo de HEAD.

Edite el índice (lado derecho) hasta que esté satisfecho. Recuerde guardar cuando sea necesario.

Cuando haya terminado, cierre meld, y git-meld-index actualizará el índice para que coincida con el contenido del directorio temporal en el lado derecho de meld que acaba de editar.


2

Si está en la Windowsplataforma, en mi opinión git guies una herramienta muy buena para stage/ commitpocas líneas del unstagedarchivo

1. Hunk sabio:

  • Seleccione el archivo de la unstagged Changessección
  • Haga clic con el botón derecho en un fragmento de código que debe organizarse
  • Seleccione Stage Hunk for commit

2. Línea sabia:

  • Seleccione el archivo de la unstagged Changessección
  • Seleccione la línea / líneas a organizar
  • Haga clic derecho y seleccione Stage Lines for commit

3. Si desea organizar el archivo completo excepto un par de líneas:

  • Seleccione el archivo de la unstagged Changessección
  • prensa Ctrl+T (Stage file to commit)
  • El archivo seleccionado ahora se mueve a la Staged ChangesSección
  • Seleccione la línea / líneas que se organizarán
  • Haga clic derecho y seleccione UnStage Lines for commit

1

Como muestra una respuesta anterior, puede usar git add --patch filename.txt

o la forma corta git add -p filename.txt

... pero para los archivos que ya están en su repositorio, existe una mejor opción para usar s --patch flag en el comando commit directamente (si está utilizando una versión de git lo suficientemente reciente): git commit --patch filename.txt

... o, de nuevo, la forma corta git commit -p filename.txt

... y luego usando las teclas mencionadas, (s / n, etc.), para elegir las líneas que se incluirán en la confirmación.


¿Qué le da eso " git add -p filename.txt" además de menos margen de error? Si estropea el cambio de archivo parcial, deshacer un complemento es mejor que deshacer una confirmación.
CTMacUser

No sé por qué, pero cuando digo 'n' la línea se incluye ... y cuando digo 'y' en el segundo trozo, también se incluye.
chovy

1

git-cola es una gran GUI y también tiene esta característica incorporada. Simplemente seleccione las líneas para escenificar y presione S. Si no se realiza ninguna selección, se organiza el trozo completo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.