Przywracanie określonych commitów z Gita

Mam drzewo Gita z wieloma commitami i wieloma plikami. Teraz chcę przywrócić określone commity, które dotykają tylko Pliku. Wyjaśnić:

> git init
Initialized empty Git repository in /home/psankar/specific/.git/
> echo "File a" > a
> git add a ; git commit -m "File a"
[master (root-commit) 5267c21] File a
 1 file changed, 1 insertion(+)
 create mode 100644 a
> echo "File b" > b
> git add b; git commit -m "File b"
[master 7b560ae] File b
 1 file changed, 1 insertion(+)
 create mode 100644 b
> echo "File c" > c
> git add c; git commit -m "File c"
[master fd6c132] File c
 1 file changed, 1 insertion(+)
 create mode 100644 c
> echo "b and c modified" > b ; cp b c
> git commit -a -m "b and c modified"
[master 1d8b062] b and c modified
 2 files changed, 2 insertions(+), 2 deletions(-)
> echo "a modified" > a
> git commit -a -m "a modified"
[master 5b7e0cd] a modified
 1 file changed, 1 insertion(+), 1 deletion(-)
> echo "c modified" > c
> git commit -a -m "c modified"
[master b49eb8e] c modified
 1 file changed, 1 insertion(+), 1 deletion(-)
> git log --pretty=oneline c
> git log --pretty=oneline c | cat
b49eb8e03af331bddf90342af7d076f831282bc9 c modified
1d8b062748f23d5b75a77f120930af6610b8ff98 b and c modified
fd6c13282ae887598d39bcd894c050878c53ccf1 File c

Teraz chcę przywrócić tylko dwa commity b49eb8 i 1d8b06 bez odwracania zmian do a. IOW odwraca tylko commity w pliku (bez odwracania innych pośrednich commitów (których liczba może być tysiące) w różnych plikach) jak to jest możliwe ?

Author: wjandrea, 2013-12-02

2 answers

Możesz użyć git revert z opcją --no-commit. W twoim przykładzie:

$ git revert --no-commit b49eb8e 1d8b062
# Files that were modified in those 2 commits will be changed in your working directory
# If any of those 2 commits had changed 'a' then you could discard the revert for it:
$ git checkout a
$ git commit -a -m "Revert commits b49eb8e and 1d8b062"

Jeśli nie podasz Komunikatu o zatwierdzeniu, przygotowana wiadomość będzie dostępna po uruchomieniu edytora zatwierdzania.

Jeśli omamisz opcję --no-commit, zmiany w commitach zostaną przywrócone. Osiąga się to poprzez zastosowanie odwrotnej zmiany w podanych commitach i zatwierdzanie tego. Skutkuje to Nowym commitem, zarówno oryginalny jak i Cofnięty commit będzie w historia twojego repozytorium.

 72
Author: mamapitufo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-02 09:57:24

Są tu dwa przypadki:

  1. Kiedy już przesunąłeś gdzieś swoje drzewo Gita i nie chcesz zmieniać historii. W takim przypadku będziesz potrzebował nowego commita wyrażającego zmiany wprowadzone podczas cofania poprzednich commitów. Powinieneś użyć odpowiedzi @mamapitufo.

  2. Jeśli nigdy nie pchnął gałąź, że zmiany są na, i można zmienić historię. W takim przypadku możesz całkowicie usunąć niechciane commity. To będzie neaten historia i oznacza, że nie naciskasz złego zwrotu do współpracowników lub społeczeństwa.

W drugim przypadku należy zrobić git rebase -i. Znajdź commit, który pojawia się przed którąkolwiek z historii, którą chcesz zmienić. Może to być hash commita lub nazwa gałęzi lub znacznika. Na przykład, można zrobić

git rebase -i 23def8231

Lub jeśli zacząłeś od gałęzi origin/dev_branch i wykonałeś pracę, która zawiera bity do usunięcia na Twojej gałęzi o nazwie dev_branch, możesz wykonać

git rebase -i origin/dev_branch

Teraz, zostaniesz wysłany do okna edytora, gdzie zobaczysz listę wszystkich zmian, które zmieniasz. Może to być vim - jeśli zwykle nie edytujesz w terminalu, może to być ustawione jako domyślne. Prawdopodobnie będziesz potrzebował szybkiego przewodnika po Vimie i otwartego umysłu, jeśli tak jest.

Teraz najłatwiej jest usunąć commity. Można to zrobić, usuwając wiersz lub dodając #, który wskazuje komentarz na początek wiersza. (Są już pewne komentarze w / align = "left" / Ignorowanie tych lub usuwanie ich nie ma wpływu.)

Po zakończeniu zapisz plik i zamknij Edytor. Rebase dzieje się tak: git wraca do commita, którego nazwałeś. Przechodzi przez listę, którą zapisałeś i powtarza każdy commit z tej listy. Wtedy to sprawia, że wynikiem tego procesu jest nowa wersja gałęzi, na której pierwotnie się znajdowałeś.

Ważne rzeczy do zapamiętania:

  • Jeśli zgubisz lub usuniesz zbyt wiele linii, możesz anuluj rebase, usuwając każdą linię zatwierdzania w pliku i zapisując. Proces rebase zakończy się bez zmian.
  • możliwe jest tworzenie konfliktów. Na przykład, jeśli usuniesz commit, który edytuje plik, i zostawisz go w późniejszym commicie, który edytuje to samo miejsce. Późniejszy commit nie będzie teraz stosowany poprawnie i będziesz musiał edytować ręcznie lub w narzędziu scalania, aby uzyskać żądaną wersję.

Możesz również wykonać wiele innych manipulacji w git rebase -i. Na przykład Zmiana kolejności zatwierdzeń, zgniatanie kilku w jeden, dodawanie dodatkowych zmian między zatwierdzeniami lub zmiana wiadomości. Jest to bardzo przydatne. Klasyczny przypadek użycia polega na czyszczeniu lokalnego oddziału, zanim przeniesiesz go z powrotem do miejsca, w którym inni ludzie będą patrzeć na twoje zmiany.

 11
Author: jwg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-27 06:16:02