Ihr Ansatz völlig falsch ist. Sie ändern etwas, das Sie nicht ändern möchten: Ihre aktuelle Verzweigung (vermutlich master
).
Eine einfache, lineare git-Repository ist eine Kette von Commits wie diese
*---A---*---*---B---*---*---C
^ ^
| |
master origin/master
^
|
HEAD
, dass der Zustand des Repository ist, nachdem Sie git fetch
genannt hast. Beachten Sie, dass sich der gesamte Verlauf mit allen Zwischenschritten direkt auf Ihrer lokalen Festplatte befindet. Es ist nur, dass Sie nur den Zustand bei der Übergabe A
ausgecheckt haben (HEAD
Punkte auf master
, die auf A
zeigt), so dass die Dateien, die Sie sehen, zu diesem Zustand gehören.
Wenn Sie jetzt nur den Status sehen möchten, der als B
festgeschrieben wurde, können Sie das Commit mit git checkout B
überprüfen. Dies aktualisiert die Dateien, die Sie auf den Zustand der B
sehen, und weist HEAD
an diesem begehen:
*---A---*---*---B---*---*---C
^ ^ ^
| | |
master HEAD origin/master
HEAD
immer verweist auf die Durchführungs-/Zweig, der git
denkt man an sind, und auf die sie Ihr Arbeitsverzeichnis vergleichen wenn Sie git status
anrufen.
Die einfache git checkout B
ist ausreichend, wenn Sie nur diese Commit betrachten möchten. Wenn Sie tatsächlich Änderungen vornehmen möchten, die Sie übernehmen und beibehalten möchten, sollten Sie einen neuen Zweig einführen, um diese Änderungen aufzuzeichnen. Dies wird durch eine einfache git checkout -b newBranch
nach der git checkout B
erreicht. Dies gibt Ihnen den Zustand
*---A---*---*---B---*---*---C
^ ^ ^
| | |
master newBranch origin/master
^
|
HEAD
Dies gibt nur einen Namen B
anderen als seinen Hash-Wert zu begehen.
*---A---*---*---B---*---*---C
^ | ^
| | |
master \ origin/master
\
*---*---D
^
|
newBranch
^
|
HEAD
Der Punkt ist, dass, nachdem eine andere Zweig Check-out/commit mit git checkout ...
, können Sie immer wieder ohne Probleme durch den Aufruf git checkout newBranch
zu begehen D
und das: Nach einigen Commits, Ihr Zustand würde wie folgt aussehen permanente Referenz stoppt git
von Müll sammeln commit D
.
Nun, warum wird git reset --hard
schlecht verwendet? Zunächst einmal klemmt es alle Ihre lokalen Änderungen, die Sie noch nicht ohne weitere Ankündigung begangen haben. Zweitens kann es Ihnen Geschichte verlieren, wenn Sie nicht vorsichtig damit sind.
Betrachten Sie zum Beispiel den Fall, dass Sie einige Änderungen vorgenommen haben, nachdem Sie zuletzt in Ihr Upstream-Repository verschoben wurden, und einen Blick auf einige historische Commit B
werfen möchten. (. Etwas das Gegenteil der Fall in Ihrer Frage) Die Geschichte sieht wie folgt aus:
*---A---*---*---B---*---*---C
^ ^
| |
origin/master master
^
|
HEAD
Mit git reset --hard B
, können Sie diesen Zustand erhalten:
*---A---*---*---B-(-*---*---C)
^ ^
| |
origin/master master
^
|
HEAD
Die Commits in Klammern sind nicht direkt referenziert oder indirekt durch jeden Zweig, und kann Müll jederzeit gesammelt werden. git
möglicherweise nicht sehr aggressiv mit Müll sammeln, aber wenn es Müll sammelt sammeln, während Sie in diesem Zustand sind, gibt es keine Möglichkeit für Sie, C
zurück zu bekommen, wird es für immer verloren. Sie wollen nicht, dass dies geschieht, also ist es keine gute Idee, sich an die Gewohnheit zu gewöhnen, git reset --hard
leicht zu verwenden.
Haben Sie git checkout
stattdessen verwendet, der Zweig master
noch C
gerichtet sein würde, und Sie würden noch in der Lage sein, zurück, um es mit einer einfachen git checkout master
zu bekommen.
Sie müssen die Verzweigung nicht wirklich zurücksetzen, da Sie sie einfach mit dem Anfangspunkt erstellen können, wo Sie ihn haben wollen, dh.'git branch newbranch SHA1-of-B' oder' git checkout -b newbranch SHA1-of-B' – Hasturkun
@ Sébastien Danke für die Einführung einiger grundlegender Konzepte. –
@Hasturkun Ihre Antwort funktioniert perfekt für mich, danke. –