Pomoże ktoś w walce z gitem? Problem niby prosty, a męczę się z nim od wczoraj..
Załóżmy, że mamy taką sytuację:
- Inicjalizuję nowe repozytorium i przechodzę do brancha
master
- Dodaję nowy plik
file
, oraz commituję zmiany - Przechodzę do brancha
branch1
- Usuwam plik
file
, a następnie commituję zmiany - Przechodzę do brancha
master
- Modyfikuję plik
file
a następnie commituję zmiany - Merguję branch
branch1
w wyniku czego otrzymuję konflikt, ale rozwiązuję go - chcę zachować plik, więc commituję zmiany
Zrobiłem więc to:
git init
touch file
git add file
git commit -m 'add file'
git checkout -b 'branch1'
rm file
git add file
git commit -m 'delete file'
git checkout master
echo 'content' > file
git add file
git commit -m 'edit file'
git merge 'branch1'
git add file
git commit -m 'solve conflict'
Historia gita wygląda następująco:
38a9e5a (HEAD -> master) resolve conflict
4d07d5f edit file
8f7a049 (branch1) delete file
40db0ce add file
Teraz, chciałbym zmienić wiadomość commita 40db0ce
. W internecie przeczytałem, że można w tym celu wykorzystać polecenie git rebase
. W takim razie uruchamiam:
git rebase -i --root
w wyniku czego otrzymuję:
pick 40db0ce add file
pick 4d07d5f edit file
pick 8f7a049 delete file
zmieniam to na:
reword 40db0ce add file
pick 4d07d5f edit file
pick 8f7a049 delete file
Zatwierdzam, wprowadzam nową wiadomość commita i znowu zatwierdzam. Otrzymuję błąd:
error: could not apply 8f7a049... delete file
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 8f7a049... delete file
CONFLICT (modify/delete): file deleted in 8f7a049 (delete file) and modified in HEAD. Version HEAD of file left in tree.
Czytam internet i okazuje się, że domyślnie git rebase
nie wie w jaki sposób rozwiązać konflikty. Można uruchomić polecenie git rerere
, by git wiedział, by przy występowaniu konfliktów w rebase rozwiązać je tak, jak były rozwiązane wcześniej. Uruchamiam więc w konsoli:
git config --global rerere.enabled 1
Próbuję jeszcze raz wykonać zmianę wiadomości commita, ale otrzymuję ten sam błąd. Czytam internet i okazuje się, że tak skonfigurowane rerere zadziała dla przyszłych commitów. Aby zadziałało dla starych, należy uruchomić skrypt, który "nauczy" gita w jaki sposób zostały rozwiązane przeszłe konflikty. Uruchamiam więc skrypt rerere-train.sh:
./rerere-train.sh --all
Ponownie próbuję zmienić wiadomość commita, ale otrzymuję ten sam błąd. Zadałem pytanie na stackoverflow i otrzymałem odpowiedź, że konflikt polegający na modyfikacji czy usunięciu to inny typ konfliktu i git rerere sobie z nim nie poradzi. No ja pierd***, to jak mam w końcu zmienić nazwę tego commita?
Nie bardzo też rozumiem jak to ma w praktyce działać - załóżmy, że orientujemy się, że musimy zmienić nazwę commita, który został wrzucony rok temu. Rerere nie poradzi sobie z rozwiązywaniem konfliktów modyfikacji, więc jeszcze raz trzeba rozwiązywać wszystkie konflikty sprzed roku?