git add --interactive „Twój edytowany fragment nie ma zastosowania”

85

Próbuję użyć git add --interactivewybiórczo dodać pewne zmiany do mojego indeksu, ale ciągle otrzymuję komunikat „Twój edytowany fragment nie ma zastosowania. Edytuj ponownie ...”. Otrzymuję tę wiadomość, nawet jeśli wybiorę opcję e i natychmiast zapiszę / zamknę mój edytor. Innymi słowy, bez jakiejkolwiek edycji kawałka łatka nie ma zastosowania.

Oto dokładny przykład, którego używam (próbuję stworzyć małe demo):

Oryginalny plik:

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

Nowy plik:

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

Próbuję pokazać, jak używać git add --interactivetylko do dodania wiersza „poprawka błędu 1” do indeksu. Uruchamiając interaktywny dodatek na pliku, wybieram tryb łatki. Przedstawia mi to

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

Odpowiadam rozdzieleniem, po którym następuje „nie”, aby zastosować pierwszy fragment. Drugi kawałek, próbuję edytować. Początkowo próbowałem usunąć dolną linię - to nie zadziałało. Całkowite pozostawienie przystojniaka w spokoju też nie działa i nie mogę zrozumieć, dlaczego.

Josh
źródło
Dobrze jest się tutaj upewnić, że nie dodajesz -znaków na początku linii, których nie ma w pliku; jest to różnica i nie może usunąć linii, których jeszcze tam nie ma. Więc jeśli wiersz w pliku różnicowym zaczyna się od +i zmienisz go na -git, przechodzi do WTF? ponieważ teraz linia oznaczona do usunięcia nie istnieje na początku (zamiast tego ta linia została oznaczona do dodania, a kiedy linia zaznaczona do dodania jest oznaczona do usunięcia, git nie może usunąć linii, której nie ma jeszcze w pliku) .
leeand00
1
Sprawdź także zakończenia linii (LF, CRLF) w moim przypadku nie dotyczyło to jednego LF zamiast CRLF!
Alberto Rivelli

Odpowiedzi:

37

W tym konkretnym przykładzie musisz dostosować numery wierszy w porcji. Zmień linię:

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

więc zamiast tego brzmi:

@@ -2,7 +2,8 @@
William Pursell
źródło
16
Po pewnym czasie odkryłem, że te wiersze pokazują „zakres z pliku” i „zakres do pliku”. Naprawdę nie rozumiem logiki stojącej za zmianą 1 na 2. Wypróbowałem to i działa, ale nie rozumiem, dlaczego zmienia się „zakres z pliku”. Oryginalny plik jest taki sam, niezależnie od tego, czy stosuję całą poprawkę, czy tylko edytowaną część. Czy możesz wyjaśnić więcej lub wskazać mi źródło informacji o ujednoliconym formacie różnic. Nie udało mi się go znaleźć.
Josh
9
@Josh: stackoverflow.com/questions/2529441/ ... może pomóc, nawet jeśli nie dostanę całkowicie porcji ujednoliconego formatu. @William +1
VonC
5
@Josh: Patrząc na to, wygląda na to, że może to być błąd. Po edycji porcji git próbuje zweryfikować poprawkę, sprawdzając, czy wszystkie porcje zostaną zastosowane (może to być przesada). Niestety, w tym przypadku oznacza to, że poprzedni fragment (którego nie stosujesz) jest sprawdzany i zachodzi pewne nakładanie się, co powoduje, że git Apply --check kończy się niepowodzeniem. Nie znam eleganckiego rozwiązania; git może postępować właściwie, zachowując nadmierną ostrożność.
William Pursell,
22
Więcej informacji na temat zmiany numerów linii? Dlaczego musimy to robić? I jak? Co oznacza każda liczba?
Bill
4
@WilliamPursell Jakie wersje gita? Przerzuciłem się na nowy komputer i uruchomiłem git v2.17.0 i nagle moje zmiany w poprawkach nie są już poprawne.
Dennis
104

Czy to jest jak w tym poście git-add ?

Ręczna edycja kawałka jest niesamowicie potężna, ale także nieco skomplikowana, jeśli nigdy wcześniej tego nie robiłeś.
Najważniejsza rzecz, o której należy pamiętać: różnica jest zawsze wcięta za pomocą jednego znaku oprócz wszelkich innych wcięć.
Postać może być:

  • spacja (oznacza niezmienioną linię),
  • a -wskazujące, że linia została usunięta,
  • lub a +wskazujące, że linia została dodana.

Nic więcej. Musi to być spacja, - lub +. Cokolwiek innego, a otrzymasz błędy
(nie ma znaku dla zmienionej linii, ponieważ są one obsługiwane przez usunięcie starej linii i dodanie zmienionej linii jako nowej).

Ponieważ masz różnicę otwartą w swoim ulubionym edytorze tekstu (skonfigurowałeś Gita tak, aby używał twojego ulubionego edytora tekstu, prawda?), Możesz robić, co chcesz - o ile upewnisz się, że wynikowe różnice są stosowane poprawnie.

I na tym polega sztuczka. Jeśli nigdy wcześniej tego nie robiłeś, Git wyświetli komunikat „Twój edytowany fragment nie ma zastosowania. Czy edytować ponownie?” tak często zaczniesz nienawidzić siebie za niezdolność do zrozumienia tego , nawet jeśli wydaje się to takie łatwe (lub Git, ponieważ nie może zrozumieć, czego chcesz).

Jedną rzeczą, która dość często mnie denerwowała, było to, że zapomniałem wcięcia jednego znaku.
Zaznaczyłbym wiersz znakiem - do usunięcia, ale w większości edytorów tekstu, który wstawia a -, nie zastępuje miejsca, które było wcześniej. Oznacza to, że dodajesz dodatkową spację do całej linii, co z kolei oznacza, że ​​algorytm porównywania nie może znaleźć / dopasować linii w oryginalnym pliku, co z kolei oznacza, że ​​Git będzie na ciebie krzyczał .

Inną rzeczą jest to, że różnica wciąż musi mieć sens. „Sense” oznacza, że ​​można go nakładać czysto. Dokładnie to, jak tworzysz rozsądną różnicę, wydaje się trochę mroczną grafiką (przynajmniej dla mnie w tej chwili), ale zawsze powinieneś pamiętać, jak wyglądał oryginalny plik, a następnie odpowiednio zaplanować swoje-i +. Jeśli będziesz edytować swoje porcje wystarczająco często, w końcu to zrozumiesz.

Zobacz także to zatwierdzenie na git add -p .

Ortomala Lokni „s odpowiedź odnosi się do Joaquín Windmuller blogu« Selektywnie wybranych zmian popełnić z git (lub Imma Edycja przystojniak) »

Zamiast liczyć linie, Git chciałby połączyć nakładające się porcje (gdy jedna jest edytowana) przed zastosowaniem wspomnianej edytowanej porcji.
Zostało to omówione w połowie 2018 roku i pozwoliłoby uniknąć scenariusza takiego:

jeśli podzielisz porcję, edytujesz pierwszą część podrzędną, przekształcając końcową linię kontekstu w usunięcie, a jeśli spróbujesz wystawić drugi fragment, zakończy się niepowodzeniem.

VonC
źródło
5
Dzięki za link, ale już to widziałem. Nie dodawałem / nie opuszczałem dodatkowej linii. Problem dotyczył numerów linii, ale nadal nie rozumiem poprawki.
Josh
9
Nie zastępowałem usuniętego „-” spacją - w ten sposób zepsułem wcięcie. Dzięki!!
pedorro
Tylko upewnij się, że nie zrozumiesz źle części z pustą przestrzenią. Pomyślałem, że wszystkie niezmienione linie powinny być po prostu linią z czarnym - zamiast zwykłym wcięciem ... Gdyby godzina "edytowanego kawałka nie ma zastosowania", dopóki nie zrozumiałem dlaczego: - /
oligofren
@oligofren Nie jestem pewien, czy cię rozumiem: co musiałeś zrobić, aby Twój edytowany kawałek został zastosowany?
VonC,
1
@VonC: Najpierw pomyślałem, że powinienem zmienić - foo na `` (tylko spacja, a nie "spacja i cała linia"). Zajęło mi trochę czasu, zanim zrozumiałem, że powinno to być „foo”.
oligofren
48

Oczywiście spóźniłem się na to, ale mimo wszystko chciałem wspomnieć dla porządku, że ten problem był omawiany w zeszłym roku na liście mailingowej git i wygląda na to, że od tego czasu niewiele się zmieniło.

Ten konkretny problem wynika z dzielenia i próby edycji tego samego kawałka. Analiza podstawowego problemu, jak pierwotnie opublikował Jeff King, jest zasadniczo taka:

Hm. Dobra, widzę. Sprawdzanie "czy this diff apply" podaje obie części podzielonej łaty do git-apply. Ale oczywiście druga część nigdy nie zostanie poprawnie zastosowana, ponieważ jej kontekst nakłada się na pierwszą część, ale nie bierze go pod uwagę.

Sprawdzenie tylko ze zmodyfikowaną poprawką zadziałałoby. Ale to nie bierze pod uwagę, że edytowana łatka może nie zostać zastosowana na dłuższą metę, w zależności od tego, czy akceptujesz drugą połowę podzielonej łatki. I nie możemy tego jeszcze wiedzieć, ponieważ użytkownik mógł nam tego nie powiedzieć (mógł pominąć pierwszą połowę, a potem wrócić do niej później po etapie edycji).

Jeff kończy swój post bardzo pragmatycznym obejściem, które zawsze się udaje i dlatego jest wysoce zalecane:

Ogólnie uważam, że dzielenie i edytowanie tego samego kawałka jest z natury niebezpieczne i doprowadzi do tego rodzaju problemów. A ponieważ edycja zapewnia nadzbiór funkcji, myślę, że powinieneś po prostu edytować i pozwolić na zastosowanie pierwszej części porcji lub nie, w zależności od twoich preferencji.

Decydując się tylko na edycję porcji, która nie została wcześniej podzielona, ​​nie będziesz musiał zajmować się numerami linii.

Niels Ganser
źródło
6
Dzięki, jest to rzeczywiście o wiele łatwiejsze niż majstrowanie przy numerach linii.
michiakig
3
To był mój problem. Potrzebowałem, żeby mój przystojniak był mniejszy. Dokonano podziału w trybie interaktywnym. Podział nie był tym, czego chciałem, więc postanowiłem spróbować edytować go ręcznie. Ciągle otrzymuję błąd. Zacząłem od nowa, pracowałem jako pierwsza próba.
Kyle ma
To najlepsza odpowiedź w tym wątku. Nie dziel i nie edytuj. Po prostu edytuj.
Dr_Zaszuś
W moim przypadku dodatkowy problem wynikał z końcówek linii Windows pokazanych ^Mw pliku diff. Po zapisaniu pliku z zakończeniami CR, interaktywna łatka edycji przeszła!
Dr_Zaszuś
Dzięki, to załatwiło sprawę. Musiałem popracować nad dużym kawałkiem, więc go podzieliłem i wszystko się zepsuło. Utrzymanie tego bez podziału sprawiło, że wszystko działało dobrze.
Matthias Fischer
16

Jeśli nie chcesz usuwać linii, która została przygotowana do usunięcia, jak w

 first line
-second line
 third line

gdzie chcesz zachować drugą linię, upewnij się, że zastąpiłeś -spacją, zamiast usuwać całą linię (tak jakbyś pozbył się dodanej linii). Git użyje linii jako kontekstu.

Rose Perrone
źródło
1
Nie było to dla mnie jasne, pomyślałem, że Git każe mi zrobić linię pojedynczą spacją.
JackHasaKeyboard
15

Ważne jest również, aby poprawnie zmodyfikować nagłówek porcji (np @@ -1,6 +1,9 @@.). Joaquin Windmuller ujawnia sekret edycji nagłówka przystojniaka w jednym ze swoich postów na blogu .

Sekrety edycji kawałków

Edytowanie porcji może być początkowo mylące, instrukcje, które daje git, ale nie są wystarczające, aby rozpocząć.

# —||

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

Sekretem jest… liczenie wierszy:

  • Jeśli usuniesz linię zaczynającą się od +, odejmij jeden od nowej liczby linii (ostatnia cyfra nagłówka porcji) .
  • Jeśli usuniesz linię zaczynającą się od - dodaj ją do nowej liczby linii (ostatnia cyfra nagłówka porcji) .
  • Nie usuwaj innych linii (linii odniesienia).

Powinno to umożliwić szybką modyfikację porcji, aby wybrać żądane części.

Ortomala Lokni
źródło
1
Czy istnieje sposób na zautomatyzowanie edycji nagłówka porcji lub skonfigurowanie gita, aby określić odpowiednią liczbę wierszy?
Dennis
Prawdopodobnie możesz napisać skrypt swojego ulubionego edytora, aby to zautomatyzować. Może jest już do tego kilka wtyczek, ale to zależy od edytora.
Ortomala Lokni
13

Niedawno po przeczytaniu tego wątku dowiedziałem się, jak przeprowadzić ręczną edycję.

Sztuczka, której użyłem, polegała na tym, że jeśli mam różnicę, taką jak:

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

Sztuczka polega na tym, aby całkowicie usunąć dwie linie, których nie chcę, tak aby wynikowa różnica wyglądała następująco:

+ Line to add
+ Line to add

Chociaż jest to najprawdopodobniej oczywiste dla większości ludzi, dopiero teraz byłem dla mnie i pomyślałem, że powinienem podzielić się swoim doświadczeniem. Proszę, powiedz mi, czy ta metoda stwarza jakiekolwiek zagrożenie.

Sedrik
źródło
2
Nie mogę ci wystarczająco podziękować! Próbowałem zmienić +na a ' 'przez co najmniej godzinę.
soumer
Wiesz, szaleństwo to robienie tego samego i oczekiwanie innego wyniku. Mówiłem to sobie przez 20 minut, zanim zorientowałem się, że muszę tylko skasować :)
solidak
7

Możesz ręcznie edytować numery linii, co jest zdecydowanie przydatne w niektórych przypadkach. Jednak prawdopodobnie mógłbyś uniknąć tego konkretnego problemu, NIE dzieląc najpierw kawałka.

Jeśli zauważysz, że prawdopodobnie będziesz musiał edytować coś później w kawałku, który automatycznie wybrał Git, najlepiej po prostu edytować cały fragment, zamiast dzielić, umieszczać połowę, a następnie edytować drugą połowę. Git lepiej sobie z tym poradzi.

Michael Hines
źródło
6

Doszedłem do tego pytania, szukając rozwiązania tego samego problemu, i nie mogłem wymyślić, jak zmienić numery linii (jak zasugerowano powyżej) w kawałku, aby git zaakceptował to w moim przypadku. Znalazłem jednak znacznie lepszy sposób, aby to zrobić, używając git gui. Tam możesz zaznaczyć linie w pliku różnicowym, które chcesz umieścić na scenie, a następnie kliknąć prawym przyciskiem myszy i wybrać opcję „Utwórz linie z zatwierdzenia”. Pamiętam, że git-cola też ma taką samą funkcjonalność.

Jayesh
źródło
To naprawdę powinna być odpowiedź. git-colawydaje się działać w systemach Linux, Windows i MacOS.
leeand00
5

Dodatkowym problemem, który miałem, gdy otrzymałem ten błąd, było to, że zakończenia linii zmieniły się, gdy zapisałem plik edycji.

Używałem systemu Windows i Notatnika do edycji (zapisuje tylko z zakończeniami linii Windows). Mój kod został napisany za pomocą Notepad ++ i skonfigurowałem go tak, aby miał zakończenia linii w stylu Unix / Linux.

Kiedy zmieniłem ustawienia, aby mieć Notepad ++ jako domyślny edytor git, mogłem wprowadzać zmiany w kawałku.

git config --global core.editor "notepad++"
KLee1
źródło
1
To zadziałało dla mnie. Ale potrzebowałem pełnej ścieżki do notatnika ++ i zajęło to trochę czasu, zanim wszystko się poprawiło: git config --global core.editor '"C:/Program\ Files\ \(x86\)/Notepad++/notepad++.exe"' (dostosuj to w zależności od tego, gdzie na twoim komputerze jest zainstalowany program notepad ++)
Annabel
1
Dokładnie ten sam problem dla mnie. To Notatnik powodował problemy. Po przełączeniu domyślnego edytora na Notepad ++ wszystko zaczęło działać ponownie.
Johnny Oshika
4

Jednym z powodów dziwnych komunikatów „Twój edytowany fragment nie ma zastosowania” (prawdopodobnie towarzyszy mu coś w rodzaju „błąd: fragment poprawki bez nagłówka w wierszu ...”) może być Twój edytor, jeśli jest skonfigurowany do usuwania końcowych białych znaków. Spowodowałoby to oczywiście poważne problemy, ponieważ łaty kodują puste wiersze jako wiersze z jedną spacją, którykolwiek fragment zawierający puste wiersze nie zostałby zastosowany, gdyby został zapisany za pomocą takiego edytora. W efekcie każdy fragment zawierający niezmienione puste wiersze nie zostanie zastosowany po edycji za pomocą, jeśli jest włączone usuwanie końcowych białych znaków.

Timo
źródło
0

FYI, otrzymywałem lekko powiązany błąd ... kiedy dodałem załatany zgodnie z sugerowaną instrukcją powyżej ... Jednak nie pokazywał żadnego błędu. Otrzymywałem to wielokrotnie, prosząc mnie o przygotowanie tego samego kawałka ... Zauważyłem, że korzystam ze starszej wersji Vima 7.4 ... Zaktualizowałem Vima i teraz działa zgodnie z oczekiwaniami. Mam nadzieję, że to komuś pomoże ...

Mantisimo
źródło