Wie setze ich meinen lokalen Zweig so zurück, dass er dem Zweig im Remote-Repository entspricht?
Ich tat:
git reset --hard HEAD
Aber wenn ich einen git status
starte,
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: Java/com/mycompany/TestContacts.Java
modified: Java/com/mycompany/TestParser.Java
Kannst du mir bitte sagen, warum ich diese 'modifiziert' habe? Ich habe diese Dateien nicht berührt? Wenn ja, möchte ich diese entfernen.
Das Einstellen Ihrer Verzweigung so, dass sie genau mit der entfernten Verzweigung übereinstimmt, kann in zwei Schritten erfolgen:
git fetch Origin
git reset --hard Origin/master
Wenn Sie den Status Ihrer aktuellen Niederlassung speichern möchten, bevor Sie dies tun (nur für den Fall), können Sie Folgendes tun:
git commit -a -m "Saving my work, just in case"
git branch my-saved-work
Jetzt wird Ihre Arbeit im Zweig "Meine gespeicherte Arbeit" gespeichert, für den Fall, dass Sie sie zurückhaben möchten (oder sie später ansehen oder sie mit Ihrem aktualisierten Zweig vergleichen möchten).
Beachten Sie, dass im ersten Beispiel davon ausgegangen wird, dass der Name des Remote-Repos "Origin" ist und dass der Zweig "master" im Remote-Repo mit dem derzeit ausgecheckten Zweig in Ihrem lokalen Repo übereinstimmt.
Übrigens ähnelt diese Situation, in der Sie sich befinden, einem gewöhnlichen Fall, in dem ein Push-Vorgang in den derzeit ausgecheckten Zweig eines nicht-bloßen Repositorys ausgeführt wurde. Hast du kürzlich in dein lokales Repo gedrängt? Wenn nicht, dann keine Sorge - irgendetwas anderes muss dazu geführt haben, dass diese Dateien unerwartet geändert wurden. Andernfalls sollten Sie sich bewusst sein, dass es nicht empfehlenswert ist, in ein nicht-bares Repository (und insbesondere nicht in den derzeit ausgecheckten Zweig) zu pushen.
Ich musste Folgendes tun (die Lösung in der akzeptierten Antwort):
git fetch Origin
git reset --hard Origin/master
Gefolgt von:
git clean -f
So sehen Sie, welche Dateien entfernt werden (ohne sie tatsächlich zu entfernen):
git clean -n -f
Setzen Sie zunächst den zuvor abgerufenen HEAD
des entsprechenden Upstream-Zweigs zurück:
git reset --hard @{u}
Der Vorteil der Angabe von @{u}
oder seiner ausführlichen Form @{upstream}
besteht darin, dass der Name des Remote-Repos und der Verzweigung nicht explizit angegeben werden muss.
Entfernen Sie anschließend nach Bedarf nicht verfolgte Dateien, optional auch mit -x
:
git clean -df
Abschließend erhalten Sie nach Bedarf die neuesten Änderungen:
git pull
git reset --hard HEAD
wird tatsächlich nur auf den letzten festgeschriebenen Zustand zurückgesetzt. In diesem Fall bezieht sich HEAD auf das HEAD Ihrer Branche.
Wenn Sie mehrere Commits haben, funktioniert dies nicht.
Was Sie wahrscheinlich tun möchten, ist das Zurücksetzen auf den Head of Origin oder den Namen Ihres Remote-Repositorys. Ich würde wahrscheinlich nur so etwas machen
git reset --hard Origin/HEAD
Sei aber vorsichtig. Hard-Resets können nicht einfach rückgängig gemacht werden. Machen Sie es besser, wie Dan es vorschlägt, und verzweigen Sie eine Kopie Ihrer Änderungen, bevor Sie sie zurücksetzen.
Alle oben genannten Vorschläge sind richtig, aber um Ihr Projekt wirklich zurückzusetzen, müssen Sie auch Dateien entfernen, die sich in Ihrem .gitignore
befinden.
Um das moralische Äquivalent von Löschen Ihres Projektverzeichnisses und erneutes Klonen von der Fernbedienung zu erhalten, gehen Sie wie folgt vor:
git fetch
git reset --hard
git clean -x -d -f
Warnung: git clean -x -d -f
ist irreversibel und Sie können Dateien und Daten verlieren (z. B. Dinge, die Sie mit .gitignore
ignoriert haben).
Die Frage mischt hier zwei Punkte:
git status
nothing to commit, working directory clean.
sagtDie One-Stop-Antwort lautet:
git fetch --Prune
(optional) Aktualisiert den lokalen Snapshot des Remote-Repos. Weitere Befehle sind nur lokal.git reset --hard @{upstream}
Setzt den lokalen Verzweigungszeiger auf den Speicherort des Snapshots der Fernbedienung sowie den Index und das Arbeitsverzeichnis auf die Dateien dieses Commits.git clean -d --force
Entfernt nicht verfolgte Dateien und Verzeichnisse, die verhindern, dass "Arbeitsverzeichnis sauber" angezeigt wird.Dies ist etwas, mit dem ich regelmäßig konfrontiert bin, und ich habe das Skript, das Wolfgang oben bereitgestellt hat, verallgemeinert, um mit jedem Zweig zu arbeiten
Ich habe auch eine Eingabeaufforderung "Sind Sie sicher" und eine Feedback-Ausgabe hinzugefügt
#!/bin/bash
# reset the current repository
# WF 2012-10-15
# AT 2012-11-09
# see http://stackoverflow.com/questions/1628088/how-to-reset-my-local-repository-to-be-just-like-the-remote-repository-head
timestamp=`date "+%Y-%m-%d-%H_%M_%S"`
branchname=`git rev-parse --symbolic-full-name --abbrev-ref HEAD`
read -p "Reset branch $branchname to Origin (y/n)? "
[ "$REPLY" != "y" ] ||
echo "about to auto-commit any changes"
git commit -a -m "auto commit at $timestamp"
if [ $? -eq 0 ]
then
echo "Creating backup auto-save branch: auto-save-$branchname-at-$timestamp"
git branch "auto-save-$branchname-at-$timestamp"
fi
echo "now resetting to Origin/$branchname"
git fetch Origin
git reset --hard Origin/$branchname
Vorausgesetzt, das Remote-Repository ist Origin
und Sie interessieren sich für branch_name
:
git fetch Origin
git reset --hard Origin/<branch_name>
Außerdem müssen Sie den aktuellen Zweig von Origin
auf HEAD
zurücksetzen.
git fetch Origin
git reset --hard Origin/HEAD
Wie es funktioniert:
git fetch Origin
lädt die neueste Version von der Fernbedienung herunter, ohne zu versuchen, etwas zusammenzuführen oder neu zu strukturieren.
Dann setzt der git reset
den Zweig <branch_name>
auf das zurück, was Sie gerade abgerufen haben. Die Option --hard
ändert alle Dateien in Ihrem Arbeitsbaum so, dass sie mit den Dateien in Origin/branch_name
übereinstimmen.
Verwenden Sie die folgenden Befehle. Diese Befehle entfernen auch alle nicht verfolgten Dateien aus dem lokalen Git
git fetch Origin
git reset --hard Origin/master
git clean -d -f
Hier ist ein Skript, das das automatisiert, was die beliebteste Antwort vorschlägt ... Siehe https://stackoverflow.com/a/13308579/1497139 für eine verbesserte Version, die Zweige unterstützt
#!/bin/bash
# reset the current repository
# WF 2012-10-15
# see https://stackoverflow.com/questions/1628088/how-to-reset-my-local-repository-to-be-just-like-the-remote-repository-head
timestamp=`date "+%Y-%m-%d-%H_%M_%S"`
git commit -a -m "auto commit at $timestamp"
if [ $? -eq 0 ]
then
git branch "auto-save-at-$timestamp"
fi
git fetch Origin
git reset --hard Origin/master
Ich tat:
git branch -D master
git checkout master
zweig vollständig zurücksetzen
beachten Sie, dass Sie zu einem anderen Zweig auschecken sollten, um den erforderlichen Zweig löschen zu können
Wenn Sie als ich ein Problem hatten, dass Sie bereits einige Änderungen vorgenommen haben, aber jetzt, aus irgendeinem Grund, Sie es loswerden möchten, ist der schnellste Weg, git reset
wie folgt zu verwenden:
git reset --hard HEAD~2
Ich hatte 2 nicht benötigte Commits, daher die Nummer 2. Sie können sie in Ihre eigene Anzahl von Commits ändern, um sie zurückzusetzen.
Beantworten Sie also Ihre Frage - wenn Sie 5 Commits vor dem Remote-Repository HEAD haben, sollten Sie diesen Befehl ausführen:
git reset --hard HEAD~5
Beachten Sie, dass Sie die vorgenommenen Änderungen verlieren. Seien Sie also vorsichtig!
Das benutze ich oft:
git fetch upstream master;
git reset --hard upstream/master;
git clean -d --force;
Beachten Sie, dass es empfehlenswert ist, keine Änderungen an Ihrem lokalen Master vorzunehmen, sondern stattdessen bei einem anderen Zweig nach Änderungen Auschecken, wobei dem Zweignamen die Art der Änderung vorangestellt wird, z. feat/
, chore/
, fix/
usw. Sie müssen also nur Änderungen übernehmen, keine Änderungen vom Master übertragen. Dasselbe gilt für andere Branchen, zu denen andere beitragen. Daher sollte das Obige nur verwendet werden, wenn Sie Änderungen an einem Zweig festgeschrieben haben, für den andere festgeschrieben haben, und zurückgesetzt werden müssen. Andernfalls sollten Sie künftig vermeiden, auf einen Zweig zu pushen, zu dem andere pushen, und stattdessen über den ausgecheckten Zweig auf diesen Zweig pushen.
Wenn Sie Ihren lokalen Zweig auf das neueste Commit im Upstream-Zweig zurücksetzen möchten, funktioniert für mich Folgendes:
Überprüfen Sie Ihre Fernbedienungen, stellen Sie sicher, dass Ihre Upstream- und Origin-Einstellungen Ihren Erwartungen entsprechen, und verwenden Sie, falls nicht erwartet, git remote add upstream <insert URL>
, z. des ursprünglichen GitHub-Repos, von dem aus du gegabelt hast, und/oder git remote add Origin <insert URL of the forked GitHub repo>
.
git remote --verbose
git checkout develop;
git commit -m "Saving work.";
git branch saved-work;
git fetch upstream develop;
git reset --hard upstream/develop;
git clean -d --force
In GitHub können Sie auch den Zweig mit demselben Namen wie den lokalen auschecken, um die Arbeit dort zu speichern. Dies ist jedoch nicht erforderlich, wenn Origin Develop dieselben Änderungen wie der lokale Zweig für gespeicherte Arbeit hat. Ich verwende den Entwicklungszweig als Beispiel, aber es kann sich um einen beliebigen vorhandenen Zweignamen handeln.
git add .
git commit -m "Reset to upstream/develop"
git Push --force Origin develop
Wenn Sie diese Änderungen dann bei Konflikten mit einem anderen Zweig zusammenführen müssen und die Änderungen in der Entwicklung beibehalten möchten, verwenden Sie Folgendes:
git merge -s recursive -X theirs develop
Während des Gebrauchs
git merge -s recursive -X ours develop
um widersprüchliche Änderungen von branch_name beizubehalten. Verwenden Sie andernfalls ein Mergetool mit git mergetool
.
Mit all den Änderungen zusammen:
git commit -m "Saving work.";
git branch saved-work;
git checkout develop;
git fetch upstream develop;
git reset --hard upstream/develop;
git clean -d --force;
git add .;
git commit -m "Reset to upstream/develop";
git Push --force Origin develop;
git checkout branch_name;
git merge develop;
Beachten Sie, dass Sie anstelle von Upstream/Develop einen Festschreibungs-Hash, einen anderen Zweignamen usw. verwenden können. Verwenden Sie ein CLI-Tool wie Oh My Zsh, um zu überprüfen, ob Ihr Zweig grün ist. bestätigt oder auch überprüfbar durch git status
). Beachten Sie, dass dies im Vergleich zur vorgelagerten Entwicklung tatsächlich Commits hinzufügen kann, wenn durch ein Commit automatisch etwas hinzugefügt wird, z. UML-Diagramme, Lizenzheader usw. In diesem Fall können Sie die Änderungen bei Bedarf in Origin develop
in upstream develop
übernehmen.
Bei den vorherigen Antworten wird davon ausgegangen, dass der zurückzusetzende Zweig der aktuelle Zweig ist (ausgecheckt). In Kommentaren hat OP hap497 klargestellt, dass die Verzweigung zwar ausgecheckt ist, dies jedoch in der ursprünglichen Frage nicht ausdrücklich gefordert wird. Da es mindestens eine "doppelte" Frage gibt, Zweig vollständig auf den Repository-Status zurücksetzen , die nicht davon ausgeht, dass der Zweig ausgecheckt ist, ist hier eine Alternative:
Wenn der Zweig "mybranch" derzeit nicht ausgecheckt ist, können Sie diesen verwenden, um ihn auf den Kopf des entfernten Zweigs "myremote/mybranch" zurückzusetzen. Low-Level Befehl:
git update-ref refs/heads/mybranch myremote/mybranch
Bei dieser Methode bleibt der ausgecheckte Zweig unverändert, und der Arbeitsbaum bleibt unberührt. Es bewegt einfach den Kopf von mybranch zu einem anderen Commit, was auch immer als zweites Argument angegeben wird. Dies ist besonders hilfreich, wenn mehrere Zweige auf neue Remote-Köpfe aktualisiert werden müssen.
Gehen Sie dabei jedoch vorsichtig vor und verwenden Sie gitk
oder ein ähnliches Tool, um Quelle und Ziel zu überprüfen. Wenn Sie dies versehentlich auf dem aktuellen Zweig tun (und Git wird Sie nicht davon abhalten), können Sie verwirrt werden, weil der neue Zweiginhalt nicht mit dem Arbeitsbaum übereinstimmt, der sich nicht geändert hat (um das Problem zu beheben, aktualisieren Sie den Zweig erneut). dorthin, wo es vorher war).
Wenn Sie für das Arbeitsverzeichnis und den Index zum Status HEAD
zurückkehren möchten, sollten Sie git reset --hard HEAD
anstelle von HEAD^
. (Dies könnte ein Tippfehler gewesen sein, genau wie der einfache gegenüber dem doppelten Gedankenstrich für --hard
.)
Bei Ihrer speziellen Frage, warum diese Dateien im Status "Geändert" angezeigt werden, sieht es so aus, als hätten Sie einen Soft-Reset anstelle eines Hard-Reset durchgeführt. Dies führt dazu, dass die Dateien, die im Commit HEAD
geändert wurden, so angezeigt werden, als ob sie bereitgestellt worden wären. Dies ist wahrscheinlich das, was Sie hier sehen.
Keine Menge an Zurücksetzen und Bereinigen schien Auswirkungen auf nicht verfolgte und geänderte Dateien in meinem lokalen Git-Repo zu haben (ich habe alle oben genannten Optionen ausprobiert). Meine einzige Lösung bestand darin, das lokale Repo zu speichern und es von der Fernbedienung aus erneut zu klonen.
Zum Glück hatte ich keine anderen Niederlassungen, die mir etwas bedeuteten.
Die einzige Lösung, die in allen Fällen funktioniert, die ich gesehen habe, ist das Löschen und erneutes Klonen. Vielleicht gibt es einen anderen Weg, aber offensichtlich lässt dieser Weg keine Chance, dass der alte Staat dort zurückbleibt, also bevorzuge ich ihn. Bash One-Liner können Sie als Makro festlegen, wenn Sie Dinge in Git oft durcheinander bringen:
REPO_PATH=$(pwd) && GIT_URL=$(git config --get remote.Origin.url) && cd .. && rm -rf $REPO_PATH && git clone --recursive $GIT_URL $REPO_PATH && cd $REPO_PATH
* geht davon aus, dass Ihre .git-Dateien nicht beschädigt sind