Twoje podejście jest całkowicie błędne. Modyfikujesz coś, czego nie chcesz modyfikować: Twoją bieżącą gałąź (prawdopodobnie master
).
Prosty, liniowy repozytorium git jest łańcuchem zobowiązuje się ten
*---A---*---*---B---*---*---C
^ ^
| |
master origin/master
^
|
HEAD
To jest stan repozytorium po nazwali git fetch
. Zauważ, że cała historia wraz ze wszystkimi pośrednimi krokami znajduje się właśnie na twoim lokalnym dysku twardym. Trzeba tylko sprawdzić stan zatwierdzenia A
(HEAD
punktów na master
, który wskazuje na A
), więc pliki, które widzisz, należą do tego stanu.
Teraz, jeśli chcesz spojrzeć na stan, który został zatwierdzony jako B
, możesz po prostu sprawdzić, czy zatwierdzić z git checkout B
. To aktualizuje pliki, które widzisz na stan B
i wskazuje HEAD
na które popełnić:
*---A---*---*---B---*---*---C
^ ^ ^
| | |
master HEAD origin/master
HEAD
zawsze odwołuje się do popełniania/gałąź git
myśli jesteś, i do którego będzie porównać swój katalog roboczy po wywołaniu git status
.
Wystarczy prosty git checkout B
, jeśli po prostu chcesz przejrzeć to zatwierdzenie. Jeśli rzeczywiście chcesz wprowadzić zmiany, które zatwierdzasz i chcesz zachować, powinieneś wprowadzić nowy oddział, aby zapisać te zmiany. Osiąga się to przez proste git checkout -b newBranch
po git checkout B
. To daje stan
*---A---*---*---B---*---*---C
^ ^ ^
| | |
master newBranch origin/master
^
|
HEAD
to po prostu daje nazwę popełnienia B
innej niż jego wartość hash. Po jakichś bardziej zobowiązuje, Twój stan będzie wyglądać następująco:
*---A---*---*---B---*---*---C
^ | ^
| | |
master \ origin/master
\
*---*---D
^
|
newBranch
^
|
HEAD
Chodzi o to, że po sprawdzeniu innego oddziału/commit z git checkout ...
, zawsze można łatwo powrócić do popełnienia D
wywołując git checkout newBranch
oraz stałe przystanki referencyjne git
z zatwierdzenia usuwania śmieci D
.
Dlaczego teraz używasz git reset --hard
? Po pierwsze, blokuje wszystkie lokalne zmiany, które nie zostały jeszcze zatwierdzone bez powiadomienia. Po drugie, może stracić historię, jeśli nie będziesz z nią ostrożny.
Rozważmy na przykład przypadek, w którym wprowadzono pewne zmiany po ostatnim przekazaniu do repozytorium wyższego szczebla i chcemy przyjrzeć się historycznemu zatwierdzeniu B
. (. Nieco przeciwieństwem sprawy w swoje pytanie) Historia wygląda następująco:
*---A---*---*---B---*---*---C
^ ^
| |
origin/master master
^
|
HEAD
Z git reset --hard B
, masz ten stan:
*---A---*---*---B-(-*---*---C)
^ ^
| |
origin/master master
^
|
HEAD
W commity w nawiasach nie są odniesione bezpośrednio lub pośrednio przez jakikolwiek oddział i mogą być w dowolnym momencie zbierane śmieci. git
może nie być bardzo agresywny w przypadku zbierania śmieci, , ale jeśli nie będzie zbierać śmieci, gdy jesteś w tym stanie, nie ma możliwości, aby uzyskać zatwierdzenie C
z powrotem, będzie utracone na zawsze. Nie chcesz, aby tak się stało, więc nie jest dobrym pomysłem, aby nabrać zwyczaju używania lekko git reset --hard
.
Gdyby użyto git checkout
zamiast oddział master
nadal będzie wskazujące na C
, i nadal będzie w stanie wrócić do niego za pomocą prostego git checkout master
.
Naprawdę nie trzeba resetować gałęzi, ponieważ można ją po prostu utworzyć, gdy punkt początkowy jest tam, gdzie chcesz, tj.'git branch newbranch SHA1-of-B' lub' git checkout -b newbranch SHA1-of-B' – Hasturkun
@ Sébastien Dzięki za przedstawienie mi podstawowych pojęć. –
@Hasturkun Twoja odpowiedź działa idealnie dla mnie, dzięki. –