git add --interactive "Ihr bearbeiteter Hunk trifft nicht zu"

85

Ich versuche, git add --interactiveeinige Änderungen selektiv zu meinem Index hinzuzufügen, erhalte jedoch ständig die Meldung "Ihr bearbeiteter Teil gilt nicht. Erneut bearbeiten ...". Ich erhalte diese Meldung auch dann, wenn ich die Option e wähle und meinen Editor sofort speichere / schließe. Mit anderen Worten, ohne das Stück überhaupt zu bearbeiten, gilt der Patch nicht.

Hier ist das genaue Beispiel, das ich verwende (ich versuche, eine kleine Demo zusammenzustellen):

Originaldatei:

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

Neue Datei:

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

Ich versuche zu zeigen, wie man verwendet, git add --interactiveum nur die Zeile "Bugfix 1" zum Index hinzuzufügen. Wenn ich das interaktive Hinzufügen der Datei ausführe, wähle ich den Patch-Modus. Es präsentiert mich mit

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

Ich antworte mit Split, gefolgt von "Nein", um das erste Stück anzuwenden. Das zweite Stück versuche ich zu bearbeiten. Ich habe ursprünglich versucht, das Endergebnis zu löschen - das hat nicht funktioniert. Das Stück ganz alleine zu lassen, funktioniert auch nicht, und ich kann nicht herausfinden, warum.

Josh
quelle
Stellen Sie hier sicher, dass Sie keine -Zeilen am Anfang von Zeilen hinzufügen , die in der Datei zunächst nicht vorhanden sind. Es ist ein Unterschied und kann keine Zeilen löschen, die noch nicht vorhanden sind. Also, wenn eine Zeile im Diff mit beginnt +und Sie sie in -Git ändern, geht WTF? weil jetzt die zum Entfernen markierte Zeile zunächst nicht vorhanden ist (stattdessen wurde diese Zeile zum Hinzufügen markiert, und wenn eine zum Hinzufügen markierte Zeile zum Entfernen markiert ist, kann git eine Zeile nicht entfernen, die noch nicht in der Datei enthalten ist). .
leeand00
1
Überprüfen Sie auch die Zeilenenden (LF, CRLF), in meinem Fall galt dies nicht für einen LF anstelle von CRLF!
Alberto Rivelli

Antworten:

39

In diesem Beispiel müssen Sie die Zeilennummern im Hunk anpassen. Ändern Sie die Zeile:

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

so dass es stattdessen lautet:

@@ -2,7 +2,8 @@
William Pursell
quelle
16
Nach einigem Graben stellte ich fest, dass diese Zeilen den "Bereich von Datei" und "Bereich von Datei zu Datei" anzeigen. Ich verstehe die Logik hinter dem Ändern der 1 in eine 2 nicht wirklich. Ich habe es versucht und es funktioniert, aber ich verstehe nicht, warum sich der "From-File-Bereich" ändert. Die Originaldatei ist dieselbe, unabhängig davon, ob ich den gesamten Patch oder nur das bearbeitete Stück anwende. Können Sie dies näher erläutern oder mich auf eine Abstiegsreferenz zum einheitlichen Diff-Format hinweisen? Es ist mir nicht gelungen, einen zu finden.
Josh
9
@Josh: stackoverflow.com/questions/2529441/… kann helfen, auch wenn ich die Hunks im Unified-Format nicht vollständig erhalte. @ William +1
VonC
5
@ Josh: Wenn man es sich ansieht, sieht es so aus, als wäre es ein Fehler. Nachdem Sie den Hunk bearbeitet haben, versucht git, den Patch zu überprüfen, indem überprüft wird, ob alle Hunks angewendet werden (dies kann übermäßig sein). In diesem Fall bedeutet dies leider, dass der vorherige Teil (den Sie nicht anwenden) überprüft wird und es einige Überlappungen gibt, die dazu führen, dass git apply --check fehlschlägt. Ich kenne keine elegante Lösung; git kann das Richtige tun, indem er hier übermäßig vorsichtig ist.
William Pursell
19
Weitere Informationen zum Ändern der Zeilennummern bitte? Warum müssen wir das tun? Und wie? Was bedeutet jede Zahl?
Bill
4
@ WilliamPursell welche Versionen von Git? Ich habe auf einen neuen Computer gewechselt und git v2.17.0 ausgeführt, und plötzlich sind meine Patch-Änderungen nie mehr gültig.
Dennis
104

Ist das wie in diesem Git-Add-Beitrag ?

Das manuelle Bearbeiten des Stücks ist immens leistungsfähig, aber auch etwas kompliziert, wenn Sie es noch nie zuvor getan haben.
Das Wichtigste, das Sie beachten sollten: Der Diff wird immer mit einem Zeichen eingerückt, zusätzlich zu den anderen Einrückungen.
Der Charakter kann entweder sein:

  • ein Leerzeichen (zeigt eine unveränderte Linie an),
  • a -zeigt an, dass die Linie entfernt wurde,
  • oder ein +Hinweis darauf, dass die Zeile hinzugefügt wurde.

Nichts anderes. Es muss entweder ein Leerzeichen, ein - oder ein + sein. Alles andere, und Sie erhalten Fehler
(es gibt kein Zeichen für eine geänderte Zeile, da diese behandelt werden, indem die alte Zeile entfernt und die geänderte als neu hinzugefügt wird).

Da Sie das Diff in Ihrem bevorzugten Texteditor geöffnet haben (Sie haben Git so konfiguriert, dass es Ihren bevorzugten Texteditor verwendet, oder?), Können Sie tun, was Sie wollen - solange Sie sicherstellen, dass das resultierende Diff sauber angewendet wird.

Und darin liegt der Trick. Wenn Sie dies noch nie zuvor getan haben, wird Git Ihnen mitteilen, dass Ihr bearbeiteter Teil nicht zutrifft. Erneut bearbeiten? So oft wirst du anfangen, dich dafür zu hassen, dass du das nicht herausfinden kannst, obwohl es so einfach zu sein scheint (oder Git, weil es nicht herausfinden kann, was du willst).

Eine Sache, die mich ziemlich oft auslöste, war, dass ich den Einzug eines Zeichens vergessen hatte.
Ich würde eine Zeile mit einem - markieren, um sie zu entfernen, aber in den meisten Texteditoren, die a einfügen -, wird der zuvor vorhandene Platz nicht überschrieben. Dies bedeutet, dass Sie der gesamten Zeile ein zusätzliches Leerzeichen hinzufügen, was wiederum bedeutet, dass der Diff-Algorithmus die Zeile in der Originaldatei nicht finden / abgleichen kann, was wiederum bedeutet, dass Git Sie anschreit .

Die andere Sache ist, dass der Unterschied immer noch Sinn machen muss. "Sinn" bedeutet, dass es sauber angewendet werden kann. Genau wie Sie ein vernünftiges Diff erstellen, scheint eine dunkle Kunst zu sein (zumindest für mich im Moment), aber Sie sollten immer daran denken, wie die Originaldatei aussah, und dann Ihre -s und + s entsprechend planen. Wenn Sie Ihre Hunks oft genug bearbeiten, werden Sie irgendwann den Dreh raus bekommen.

Siehe auch dieses Commit für git add -p .

Ortomala Lokni ‚s Antwort bezieht sich auf Joaquín Windmüller Blog - Eintrag‚ Selektiv select Änderungen mit git (oder Imma bearbeiten Ihr großes Stück) zu begehen

Anstatt Zeilen zu zählen, möchte Git überlappende Hunks (wenn einer bearbeitet wird) zusammenführen, bevor der bearbeitete Hunk angewendet wird.
Das wurde Mitte 2018 besprochen und würde Szenarien wie: vermeiden.

Wenn Sie einen Teil teilen, den ersten Teil bearbeiten und eine nachfolgende Kontextzeile in eine Löschung umwandeln, schlägt dies fehl, wenn Sie versuchen, den zweiten Teil zu inszenieren.

VonC
quelle
5
Danke für den Link, aber das hatte ich schon gesehen. Ich habe keine zusätzliche Zeile hinzugefügt / verlassen. Das Problem lag in den Zeilennummern, aber ich verstehe das Update immer noch nicht.
Josh
9
Ich habe ein gelöschtes '-' nicht durch ein Leerzeichen ersetzt, wodurch die Einrückung durcheinander gebracht wurde. Vielen Dank!!
Pedorro
Stellen Sie nur sicher, dass Sie das Leerzeichen nicht falsch verstehen. Ich dachte, alle unveränderten Zeilen sollten nur eine Zeile mit einem schwarzen sein - anstelle nur des Einrückungszeichens ... Hatte eine Stunde "bearbeitetes Stück gilt nicht", bis ich verstand warum: - /
Oligofren
@oligofren Ich bin mir nicht sicher, ob ich dich verstehe: Was mussten Sie tun, damit sich Ihr bearbeitetes Stück bewarb?
VonC
1
@VonC: Ich dachte zuerst, ich sollte - foo in `` wechseln (nur ein Leerzeichen, nicht "ein Leerzeichen und die gesamte Zeile"). Ich habe eine Weile gebraucht, um zu verstehen, dass es "foo" sein sollte.
Oligofren
48

Natürlich bin ich zu spät dran, wollte aber trotzdem für die Aufzeichnung erwähnen, dass dieses Problem letztes Jahr auf der Git-Mailingliste diskutiert wurde und sich seitdem anscheinend nicht viel geändert hat.

Dieses spezielle Problem ergibt sich aus der Aufteilung und dem Versuch, dasselbe Stück zu bearbeiten. Die ursprünglich von Jeff King veröffentlichte Analyse des zugrunde liegenden Problems lautet im Wesentlichen:

Hm. OK, ich verstehe. Die Check-Feeds "Gilt dieser Unterschied?" beide Teile des geteilten Patches zu Git-Apply. Aber natürlich wird der zweite Teil niemals richtig angewendet, da sich sein Kontext mit dem ersten Teil überschneidet, ihn aber nicht berücksichtigt.

Den Check mit just machen dem bearbeiteten Patch würde funktionieren. Dies berücksichtigt jedoch nicht, dass Ihr bearbeiteter Patch möglicherweise auf lange Sicht nicht angewendet werden kann, je nachdem, ob Sie die andere Hälfte des geteilten Patches akzeptieren oder nicht. Und das können wir noch nicht wissen, weil der Benutzer es uns möglicherweise nicht gesagt hat (er hätte die erste Hälfte überspringen und später nach dem Bearbeitungsschritt darauf zurückkommen können).

Jeff schließt seinen Beitrag mit einer sehr pragmatischen Problemumgehung ab, die immer erfolgreich ist und daher dringend empfohlen wird:

Im Allgemeinen denke ich, dass das Teilen und Bearbeiten desselben Teils von Natur aus gefährlich ist und zu solchen Problemen führen wird. Und da das Bearbeiten eine Obermenge der Funktionalität bietet, sollten Sie es einfach bearbeiten und entweder zulassen, dass der erste Teil des Hunks angewendet wird, oder nicht, je nach Ihren Vorlieben.

Wenn Sie nur ein Stück bearbeiten, das zuvor nicht geteilt wurde, müssen Sie sich nicht mit den Zeilennummern befassen.

Niels Ganser
quelle
6
Danke, das ist in der Tat viel einfacher als mit Zeilennummern herumzuspielen.
michiakig
3
Das war mein Problem. Ich brauchte mein Stück, um kleiner zu sein. Split in interaktiv durchgeführt. Die Aufteilung war nicht das, was ich wollte, also entschied ich mich, manuell zu bearbeiten. Habe den Fehler erhalten. Von vorne angefangen, erster Versuch gearbeitet.
Kyles
Dies ist die beste Antwort in diesem Thread. Nicht teilen und bearbeiten. Einfach bearbeiten.
Dr_Zaszuś
In meinem Fall kam ein zusätzliches Problem von Windows-Zeilenenden, die wie ^Min der Diff-Datei angezeigt wurden . Nachdem ich die Datei mit CR-Endungen gespeichert hatte, wurde der interaktive Bearbeitungs-Patch ausgeführt!
Dr_Zaszuś
Danke, das hat den Trick für mich getan. Ich musste an einem riesigen Stück arbeiten, also teilte ich es auf und alles brach zusammen. Wenn Sie es nicht teilen, funktioniert alles einwandfrei.
Matthias Fischer
16

Wenn Sie eine zum Löschen bereitgestellte Zeile nicht löschen möchten, wie in

 first line
-second line
 third line

Wenn Sie die zweite Zeile behalten möchten, stellen Sie sicher, dass Sie die -durch ein Leerzeichen ersetzen , anstatt die gesamte Zeile zu löschen (als würden Sie eine hinzugefügte Zeile entfernen). Git wird die Zeile als Kontext verwenden.

Rose Perrone
quelle
1
Das war mir nicht klar, ich dachte, Git sagte mir, ich solle die Zeile zu einem einzigen Leerzeichen machen.
JackHasaKeyboard
14

Es ist wichtig, auch den Hunk-Header korrekt zu ändern (z @@ -1,6 +1,9 @@. B. ). Joaquin Windmuller enthüllt in einem seiner Blog- Beiträge das Geheimnis der Bearbeitung von Hunk-Headern .

Die Geheimnisse der Bearbeitung von Hunks

Das Bearbeiten der Hunks kann zunächst verwirrend sein. Die Anweisungen, die Git Ihnen gibt, reichen jedoch nicht aus, um loszulegen.

# —||

# 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.

Die geheime Sauce ist… Linien zählen:

  • Wenn Sie eine Zeile entfernen, die mit + beginnt, subtrahieren Sie eine von der neuen Zeilenanzahl (letzte Ziffer der Kopfzeile des Hunks) .
  • Wenn Sie eine Zeile entfernen, die mit beginnt, fügen Sie eine zur neuen Zeilenanzahl hinzu (letzte Ziffer der Kopfzeile des Hunk). .
  • Entfernen Sie nicht die anderen Linien (Referenzlinien).

Auf diese Weise können Sie die Hunks schnell ändern, um die gewünschten Teile auszuwählen.

Ortomala Lokni
quelle
1
Gibt es eine Möglichkeit, die Bearbeitung des Hunk-Headers zu automatisieren oder git so zu konfigurieren, dass die entsprechenden Zeilenzahlen ermittelt werden?
Dennis
Sie können wahrscheinlich Ihren Lieblingseditor skripten, um dies zu automatisieren. Vielleicht gibt es dafür bereits einige Plugins, die jedoch vom Editor abhängig sind.
Ortomala Lokni
13

Ich habe kürzlich durch Lesen dieses Threads herausgefunden, wie man die manuelle Bearbeitung durchführt.

Der Trick, den ich benutzte, war, wenn ich einen Unterschied habe wie:

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

Der Trick besteht darin, die beiden Linien, die ich nicht möchte, vollständig zu entfernen, sodass der resultierende Unterschied wie folgt aussieht:

+ Line to add
+ Line to add

Während dies für die meisten Menschen höchstwahrscheinlich offensichtlich ist, war es bis heute nicht für mich und ich dachte, ich sollte nur meine Erfahrungen teilen. Bitte sagen Sie mir, ob für diese Methode eine Gefahr besteht.

Sedrik
quelle
2
Ich kann dir nicht genug danken! Ich habe mindestens eine Stunde lang versucht, das +in ein ' 'zu verwandeln.
Soumer
Weißt du, Verrücktheit macht dasselbe und erwartet ein anderes Ergebnis. Ich habe mir das 20 Minuten lang gesagt, bevor ich herausgefunden habe, dass ich nur löschen muss :)
solidak
7

Sie können die Zeilennummern manuell bearbeiten, was in einigen Fällen auf jeden Fall nützlich ist. Sie hätten dieses spezielle Problem jedoch wahrscheinlich vermeiden können, indem Sie das Stück NICHT zuerst aufgeteilt hätten.

Wenn Sie sehen, dass Sie wahrscheinlich etwas später in dem von Git automatisch ausgewählten Teil bearbeiten müssen, ist es am besten, nur den gesamten Teil zu bearbeiten, anstatt ihn zu teilen, die Hälfte zu inszenieren und dann die andere Hälfte zu bearbeiten. Git wird es besser machen, das herauszufinden.

Michael Hines
quelle
6

Ich kam zu dieser Frage und suchte nach einer Lösung für dasselbe Problem. Ich konnte nicht herausfinden, wie ich die Zeilennummern (wie oben vorgeschlagen) im Hunk ändern sollte, damit Git sie in meinem Fall akzeptiert. Ich habe jedoch einen viel besseren Weg gefunden, dies zu tun git gui. Dort können Sie die Linien im Diff auswählen, die Sie inszenieren möchten, dann mit der rechten Maustaste klicken und "Linien aus Commit inszenieren" auswählen. Ich erinnere mich, dass Git-Cola auch die gleiche Funktionalität hat.

Jayesh
quelle
Das sollte wirklich die Antwort sein. git-colascheint unter Linux, Windows und MacOS zu funktionieren.
leeand00
5

Ein zusätzliches Problem, das ich hatte, als ich diesen Fehler bekam, war, dass sich die Zeilenenden änderten, als ich die Bearbeitungsdatei speicherte.

Ich habe Windows und Notepad für meine Änderungen verwendet (speichert nur mit Windows-Zeilenenden). Mein Code wurde mit Notepad ++ geschrieben und ich habe ihn so eingerichtet, dass er Zeilenenden im Unix / Linux-Stil hat.

Als ich meine Einstellungen so änderte, dass Notepad ++ als Standard-Git-Editor verwendet wurde, konnte ich meine Änderungen am Hunk vornehmen.

git config --global core.editor "notepad++"
KLee1
quelle
1
Das hat bei mir funktioniert. Aber ich brauchte den vollständigen Pfad zu Notepad ++ und es dauerte eine Weile, bis alles richtig war: git config --global core.editor '"C:/Program\ Files\ \(x86\)/Notepad++/notepad++.exe"' (Passen Sie dies an die Stelle an, an der Notepad ++ auf Ihrem PC installiert ist)
Annabel
1
Genau das gleiche Problem für mich. Es war Notepad, der Probleme verursachte. Nachdem ich meinen Standardeditor auf Notepad ++ umgestellt hatte, fing alles wieder an zu funktionieren.
Johnny Oshika
4

Ein Grund für die seltsamen Meldungen "Ihr bearbeiteter Hunk wird nicht angewendet" (wahrscheinlich begleitet von etwas wie "Fehler: Patchfragment ohne Header in Zeile ...") könnte Ihr Editor sein, wenn er so konfiguriert ist, dass nachgestellte Leerzeichen entfernt werden. Dies würde offensichtlich große Probleme verursachen, da Patches leere Zeilen als Zeilen mit einem Leerzeichen codieren. Jeder Teil, der leere Zeilen enthält, würde nicht angewendet, wenn er mit einem solchen Editor gespeichert würde. Tatsächlich würde ein Teil, der unveränderte Leerzeilen enthält, nach der Bearbeitung nicht angewendet, wenn das Entfernen von nachgestellten Leerzeichen aktiviert ist.

Timo
quelle
0

Zu Ihrer Information, ich habe einen leicht zusammenhängenden Fehler erhalten ... als ich Patches gemäß der oben vorgeschlagenen Anweisung hinzufügte ... Es wurde jedoch kein Fehler angezeigt. Ich wurde wiederholt gebeten, das gleiche Stück zu inszenieren ... Ich bemerkte, dass ich eine ältere Version von Vim 7.4 ausführte ... Ich habe vim aktualisiert und es funktioniert jetzt wie erwartet. Hoffentlich hilft das jemandem ..

Mantisimo
quelle