git resetprzede wszystkim o przeniesienie HEAD, i ogólnie oddział ref .
Pytanie: co z drzewem roboczym i indeksem?
W przypadku korzystania z --soft, przenosi HEAD, najczęściej aktualizuje referencję gałęzi i tylkoHEAD .
To różni się od commit --amend:
- nie tworzy nowego zatwierdzenia.
- może faktycznie przenieść HEAD do dowolnego zatwierdzenia (tak jak
commit --amendtylko o nie przenoszeniu HEAD, jednocześnie pozwalając na ponowne wykonanie bieżącego zatwierdzenia)
Właśnie znalazłem ten przykład połączenia:
- klasyczne połączenie
- scalenie poddrzewa
wszystko w jeden (ośmiornica, ponieważ jest więcej niż dwie połączone gałęzie) zatwierdzić scalić.
Tomas „wereHamster” Carnecky wyjaśnia w swoim artykule „Scalanie ośmiornic poddrzewa” :
- Strategii scalania poddrzewa można użyć, jeśli chcesz scalić jeden projekt z podkatalogiem innego projektu, a następnie zachować aktualność podprojektu. Jest to alternatywa dla podmodułów git.
- Strategii łączenia ośmiornicy można użyć do scalenia trzech lub więcej gałęzi. Normalna strategia może łączyć tylko dwie gałęzie, a jeśli spróbujesz scalić więcej niż to, git automatycznie wróci do strategii ośmiornicy.
Problem w tym, że możesz wybrać tylko jedną strategię. Chciałem jednak połączyć te dwa elementy, aby uzyskać czystą historię, w której całe repozytorium jest atomowo aktualizowane do nowej wersji.
Mam superprojekt, nazwijmy go projectA, i podprojekt projectB, który połączyłem w podkatalogu projectA.
(to jest część scalania poddrzewa)
Utrzymuję też kilka lokalnych zmian.
ProjectAjest regularnie aktualizowany, projectBma nową wersję co kilka dni lub tygodni i zwykle zależy od konkretnej wersji projectA.
Decydując się na aktualizację obu projektów, po prostu nie wyciągam z nich, projectAa projectB to spowodowałoby utworzenie dwóch zatwierdzeń dla czegoś, co powinno być atomową aktualizacją całego projektu .
Zamiast tworzyć jeden scalającej który łączy projectA, projectBa moim lokalnym zobowiązuje .
Problem polega na tym, że jest to scalanie ośmiornic (trzy głowy), ale projectBmusi zostać połączone ze strategią poddrzewa . Więc oto co robię:
# Merge projectA with the default strategy:
git merge projectA/master
# Merge projectB with the subtree strategy:
git merge -s subtree projectB/master
Tutaj autor użył a reset --hard, a następnie, read-treeaby przywrócić to, co zrobiły pierwsze dwa scalenia w drzewie roboczym i indeksie, ale to reset --softmoże pomóc:
Jak powtórzyć te dwa scalenia , które zadziałały, tj. Moje drzewo robocze i indeks są dobrze, ale bez konieczności nagrywania tych dwóch zatwierdzeń?
# Move the HEAD, and just the HEAD, two commits back!
git reset --soft HEAD@{2}
Teraz możemy wznowić rozwiązanie Tomasza:
# Pretend that we just did an octopus merge with three heads:
echo $(git rev-parse projectA/master) > .git/MERGE_HEAD
echo $(git rev-parse projectB/master) >> .git/MERGE_HEAD
# And finally do the commit:
git commit
Tak więc za każdym razem:
- jesteś zadowolony z tego, z czym skończysz (pod względem drzewa roboczego i indeksu)
- jesteś nie zadowolony z wszystkich zatwierdzeń, które miały ty się tam dostać:
git reset --soft jest odpowiedzią.
git reset --soft: stackoverflow.com/questions/6869705/ ...