Git-Zweig muss auf Ursprungsversion zurückgesetzt werden

440

Ich habe versehentlich an einem Zweig gearbeitet, an dem ich eine Weile nicht hätte sein sollen, also habe ich mich davon getrennt und ihm den passenden Namen gegeben. Jetzt möchte ich den Zweig überschreiben, auf dem ich nicht die Version von Origin (Github) hätte verwenden sollen. Gibt es eine einfache Möglichkeit, dies zu tun? Ich habe versucht, den Zweig zu löschen und dann den Tracking-Zweig zurückzusetzen, aber es gibt mir nur die Version, an der ich wieder gearbeitet habe.

Brad Herman
quelle
Mit Git 2.23 (August 2019) : git switch -C mybranch origin/mybranch. Siehe meine bearbeitete Antwort unten
VonC

Antworten:

814

Wenn Sie noch nicht zum Ursprung verschoben haben, können Sie Ihren Zweig auf den vorgelagerten Zweig zurücksetzen mit:

git checkout mybranch
git reset --hard origin/mybranch

(Stellen Sie sicher, dass Sie Ihr letztes Commit in einem separaten Zweig referenzieren, wie Sie in Ihrer Frage erwähnt haben.)

Beachten Sie, dass sich unmittelbar nach dem Zurücksetzen mybranch@{1}auf das alte Festschreiben vor dem Zurücksetzen bezieht.

Wenn Sie jedoch bereits einen Push durchgeführt haben, finden Sie unter " Git-Zweig erstellen und Original in den Upstream-Status zurücksetzen " weitere Optionen.


Mit Git 2.23 (August 2019) wäre das ein Befehl : git switch.
Nämlich:git switch -C mybranch origin/mybranch

Beispiel

C:\Users\vonc\git\git>git switch -C master origin/master
Reset branch 'master'
Branch 'master' set up to track remote branch 'master' from 'origin'.
Your branch is up to date with 'origin/master'.

Dadurch werden der Index und der Arbeitsbaum wie gewohnt wiederhergestellt git reset --hard.


Wie von Brad Herman kommentiert , reset --hardwürde a jede neue Datei entfernen oder geänderte Dateien auf HEAD zurücksetzen .

git clean -f -dUm sicherzugehen , dass Sie von einem "sauberen Schiefer" ausgehen, würde a nach dem Zurücksetzen einen Arbeitsbaum sicherstellen, der genau mit dem Zweig identisch ist, auf den Sie gerade zurückgesetzt haben.


Dieser Blog-Beitrag schlägt diese Aliase vor (nur für masterZweige, aber Sie können diese anpassen / erweitern):

[alias]
   resetorigin = !git fetch origin && git reset --hard origin/master && git clean -f -d
   resetupstream = !git fetch upstream && git reset --hard upstream/master && git clean -f -d

Dann können Sie Folgendes eingeben:

git resetupstream

oder

git resetorigin
VonC
quelle
26
Dies wird UNSTAGED / STAGED Änderungen (von der --hard) löschen
Peter Ehrlich
5
Ich habe den git reset --hard origin/mybranchBefehl mehrmals verwendet, als mir lokale Änderungen egal waren und ich wollte nur eine saubere Kopie, die dem Ursprung entspricht. Heute hat dies jedoch nicht funktioniert - ich hatte immer noch eine Handvoll neuer, nicht bereitgestellter Dateien, und Git versprach mir immer wieder, dass es bei HEAD war. Der Hinweis zu git clean -f -dbehoben, dass durch Löschen aller neuen Dateien, die ich nicht wollte.
Matthew Clark
@MatthewClark Das wird erwartet: siehe Kommentar zu stackoverflow.com/q/4327708/6309
VonC
1
Großartig! Auch oft habe ich verwendet git reset --hard HEAD, um zu einem vorherigen Commit zurückzukehren und alle Änderungen zu ignorieren
daronwolff
Ist das auch mit Sourctree möglich?
Lonzak
20

Angenommen, dies ist passiert:

# on branch master
vi buggy.py                 # you edit file
git add buggy.py            # stage file
git commit -m "Fix the bug" # commit
vi tests.py                 # edit another file but do not commit yet

Dann stellen Sie fest, dass Sie Änderungen am falschen Zweig vornehmen.

git checkout -b mybranch    # you create the correct branch and switch to it

Zeigt aber masterimmer noch auf Ihr Commit. Sie möchten, dass es zeigt, wohin es zuvor gezeigt hat.

Lösung

Der einfachste Weg ist:

git branch --force master origin/master

Ein anderer Weg ist:

git checkout master
git reset --soft origin/master
git checkout mybranch

Beachten Sie, dass bei Verwendung reset --hardIhre nicht festgeschriebenen Änderungen verloren gehen ( tests.pyin meinem Beispiel).

user28667
quelle
Das scheint sicherer als in meiner Antwort;) +1
VonC
8

Ich habe ein privates Repo auf einem Server und muss es regelmäßig neu starten / erzwingen, was es erforderlich macht, den lokalen Zweig auf meinem anderen Computer häufig zurückzusetzen. Ich habe daher den folgenden Alias ​​"catchup" erstellt, der dies für den aktuellen Zweig ermöglicht. Im Gegensatz zur anderen Antwort enthält dieser Alias ​​keinen fest codierten Zweignamen.

Festhalten.

[alias]
  catchup = "!f(){ echo -n \"reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) \"; read -r ans; if [ \"$ans\" = \"y\" -o \"$ans\" = \"Y\" -o -z \"$ans\" ]; then git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)); else echo \"catchup aborted\"; fi }; f"

Richtig formatiert (funktioniert nicht mit den Zeilenumbrüchen in .gitconfig) sieht es folgendermaßen aus:

"
!f(){
  echo -n \"reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) \";
  read -r ans;
  if [ \"$ans\" = \"y\" -o \"$ans\" = \"Y\" -o -z \"$ans\" ]; then
    git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD));
  else
    echo \"catchup aborted\";
  fi
}; f
"
  • Das \\033[0;33mund \\033[0mdient zur Hervorhebung des aktuellen Zweigs und stromaufwärts mit Farbe.
  • $(git symbolic-ref -q --short HEAD) ist der aktuelle Filialname
  • $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)) ist der Upstream des aktuellen Zweigs.

Da das Zurücksetzen ein potenziell gefährlicher Aufruf ist (insbesondere mit der Option --hard verlieren Sie alle nicht festgeschriebenen Änderungen), erfahren Sie zunächst, was zu tun ist. Wenn Sie sich beispielsweise in einem Zweig dev-container mit der Fernbedienung qcpp / dev-container befinden und eingeben git catchup, werden Sie aufgefordert:

dev-container auf qcpp / dev-container zurücksetzen? (J / n)

Wenn Sie dann y eingeben oder einfach die Eingabetaste drücken, wird der Reset durchgeführt. Wenn Sie etwas anderes eingeben, wird der Reset nicht durchgeführt.

Wenn Sie sehr sicher sein und programmgesteuert verhindern möchten, dass nicht bereitgestellte / nicht festgeschriebene Änderungen verloren gehen, können Sie den obigen Alias ​​mit entsprechenden Überprüfungen auf Diff-Index weiter aufpeppen .

Das obligatorische Wort der Warnung: Wenn Sie an einem öffentlichen Repository arbeiten, auf dem andere Personen basieren, und Sie diesen Alias ​​benötigen, machen Sie es falsch ™ .

DerManu
quelle
1

Ich habe es versucht und es hat meinen aktuellen Zweig nicht auf meinen Remote-Github zurückgesetzt. Ich habe gegoogelt und https://itsyndicate.org/blog/how-to-use-git-force-pull-properly/ gefunden.

was vorgeschlagen

git fetch origin master
git reset --hard origin/master

Ich wollte meinen v8-Zweig zurücksetzen, also tat ich es

git fetch origin v8
git reset --hard origin/v8

und es hat funktioniert

SimpleSi
quelle
Gut, dass Sie Fetch erwähnen. Ich habe das einmal ohne gemacht und alles auf vor 2 Jahren zurückgesetzt :)
Adam