git add --interactive "Tu trozo editado no se aplica"


85

Estoy tratando de usar git add --interactivepara agregar selectivamente algunos cambios a mi índice, pero continuamente recibo el mensaje "Tu trozo editado no se aplica. Edita de nuevo ...". Recibo este mensaje incluso si elijo la opción e, e inmediatamente guardo / cierro mi editor. En otras palabras, sin editar el trozo en absoluto, el parche no se aplica.

Aquí está el ejemplo exacto que estoy usando (estoy tratando de armar una pequeña demostración):

Archivo original:

first change
second change off branch
third change off branch
second change
third change
fourth change

Archivo nuevo:

Change supporting feature 1
first change
second change off branch
third change off branch
second change
third change
fourth change
bug fix 1
change supporting feature 1

Estoy tratando de mostrar cómo usar git add --interactivepara agregar solo la línea "corrección de error 1" al índice. Al ejecutar el complemento interactivo en el archivo, elijo el modo de parche. Me presenta

diff --git a/newfile b/newfile
index 6d501a3..8b81ae9 100644
--- a/newfile
+++ b/newfile
@@ -1,6 +1,9 @@
+Change supporting feature 1
 first change
 second change off branch
 third change off branch
 second change
 third change
 fourth change
+bug fix 1
+change supporting feature 1

Respondo con split, seguido de "no" para aplicar el primer trozo. El segundo trozo, trato de editar. Originalmente intenté eliminar el resultado final, eso no funcionó. Dejar al galán solo por completo tampoco funciona, y no puedo entender por qué.


Una buena cosa de la que debe asegurarse aquí es que no está agregando -'s al principio de líneas que no existen en el archivo para empezar; es una diferencia y no puede eliminar líneas que aún no están allí. Entonces, si una línea en la diferencia comienza con +y la cambia a -git, ¿se vuelve WTF? porque ahora la línea marcada para ser eliminada no existe para empezar (en su lugar, esa línea fue marcada para agregar, y cuando una línea marcada para agregar está marcada para eliminación, git no puede eliminar una línea que aún no está en el archivo) .
leeand00

1
Verifique también los finales de línea (LF, CRLF) en mi caso, ¡no se aplicó para un LF en lugar de CRLF!
Alberto Rivelli

Respuestas:


37

Para este ejemplo en particular, necesita ajustar los números de línea en el trozo. Cambiar la línea:

@@ -1,6 +2,8 @@

para que en su lugar lea:

@@ -2,7 +2,8 @@

16
Después de investigar un poco, descubrí que esas líneas muestran el "rango desde el archivo" y el "rango al archivo". Realmente no entiendo la lógica detrás de cambiar el 1 a un 2. Lo probé y funciona, pero no entiendo por qué cambia el "rango del archivo". El archivo original es el mismo, ya sea que esté aplicando el parche completo o solo el trozo editado. ¿Puede aclarar más o señalarme una referencia de descenso en el formato de diferencia unificado? No he podido encontrar uno.
Josh

9
@Josh: stackoverflow.com/questions/2529441/… puede ayudar, incluso si no obtengo por completo los trozos de formato unificado. @William +1
VonC

5
@Josh: Al mirarlo, parece que puede ser un error. Después de editar el trozo, git intenta verificar el parche verificando que se apliquen todos los trozos (esto puede ser excesivo). Desafortunadamente, en este caso, eso significa que el trozo anterior (que no está aplicando) está siendo verificado, y hay cierta superposición que hace que git apply --check falle. No conozco una solución elegante; git puede estar haciendo lo correcto al ser demasiado cauteloso aquí.
William Pursell

22
¿Más información sobre cómo cambiar los números de línea, por favor? ¿Por qué tenemos que hacer eso? ¿Y cómo? ¿Qué significa cada número?
Bill

4
@WilliamPursell ¿qué versiones de git? Me cambié a una computadora nueva y ejecuté git v2.17.0 y, de repente, las ediciones de mi parche ya no son válidas.
Dennis

104

¿Es esto como en esta publicación de git-add ?

Editar manualmente el trozo es inmensamente poderoso, pero también un poco complicado si nunca lo ha hecho antes.
Lo más importante a tener en cuenta: la diferencia siempre tiene sangría con un carácter además de cualquier otra sangría que haya.
El personaje puede ser:

  • un espacio (indica una línea sin cambios),
  • a -que indica que la línea fue eliminada,
  • o +indicando que se agregó la línea.

Nada más. Debe ser un espacio, un - o un +. Cualquier otra cosa, y obtendrá errores
(no hay carácter para una línea cambiada, ya que estos se manejan eliminando la línea anterior y agregando la cambiada como nueva).

Dado que tiene la diferencia abierta en su editor de texto favorito (configuró Git para usar su editor de texto favorito, ¿verdad?), Puede hacer lo que quiera, siempre que se asegure de que la diferencia resultante se aplique limpiamente.

Y ahí está el truco. Si nunca ha hecho esto antes, Git le dirá "Su trozo editado no se aplica. ¿Editar de nuevo?" muy a menudo, comenzará a odiarse a sí mismo por su incapacidad para resolver esto , a pesar de que parece tan fácil (o Git porque no puede descubrir lo que quiere).

Una cosa que me hizo tropezar con bastante frecuencia fue que olvidé la sangría de un carácter.
Marcaría una línea con una - para eliminarla, pero en la mayoría de los editores de texto que inserta una -, no sobrescribe el espacio que había antes. Esto significa que está agregando un espacio adicional a toda la línea, lo que a su vez significa que el algoritmo de diferencias no puede encontrar / hacer coincidir la línea en el archivo original, lo que a su vez significa que Git le gritará .

La otra cosa es que la diferencia todavía tiene que tener sentido. "Sense" significa que se puede aplicar limpiamente. Exactamente cómo crea una diferencia sensible parece ser un arte oscuro (al menos para mí en este momento), pero siempre debe tener en cuenta cómo se veía el archivo original y luego planificar sus -s y + s en consecuencia. Si edita sus macizos con la suficiente frecuencia, eventualmente lo dominará.

Vea también esta confirmación en git add -p .

La respuesta de Ortomala Lokni se refiere a la publicación del blog de Joaquín Windmüller " Seleccione de forma selectiva los cambios para confirmar con git (o Imma edita su trozo) "

En lugar de contar líneas, lo que a Git le gustaría hacer es fusionar trozos superpuestos (cuando se edita uno) antes de aplicar dicho trozo editado.
Eso se discutió a mediados de 2018 y evitaría escenarios como:

si divide un trozo, edite el primer sub trozo, transformando una línea de contexto final en una eliminación, luego, si intenta organizar el segundo sub trozo, fallará.


5
Gracias por el enlace, pero ya lo había visto. No estaba agregando / dejando una línea adicional. El problema estaba en los números de línea, pero todavía no entiendo la solución.
Josh

9
No estaba reemplazando un '-' eliminado con un espacio en blanco, arruinando así la sangría. ¡¡Gracias!!
pedorro

Solo asegúrese de no malinterpretar la parte del espacio en blanco. Pensé que todas las líneas sin cambios deberían ser solo una línea con un negro, en lugar de simplemente el carácter de sangría ... Tuve una hora de "trozo editado no se aplica" hasta que entendí por qué: - /
oligofren

@oligofren No estoy seguro de entenderlo: ¿qué tuvo que hacer para que se aplicara su trozo editado?
VonC

1
@VonC: Primero pensé que debería cambiar - foo a "(solo un espacio en blanco, no" un espacio en blanco y toda la línea "). Me tomó un tiempo entender que debería haber sido "foo".
oligofren

48

Por supuesto, llegué tarde a esto, pero de todos modos quería mencionar que este tema se discutió el año pasado en la lista de correo de git y parece que no ha cambiado mucho desde entonces.

Este problema en particular se debe a dividir e intentar editar el mismo trozo. El análisis, publicado originalmente por Jeff King, del problema subyacente es esencialmente:

Hm. OK veo. La verificación "¿se aplica esta diferencia?" Alimenta ambas partes del parche dividido para aplicar git. Pero, por supuesto, la segunda parte nunca se aplicará correctamente, porque su contexto se superpone con la primera parte, pero no lo tiene en cuenta.

Hacer la comprobación con solo el parche editado funcionaría. Pero eso no tiene en cuenta que su parche editado potencialmente no se aplicará a largo plazo, dependiendo de si acepta o no la otra mitad del parche dividido. Y no podemos saber eso todavía, porque es posible que el usuario no nos lo haya dicho (podría haberse saltado la primera mitad y luego volver a ella después del paso de edición).

Jeff concluye su publicación con una solución muy pragmática que siempre tiene éxito y, por lo tanto, es muy recomendable:

Entonces, en general, creo que dividir y editar el mismo trozo es intrínsecamente peligroso y conducirá a este tipo de problemas. Y debido a que la edición proporciona un superconjunto de la funcionalidad, creo que debería editar y permitir que se aplique o no la primera parte del trozo, según sus preferencias.

Si solo elige editar un trozo que no haya sido dividido previamente, no tendrá que lidiar con los números de línea.


6
Gracias, esto es mucho más fácil que jugar con los números de línea.
michiakig

3
Este era mi problema. Necesitaba que mi galán fuera más pequeño. Realizó un split en interactivo. La división no era lo que quería, así que decidí intentar editar manualmente. Seguía recibiendo el error. Comenzó de nuevo, trabajó en el primer intento.
Kyle s

Esta es la mejor respuesta en este hilo. No divida y edite. Solo edita.
Dr_Zaszuś

En mi caso, un problema adicional provenía de los finales de línea de Windows que se muestran como ^Men el archivo diff. Una vez que guardé el archivo con terminaciones CR, ¡se ejecutó el parche de edición interactivo!
Dr_Zaszuś

Gracias, esto me sirvió. Tuve que trabajar en un gran trozo, así que lo dividí y todo se rompió. Mantenerlo sin dividir hizo que todo funcionara bien.
Matthias Fischer

16

Cuando no desea eliminar una línea que se preparó para su eliminación, como en

 first line
-second line
 third line

donde desea mantener la segunda línea, asegúrese de reemplazarla -con un espacio, en lugar de eliminar toda la línea (como lo haría para deshacerse de una línea agregada). Git usará la línea para el contexto.


1
Esto no estaba claro para mí, pensé que Git me estaba diciendo que hiciera de la línea un solo espacio.
JackHasaKeyboard

15

También es importante modificar correctamente el encabezado del trozo (por ejemplo @@ -1,6 +1,9 @@). Joaquin Windmuller revela el secreto de la edición de encabezados en una de las publicaciones de su blog .

Los secretos de editar macizos

Editar los hunks puede ser confuso al principio, las instrucciones que te da git te ayudan pero no son suficientes para empezar.

# —||

# To remove ‘-’ lines, make them ’ ’ lines (context).

# To remove ‘+’ lines, delete them.

# Lines starting with # will be removed.

#

# If the patch applies cleanly, the edited hunk will immediately be

# marked for staging. If it does not apply cleanly, you will be given

# an opportunity to edit again. If all lines of the hunk are removed,

# then the edit is aborted and the hunk is left unchanged.

La salsa secreta es ... contar líneas:

  • Si elimina una línea que comienza con +, reste una al nuevo recuento de líneas (último dígito del encabezado del trozo) .
  • Si elimina una línea que comienza con - entonces agregue una al nuevo recuento de líneas (último dígito del encabezado del trozo) .
  • No elimine las otras líneas (líneas de referencia).

Esto debería permitirle modificar rápidamente los trozos para seleccionar las partes que desee.


1
¿Hay alguna forma de automatizar la edición del encabezado del trozo o configurar git para determinar los recuentos de líneas apropiados?
Dennis

Probablemente puedas programar tu editor favorito para automatizar esto. Quizás ya haya algunos complementos para esto, pero esto depende del editor.
Ortomala Lokni

13

Recientemente, al leer este hilo, descubrí cómo hacer la edición manual.

El truco que utilicé fue que si tengo una diferencia como:

+ Line to add
+ Line to add
+ Line I dont want to include
+ Line I dont want to include

El truco es eliminar por completo las dos líneas que no quiero, haciendo que la diferencia resultante se vea así:

+ Line to add
+ Line to add

Si bien esto probablemente sea obvio para la mayoría de las personas, no lo fue para mí hasta hoy y pensé que debería compartir mi experiencia. Por favor dígame si existe algún peligro con este método.


2
¡No puedo agradecerles lo suficiente! Yo estaba tratando de cambiar el +en una ' 'por lo menos durante una hora.
soumer

Ya sabes, la locura es hacer lo mismo y esperar un resultado diferente. Me he estado diciendo eso durante 20 minutos antes de darme cuenta de que solo necesitaba borrar :)
solidak

7

Puede editar manualmente los números de línea, lo que definitivamente es útil en algunos casos. Sin embargo, probablemente podría haber evitado este problema en particular NO dividiendo primero el trozo.

Si ve que probablemente necesitará editar algo más adelante en el trozo que Git ha elegido automáticamente, es mejor editar todo el trozo en lugar de dividir, preparar la mitad y luego editar la otra mitad. Git hará un mejor trabajo averiguando eso.


6

Llegué a esta pregunta buscando una solución al mismo problema y no pude averiguar cómo cambiar los números de línea (como se sugirió anteriormente) en el trozo para que git lo aceptara en mi caso. Sin git guiembargo, encontré una manera mucho mejor de hacerlo usando . Allí puede seleccionar las líneas en el diff que desea escenificar, luego hacer clic derecho y elegir "Stage lines from commit". Recuerdo que git-cola también tiene la misma funcionalidad.


Esta realmente debería ser la respuesta. git-colaparece funcionar en Linux, Windows y MacOS.
leeand00

5

Un problema adicional que tuve cuando recibí este error fue que los finales de línea cambiaron cuando guardé el archivo de edición.

Estaba usando Windows y usando el Bloc de notas para mis ediciones (solo guarda con finales de línea de Windows). Mi código fue escrito con Notepad ++ y lo configuré para tener terminaciones de línea estilo Unix / Linux.

Cuando cambié mi configuración para tener Notepad ++ como el editor de git predeterminado, pude hacer mis ediciones en el trozo.

git config --global core.editor "notepad++"

1
Esto funcionó para mí. Pero necesitaba la ruta completa a notepad ++ y eso tomó un tiempo para hacerlo bien: git config --global core.editor '"C:/Program\ Files\ \(x86\)/Notepad++/notepad++.exe"' (adapte esto de acuerdo a dónde está instalado notepad ++ en su PC)
Annabel

1
Exactamente el mismo problema para mí. Era el Bloc de notas el que estaba causando problemas. Una vez que cambié mi editor predeterminado a Notepad ++, todo comenzó a funcionar nuevamente.
Johnny Oshika

4

Una razón para los extraños mensajes "Su trozo editado no se aplica" (probablemente acompañado de algo como "error: fragmento de parche sin encabezado en la línea ...") podría ser su editor si está configurado para eliminar los espacios en blanco finales. Obviamente, esto causaría problemas importantes, ya que los parches codifican líneas vacías, ya que las líneas con un espacio, cualquier trozo que contenga líneas vacías no se aplicaría si se guardara con dicho editor. Entonces, en efecto, cualquier trozo que contenga líneas vacías sin cambios no se aplicaría después de editar con si la eliminación de los espacios en blanco finales está activada.


0

Para su información, estaba obteniendo un error ligeramente interrelacionado ... cuando agregué un parche siguiendo las instrucciones sugeridas anteriormente ... Sin embargo, no mostraba ningún error. Lo recibía repetidamente pidiéndome que escenificara el mismo trozo ... Me di cuenta de que estaba ejecutando una versión anterior de Vim 7.4 ... Actualicé vim y ahora funciona como se esperaba. Espero que esto ayude a alguien..

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.