Jak zmienić poprzednie zatwierdzenie, aby uwzględnić pominięty plik?


98

Popełniłem zmianę i zapomniałem dodać plik do zbioru zmian. Po innych zatwierdzeniach zdałem sobie sprawę, że brakuje pliku w HEAD^4zatwierdzeniu.

Jak przepisać poprzednie zatwierdzenie, aby uwzględnić brakujący plik?


czy nacisnąłeś te 4 zatwierdzenia?
— mvp

@mvp nie, są one tylko w moim lokalnym repozytorium git.
— kolrie

Odpowiedzi:


54

Użyj git rebase --interactive HEAD~4i ustaw editopcję dla zatwierdzenia, które chcesz zmienić.

Pamiętaj, że nie powinieneś w ten sposób modyfikować zatwierdzeń wysyłanych do zdalnego repozytorium. W takim przypadku lepiej jest dodać nowe zatwierdzenie z brakującym plikiem.


Dzięki. Czy tak jest, nawet jeśli jestem jedynym użytkownikiem zdalnego repozytorium? Czy nie pozwoliłoby mi to zrobić, git push -fgdybym był pewien, że upstream się nie zmienił?
— kolrie

1
Jeśli jesteś jedynym użytkownikiem zdalnego repozytorium, możesz wykonać wymuszone wypychanie.
— Rafał Rawicki

7
Myślę, że te instrukcje nie są wystarczająco szczegółowe. Próbując go po raz pierwszy usłyszałem komunikat „Nie można zmienić bazy danych: Twój indeks zawiera niezatwierdzone zmiany”. Ja już add-ED brakujące pliki, więc zrobiłem commit z „xxx” jako wiadomości. Następnie wykonałem polecenie rebase i zmieniłem zatwierdzenie „xxx” z „wybierz” na „edytuj”. Następnie wykonałem polecenie „git rebase --continue”. Teraz, kiedy patrzę na historię, mam „xxx” jako ostatnie zatwierdzenie, a wcześniejsze zatwierdzenie, do którego chciałem je dodać, pozostaje niezmienione! Zastanawiam się, gdzie był mój błąd?
— Darren Cook

2
Zgniatanie ostatniego zatwierdzenia nie spowoduje umieszczenia pliku w HEAD ~ 4.
— Justin

1
git add editedFiles; git commit -m "Bla"; git rebase -i HEAD ~ 5; // tak jak teraz dodano nowe zatwierdzenie, więc musieliśmy zmienić bazę z 5 zamiast 4. teraz przenieś zatwierdzenie "Blah" do drugiej linii i zmień je z "Pick" na "s" (squash), co zmiażdży zatwierdzenie za pomocą HEAD ~ 5, ponieważ polecenia są wykonywane od góry do dołu
— zstring

274

Zdaję sobie sprawę, że ludzie mogą wyszukiwać w wyszukiwarce Google i przychodzić tutaj, aby znaleźć prostszą odpowiedź: a co, jeśli to tylko ostatnie zatwierdzenie? (Pytanie OP dotyczy naprawienia czwartego zatwierdzenia w historii)

Jeśli zdecydujesz się zatwierdzić i zdasz sobie sprawę, że zapomniałeś od razu dodać plik , po prostu wykonaj:

# edited file-that-i-remember.txt
git add file-that-i-remember.txt
git commit

# realize you forgot a file
git add file-that-i-forgot.txt
git commit --amend --no-edit

Gdzie --no-editzachowa ten sam komunikat o zatwierdzeniu.

Bułka z masłem!


21
To jest odpowiedź.
— Adam Bittlingmayer

5
Warto wspomnieć, jeśli zatwierdzenia nie są przesyłane do pilota.
— Ram Patra

1
Tak, warto tu wspomnieć w komentarzach: Służy do użycia przed push . Dzięki za wskazanie tego.
— Dr Beco

2
Jedna uwaga jest taka, że ​​zatwierdzenia przed i po --amendmają różne skróty
— sonlexqt

6
Dzięki, ale to niemożliwe: poprosił OP HEAD^4. Tak jest w porządku, tylko jako dodatek w celach informacyjnych. ;)
— Dr Beco

11

Jeśli NIE wypchnąłeś tych 4 zatwierdzeń, możesz to zrobić w następujący sposób:

Utwórz pliki łatek dla wszystkich tych zatwierdzeń:

git format-patch -4

Przewiń wstecz o 4 zatwierdzenia:

git reset --hard HEAD~4

Dodaj brakujący plik:

git add missing-file

Zatwierdź to za pomocą --amend:

git commit --amend

Zastosuj wszystkie zapisane poprawki z powrotem:

git am *.patch

Jeśli nacisnąłeś, NIE powinieneś używać tej metody. Zamiast tego po prostu przyznaj się do pomyłki i utwórz jeszcze jedno zatwierdzenie na szczycie HEAD, które rozwiązuje ten problem.


Jeśli chcesz zrobić to krok po kroku, łatwiej jest wybrać najlepsze zmiany po zmodyfikowanym, niż wyeksportować je jako łatkę.
— Rafał Rawicki

1
To kwestia gustu. Lubię git format-patch/ git amznacznie lepiej. Co najważniejsze, daje ci to większą pewność, jeśli coś schrzanisz - zatwierdzenie zapisane jako łatka w fizycznym pliku jest najlepszą siecią bezpieczeństwa.
— mvp,

Prawdziwe zaufanie polega na tym, że działając na repozytorium git nigdy niczego nie usuwasz. Stare commity są dostępne do startu git gc:)
— Rafał Rawicki

To jest trywialne i oczywiste dla ciebie i dla mnie. Ale dla użytkownika, który dopiero zaczyna i prawdopodobnie nie rozumie nic o git - ten fakt wcale nie jest oczywisty.
— mvp

2
Te instrukcje wydawały się rozwlekłe, ale były dość proste i łatwe do wykonania. Dzięki. (Chciałbym tylko dodać końcowy etap: rm *.patch)
— Darren Cook

9

Chociaż zaakceptowana odpowiedź jest poprawna, brakuje w niej szczegółowych instrukcji, jak przeprowadzić edycję zatwierdzenia podczas procesu rebase.

  • Najpierw rozpocznij proces rebase:

    git rebase --interactive HEAD~4
    
  • Zostanie wyświetlona lista zatwierdzeń, wybierz zatwierdzenie, które chcesz edytować, zmieniając słowo pickna editi zapisz plik.

  • Wprowadź niezbędne modyfikacje w swoim kodzie (pamiętaj, aby wywołać git addnowe pliki)

  • Po wykonaniu wszystkich modyfikacji wydaj git commit --amend- to zmieni zatwierdzenie oznaczone jakoedit

  • Wywołanie git rebase --continue, które zakończy proces (jeśli jest więcej zatwierdzeń oznaczonych jako edit, powyższe kroki należy powtórzyć)

Ważne notatki:

  • NIE usuwaj linii oznaczonych jako pick, których nie chcesz edytować - pozostaw je bez zmian. Usunięcie tych wierszy spowoduje usunięcie powiązanych zatwierdzeń

  • GIT zmusza cię do zmiany stashbazy, jeśli twój katalog roboczy nie jest czysty; możesz jednak git stash pop / git stash applypodczas rebase, aby zmienić te zmiany (tj. zmiany schowane przed rozpoczęciem procesu rebase) do zatwierdzenia oznaczonego jakoedit

  • jeśli coś poszło nie tak i chcesz cofnąć zmiany dokonane podczas procesu rebase przed jego zakończeniem (tj. chcesz powrócić do punktu przed rozpoczęciem rebase), użyj git rebase --abort- przeczytaj również: Jak przerwać interaktywną rebase, jeśli --abort nie robi t działa?

  • Jak powiedziano w zaakceptowanej odpowiedzi:

    Pamiętaj, że nie powinieneś w ten sposób modyfikować zatwierdzeń przesyłanych do zdalnego repozytorium. W takim przypadku lepiej jest dodać nowe zatwierdzenie z brakującym plikiem.

    Odpowiedź dlaczego znajduje się w Git Book (akapit zatytułowany „ The Perils of Rebasing ”):

    Nie zmieniaj bazy zatwierdzeń, które istnieją poza repozytorium.

    Jeśli zastosujesz się do tej wskazówki, wszystko będzie dobrze. Jeśli tego nie zrobisz, ludzie będą cię nienawidzić, a przyjaciele i rodzina będą cię gardzić.

    Kiedy zmieniasz bazę, porzucasz istniejące zatwierdzenia i tworzysz nowe, które są podobne, ale różne. Jeśli gdzieś popchniesz zatwierdzenia, a inni ściągną je i oprze na nich pracę, a następnie przepiszesz te zatwierdzenia za pomocą git rebase i ponownie je popchniesz, Twoi współpracownicy będą musieli ponownie scalić swoją pracę, a gdy spróbujesz, wszystko się pogmatwa wciągnij ich pracę z powrotem do swojej.

    […]

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.