Z innych odpowiedzi tutaj byłem trochę zdezorientowany, jak git rebase -i
można go użyć do usunięcia zatwierdzenia, więc mam nadzieję, że zapisanie mojego testu tutaj jest tutaj (bardzo podobne do OP).
Oto bash
skrypt, który możesz wkleić, aby utworzyć repozytorium testowe w /tmp
folderze:
set -x
rm -rf /tmp/myrepo*
cd /tmp
mkdir myrepo_git
cd myrepo_git
git init
git config user.name me
git config user.email me@myself.com
mkdir folder
echo aaaa >> folder/file.txt
git add folder/file.txt
git commit -m "1st git commit"
echo bbbb >> folder/file.txt
git add folder/file.txt
git commit -m "2nd git commit"
echo cccc >> folder/file.txt
git add folder/file.txt
git commit -m "3rd git commit"
echo dddd >> folder/file.txt
git add folder/file.txt
git commit -m "4th git commit"
echo eeee >> folder/file.txt
git add folder/file.txt
git commit -m "5th git commit"
W tym momencie mamy file.txt
z tymi treściami:
aaaa
bbbb
cccc
dddd
eeee
W tym momencie HEAD jest na 5. zatwierdzeniu, HEAD ~ 1 będzie na 4. - a HEAD ~ 4 będzie na 1. zatwierdzeniu (więc HEAD ~ 5 nie istnieje). Powiedzmy, że chcemy usunąć 3. zatwierdzenie - możemy wydać to polecenie w myrepo_git
katalogu:
git rebase -i HEAD~4
( Zauważ, że git rebase -i HEAD~5
wyniki z „fatal: Potrzebowałem jednej wersji; niepoprawny HEAD ~ 5”. ) Otworzy się edytor tekstu (patrz zrzut ekranu w odpowiedzi @Dennis ) z następującymi treściami:
pick 5978582 2nd git commit
pick 448c212 3rd git commit
pick b50213c 4th git commit
pick a9c8fa1 5th git commit
# Rebase b916e7f..a9c8fa1 onto b916e7f
# ...
Otrzymujemy więc wszystkie zatwierdzenia od (ale nie wliczając ) naszej żądanej GŁOWICY ~ 4. Usuń linię pick 448c212 3rd git commit
i zapisz plik; otrzymasz tę odpowiedź od git rebase
:
error: could not apply b50213c... 4th git commit
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To check out the original branch and stop rebasing run "git rebase --abort".
Could not apply b50213c... 4th git commit
W tym momencie otwórz myrepo_git / folder/file.txt
w edytorze tekstu; zobaczysz, że został zmodyfikowany:
aaaa
bbbb
<<<<<<< HEAD
=======
cccc
dddd
>>>>>>> b50213c... 4th git commit
Zasadniczo git
widzi, że kiedy HEAD dotarł do drugiego zatwierdzenia, pojawiła się treść aaaa
+ bbbb
; a następnie ma łatkę dodaną cccc
+, dddd
której nie wie, jak dołączyć do istniejącej zawartości.
Więc tutaj git
nie możesz zdecydować za Ciebie - to ty musisz podjąć decyzję: usuwając 3. zatwierdzenie, albo zachowujesz wprowadzone przez niego zmiany (tutaj wiersz cccc
) - albo nie. Jeśli nie, po prostu usuń dodatkowe wiersze - w tym cccc
- przy folder/file.txt
użyciu edytora tekstu, aby wyglądało to tak:
aaaa
bbbb
dddd
... a następnie zapisz folder/file.txt
. Teraz możesz wydać następujące polecenia w myrepo_git
katalogu:
$ nano folder/file.txt # text editor - edit, save
$ git rebase --continue
folder/file.txt: needs merge
You must edit all merge conflicts and then
mark them as resolved using git add
Ach - tak aby zaznaczyć, że mamy rozwiązać konflikt, my musi , przed wykonaniem :git add
folder/file.txt
git rebase --continue
$ git add folder/file.txt
$ git rebase --continue
Tutaj ponownie otwiera się edytor tekstowy, pokazujący wiersz 4th git commit
- tutaj mamy szansę zmienić komunikat zatwierdzenia (który w tym przypadku można znacznie zmienić na 4th (and removed 3rd) commit
lub podobny). Powiedzmy, że nie chcesz - więc po prostu wyjdź z edytora tekstu bez zapisywania; gdy to zrobisz, otrzymasz:
$ git rebase --continue
[detached HEAD b8275fc] 4th git commit
1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/master.
W tym momencie masz teraz taką historię (którą możesz również sprawdzić za pomocą powiedz gitk .
lub innymi narzędziami) zawartości folder/file.txt
(z pozornie niezmienionymi znacznikami czasu oryginalnych zatwierdzeń):
1st git commit | +aaaa
----------------------------------------------
2nd git commit | aaaa
| +bbbb
----------------------------------------------
4th git commit | aaaa
| bbbb
| +dddd
----------------------------------------------
5th git commit | aaaa
| bbbb
| dddd
| +eeee
A jeśli wcześniej postanowiliśmy zachować linię cccc
(zawartość trzeciego git commit, którą usunęliśmy), mielibyśmy:
1st git commit | +aaaa
----------------------------------------------
2nd git commit | aaaa
| +bbbb
----------------------------------------------
4th git commit | aaaa
| bbbb
| +cccc
| +dddd
----------------------------------------------
5th git commit | aaaa
| bbbb
| cccc
| dddd
| +eeee
Cóż, tego rodzaju lekturę miałem nadzieję znaleźć, żeby zacząć się zastanawiać, jak git rebase
działa usuwanie skryptu ; więc mam nadzieję, że może to również pomóc innym ...