Git: Wie man sich zwischen Commits hin und her bewegt

76

Ich habe eine neue Frage zu Git:

Ich muss mich in der Geschichte eines Zweigs hin und her bewegen. Das heißt, ich muss alle Dateien in den Zustand bringen, in dem sie sich in einer alten Revision befanden, und dann muss ich in den neuesten Zustand im Repository zurückkehren. Ich muss mich nicht festlegen.

Mit SVN wäre es

svn up -r800

um zur Revision 800 zu gelangen, und

svn up

um mit dem Repository synchronisiert zu werden.

Ich kenne den Hash des Commits, zu dem ich zurückkehren möchte, also habe ich es versucht

git reset <hash>

das scheint mich dorthin zu bringen. Aber dann habe ich es versucht

git pull

aber das beschwert sich über Konflikte.

Was ist also der richtige Weg, um sich durch die Geschichte der Branche zu bewegen?

Ich denke in Bezug auf SVN, also zögern Sie nicht, mich auf ein nettes Tutorial hinzuweisen. Beachten Sie, dass ich bereits http://git.or.cz/course/svn.html und http://www.youtube.com/watch?v=8dhZ9BXQgc4 überprüft habe .

Danke, Ondra.

Ondra Žižka
quelle
1
Randnotiz: Ich habe mich daran gewöhnt, git pullganz zu vermeiden . Stattdessen verwende ich git fetch --allAlias ​​für guBash und habe gitkdie ganze Zeit geöffnet, um alle Zweige anzuzeigen - siehe Ansicht -> Bearbeiten -> Alle 4 Kontrollkästchen aktivieren. Dann bewege ich mich mit git resetoder gist stash+ git co, je nachdem was ich brauche.
Ondra Žižka

Antworten:

71

Nun, ich bin auch ein ehemaliger SVN-Benutzer und verwende jetzt Git für alle meine Projekte.

Wenn Sie git verwenden, sollten Sie die Denkweise der in svn verwendeten Client-Server-Architektur ändern. In svn benötigt jede Änderung eine Verbindung mit dem Server. Mit git befindet sich Ihr Repo im Arbeitsverzeichnis. Sie benötigen nicht für jede Repo-Aktion eine Verbindung.

Nur verwenden git pushund git pullmit Repo synchronisieren. Stellen Sie sich vor, Sie verwenden rsync oder eine andere Sicherungslösung, um zwei Orte mit genau demselben Inhalt zu versehen. Genauso wie Sie eine externe Sicherungsfestplatte anschließen, müssen Sie den Inhalt darin mit dem Inhalt in Ihrer Hauptfestplatte identisch machen. Das ist die Verwendung von git pullund git push.

Wenn Sie nur den Verlauf hin und her gehen möchten, tun Sie dies mit git checkout. Siehe die Revisions-ID mit git history. Wenn Sie Linux verwenden, verwenden Sie gitk, um den Revisionsbaum anzuzeigen. In Windows kann Tortoise Git es mithilfe eines Revisionsdiagramms anzeigen.

Verwenden Sie, um zur neuesten Version zurückzukehren git checkout master. Lassen Sie sich immer etwas tun, bevor Sie einen Befehl ausführen git status. Dieser Befehl zeigt alles an, was Sie über den aktuellen Repo-Zustand wissen müssen und welche Maßnahmen Sie ergreifen müssen, um ihn richtig zu machen. Stellen Sie vor git pullund git pushsicher, dass das git statusErgebnis Text enthält working directory clean.

Wenn Sie eine Datei auf die vorherige Version zurücksetzen müssen, können Sie dies tun git merge. Bevor Sie eine Datei bearbeiten, testen Sie sie zuerst mit git diff. Bsp. : git diff rev1:rev2 filename. Es wird zwischen zwei Revisionen anders gedruckt. Die Änderung in Version 1 wird durch die Änderungen in Version 2 ersetzt. Um zurückzusetzen, ist rev2 älter als rev1. Nachdem Sie mit dem diff Ergebnis zufrieden stellen, tun Sie es mit git merge, ersetzen Sie einfach diffmit merge, wenn alle anderen Parameter gleich bleiben.

Ich hoffe das hilft dir. Der Hauptschlüssel ist zu sehen, dass Ihr Arbeitsverzeichnis Ihr Repo ist. Wenn Sie dies verstehen, können Sie Git in vollem Umfang nutzen. Viel Glück.

Donny Kurnia
quelle
39

Sie können git checkoutjedes Commit auschecken und es dann mit einem Zweignamen verwenden, um zu einem benannten Zweig zurückzukehren.

git checkoutMit einer Commit-ID und keinem Filialnamen gelangen Sie von einem benannten Zweig zu einem so genannten abgetrennten Kopf .

Wenn Sie verwenden git reset, wird Ihr Zweig selbst in einen alten Zustand zurückversetzt, wodurch die neueren Commits verwaist werden, was wahrscheinlich nicht das ist, was Sie wollen.

CB Bailey
quelle
Was macht das checkoutwirklich? Ändert es die Dateien in den Status des angegebenen Commits, indem die Patches der Commits zwischen dem aktuellen Status und dem Status des angegebenen Commits umgekehrt angewendet werden?
Ondra Žižka
Ich habe gefunden git resetund git reset origin. Ich werde keine Commits ausführen, daher spielt es keine Rolle, ob ich die letzten Commits verliere, soweit sie leicht wiederhergestellt werden können (dh mit einem einzigen Befehl).
Ondra Žižka
1
Git Checkout machen die Änderung nicht dauerhaft. Verwenden Sie dazu git merge. Siehe meine Antworten.
Donny Kurnia
1
Beim Zurücksetzen der Kasse wird der Index- / Cache- / Staging-Bereich auf den durch das angegebene Commit festgelegten Baum gesetzt und anschließend der Arbeitsbaum aktualisiert, um ihn an den Cache anzupassen. Es muss kein Patch erneut angewendet werden. Es wird nur der Baum wie beim angegebenen Commit verwendet. (Es hat auch Fehlerprüfung und aktualisiert den ausgecheckten Zweig, wenn Sie ihm einen
CB Bailey
30

Die anderen Antworten sind informativ, aber ich glaube, dies kommt den Wünschen des OP am nächsten:

Fügen Sie diese beiden Funktionen zu Ihrem ~ / .bashrc hinzu:

# checkout prev (older) revision
git_prev() {
    git checkout HEAD~
}

# checkout next (newer) commit
git_next() {
    BRANCH=`git show-ref | grep $(git show-ref -s -- HEAD) | sed 's|.*/\(.*\)|\1|' | grep -v HEAD | sort | uniq`
    HASH=`git rev-parse $BRANCH`
    PREV=`git rev-list --topo-order HEAD..$HASH | tail -1`
    git checkout $PREV
}

Verwendung:

$ git_prev
Previous HEAD position was 7042c8a... Commit message2
HEAD is now at d753ecc... Commit message1

$ git_next
Previous HEAD position was d753ecc... Commit message1
HEAD is now at 7042c8a... Commit message2

Hinweis : Diese Befehle wechseln immer in den Status " Getrennter HEAD" . Wenn Sie git_prevdann git_nextaus einem aktuell ausgecheckten Zweig stammen, werden Sie bei der letzten Revision zurückkehren, befinden sich jedoch im getrennten HEAD-Status. Tun git checkout BRANCH_NAME, um wieder normal zu werden.

Raine Revere
quelle
Sobald Sie solche Dinge tun, werfen Sie einen Blick auf Git-Aliase kann lohnenswert sein.
Rethab
Ich liebe diese Antwort und sie hat eine Minute lang funktioniert, aber jetzt, wenn ich git_next starte, bekomme ich dieseusage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]] [-e pattern] [-f file] [--binary-files=value] [--color=when] [--context[=num]] [--directories=action] [--label] [--line-buffered] [--null] [pattern] [file ...]
Squirrl
11

Versuchen Sie git reflog, hier werden Commits und Checkouts aufgelistet, die Sie durchgeführt haben, um zwischen den Commits zu wechseln, selbst die Commits, die Sie beim Auschecken zu einem vorherigen Commit verloren haben.

Dann können Sie versuchen git checkout <hash of a commit>, zu diesem Commit zu wechseln.

Hoffe das hilft!

Ryan Le
quelle
7

Verwenden Sie zum Auschecken einer anderen Version einer Datei

git checkout rev -- filename

Dabei kann rev die ID eines Commits, der Name eines Zweigs, der Name eines Tags oder eine relative Version sein.

Verwenden Sie git log, gitkschauen Versionen prüfen Sie wollen zu sehen , welche Version der Datei.

Um diese Version der Datei dauerhaft zu machen, müssen Sie die Datei festschreiben: git add filename; git commit filename

Ich würde nicht empfehlen git pull, Versionen zu untersuchen, da sie zusammengeführt werden und möglicherweise Ihren aktuellen Status ändern.

Sie müssen nicht verwenden müssen , git resetin diesem Fall, wenn Sie git addeine Datei , die Sie nicht zu begehen entscheiden.

Jamey Hicks
quelle
süßer jeebus sei vorsichtig dabei. Mein Kollege hat diesen Befehl ausgeführt, um Änderungen in meinem Zweig auszuprobieren, meine Arbeit im Wert von etwa einer Woche ausgelöscht und sie auf diese Weise zum Repo gebracht ...
karina
Solange Ihr Mitarbeiter kein Push-F ausgeführt hat, können Sie sein Commit jederzeit rückgängig machen und die fehlende Arbeit wiederherstellen. Wenn Sie Zugriff auf das Repo haben, zu dem er gedrückt hat, kann sogar ein Force-Push über Git-Reflog wiederhergestellt werden. Wenn Sie Ihre Filiale noch haben, kann sie wiederhergestellt werden. Aber ja, du musst vorsichtig sein.
Jamey Hicks