Wie erzwinge ich "Git Pull", um lokale Dateien zu überschreiben?


7184

Wie erzwinge ich ein Überschreiben lokaler Dateien auf a git pull?

Das Szenario ist das folgende:

  • Ein Teammitglied ändert die Vorlagen für eine Website, an der wir arbeiten
  • Sie fügen einige Bilder zum Bilderverzeichnis hinzu (vergessen jedoch, sie unter Quellcodeverwaltung hinzuzufügen).
  • Sie senden mir die Bilder später per Post
  • Ich füge die Bilder unter der Quellcodeverwaltung hinzu und schiebe sie zusammen mit anderen Änderungen an GitHub
  • Sie können keine Updates von GitHub abrufen, da Git ihre Dateien nicht überschreiben möchte.

Dies ist der Fehler, den ich bekomme:

Fehler: Die nicht verfolgte Arbeitsbaumdatei 'public / images / icon.gif' wird durch Zusammenführen überschrieben

Wie zwinge ich Git, sie zu überschreiben? Die Person ist ein Designer - normalerweise löse ich alle Konflikte von Hand, sodass der Server die neueste Version hat, die sie nur auf ihrem Computer aktualisieren müssen.


17
Jeder, der dies liest und denkt, er könnte Dateien verlieren. Ich war in dieser Position und habe festgestellt, dass der Puffer von Sublime Text mich gerettet hat. Wenn ich an etwas arbeite, lösche ich versehentlich alles, indem ich versuche, ein ähnliches Problem zu lösen oder es zu verwenden eine Antwort auf diese Frage und haben die Dateien in Sublime geöffnet (was es eine gute Chance gibt), dann werden die Dateien immer noch dort sein, ist Sublime, entweder nur dort oder in der Rückgängig-Geschichte
Toni Leigh

62
git reset --hard origin/branch_to_overwrite
Andrew Atkinson

1
Grundsätzlich sollten Sie erst nach dem ersten Checkout -b einen Pull-from-Develop ausführen. mach deine Arbeit, dann
drücke

1
Kurze Antwort: Zweig löschen und neu erstellen. 1. Zweig löschen: git branch <branch> -D2. Vor dem Konflikt auf ein Commit zurücksetzen : git reset <commit> --hard3. Zweig neu erstellen: git branch <branch>4. Tracking auf den Server setzen: git --set-upstream-to=origin/<branch> <branch> 5. Pull: git pull`
Nino Filiu

1
Um alle CRLF auf LF-Endungen zu ändern, (sauber starten)git config core.autocrlf false; git ls-files -z | xargs -0 rm; git checkout .
Chloe

Antworten:


10036

Wichtig: Wenn Sie lokale Änderungen haben, gehen diese verloren. Mit oder ohne --hardOption gehen alle lokalen Commits verloren, die nicht gepusht wurden. [*]

Wenn Sie Dateien haben, die nicht von Git verfolgt werden (z. B. hochgeladene Benutzerinhalte), sind diese Dateien nicht betroffen.


Ich denke das ist der richtige Weg:

git fetch --all

Dann haben Sie zwei Möglichkeiten:

git reset --hard origin/master

ODER Wenn Sie sich in einem anderen Zweig befinden:

git reset --hard origin/<branch_name>

Erläuterung:

git fetch lädt das Neueste von der Fernbedienung herunter, ohne zu versuchen, etwas zusammenzuführen oder neu zu starten.

Dann git resetsetzt der Master-Zweig auf das zurück, was Sie gerade abgerufen haben. Die --hardOption ändert alle Dateien in Ihrem Arbeitsbaum so, dass sie mit den Dateien in übereinstimmenorigin/master


Behalten Sie die aktuellen lokalen Commits bei

[*] : Es ist erwähnenswert, dass es möglich ist, aktuelle lokale Commits beizubehalten, indem mastervor dem Zurücksetzen ein Zweig erstellt wird :

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master

Danach bleiben alle alten Commits erhalten new-branch-to-save-current-commits.

Nicht festgeschriebene Änderungen

Nicht festgeschriebene Änderungen (auch inszeniert) gehen jedoch verloren. Stellen Sie sicher, dass Sie alles verstauen und festschreiben, was Sie brauchen. Dazu können Sie Folgendes ausführen:

git stash

Und dann, um diese nicht festgeschriebenen Änderungen erneut anzuwenden:

git stash pop

14
Achtung! Wenn Sie lokale, nicht gepusste Commits haben, werden diese aus Ihrer Filiale entfernt! Diese Lösung hält nicht verfolgte Dateien nicht im Repository intakt, sondern überschreibt alles andere.
Matthijs P

479
Es ist eine beliebte Frage, daher möchte ich den oberen Kommentar hier klarstellen. Ich habe gerade Befehle ausgeführt, wie in dieser Antwort beschrieben, und es wurden nicht ALLE lokalen Dateien entfernt. Nur die remote verfolgten Dateien wurden überschrieben, und jede lokale Datei, die hier war, blieb unberührt.
Red

14
git reset --hard origin/branch-name
Wenn

97
Angesichts der Anzahl der positiven Stimmen für diese Frage und Antwort denke ich, dass Git einen Befehl wiegit pull -f
Sophivorus

7
Commits, die vor dem Hard-Reset nicht gepusht wurden, können mit wiederhergestellt werden git reflog, wobei alle Commits aufgelistet werden, auch solche ohne Basis. Bis Sie Ihre lokale Kopie mit bereinigen git gc, ist alles verloren
Koen.

933

Versuche dies:

git reset --hard HEAD
git pull

Es sollte tun, was Sie wollen.


16
Ich habe dies getan und einige lokale Dateien, die nicht mehr im Repo waren, wurden auf der Festplatte belassen.
Piotr Owsiak

26
Ich denke nicht, dass dies richtig ist. Das Obige führt eine Zusammenführung durch, nicht ein Überschreiben, das in der Frage angefordert wurde: "Wie kann man Git zwingen, sie zu überschreiben?" Ich habe keine Antwort, ich suche gerade danach. Im Moment wechsle ich zum Zweig mit dem Code, den ich behalten möchte. "Git checkout BranchWithCodeToKeep", dann "git branch -D BranchToOverwrite" und schließlich "git checkout -b BranchToOverwrite". Sie haben jetzt den genauen Code von BranchWithCodeToKeep für den Zweig BranchToOverwrite, ohne eine Zusammenführung durchführen zu müssen.
Felbus

252
Anstatt mit 'git pull' zu verschmelzen, versuchen Sie git fetch --all gefolgt von 'git reset --hard origin / master'
Lloyd Moore

5
Ja, die @ lloydmoore-Lösung hat bei mir funktioniert. Könnte eher eine Antwort als nur ein Kommentar sein.
Max Williams

2
Dadurch werden die aktuellen Änderungen auf das zuletzt gezogene Branch Commit zurückgesetzt. Dann führt git pull die Änderungen aus dem letzten Zweig zusammen. Dies tat genau das, was ich wollte. Danke!
Codeversed

459

WARNUNG: git cleanLöscht alle nicht verfolgten Dateien / Verzeichnisse und kann nicht rückgängig gemacht werden.


Manchmal clean -fhilft es einfach nicht. Falls Sie DIRECTORIES nicht mehr verfolgt haben, wird auch die Option -d benötigt:

# WARNING: this can't be undone!

git reset --hard HEAD
git clean -f -d
git pull

WARNUNG: git cleanLöscht alle nicht verfolgten Dateien / Verzeichnisse und kann nicht rückgängig gemacht werden.

Erwägen Sie zuerst die Verwendung des Flags -n( --dry-run). Dies zeigt Ihnen, was gelöscht wird, ohne etwas zu löschen:

git clean -n -f -d

Beispielausgabe:

Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...

33
Genial ... lief dies gegen mein Dotfiles-Repo ... In meinem Home-Verzeichnis. Gut, dass ich dort eigentlich nichts Wichtiges hatte ...
Lauri

7
Ich denke, die Beschreibung des Szenarios macht deutlich, dass er den Inhalt nicht wirklich wegwerfen möchte. Vielmehr will er aufhören, die Dateien zu überschreiben. @Lauri, das hätte dir nicht passieren dürfen. Leider scheinen die Leute das Wesentliche der Szenariobeschreibung falsch verstanden zu haben - siehe meinen Vorschlag.
Igel

19
ENDLICH . git clean -f -d ist praktisch, wenn make clean nicht alles reinigt.
EarthmeLon

7
@crizCraig, es sei denn, sie werden hinzugefügt in.gitignore
Bleeding Fingers

5
@earthmeLon, dafür möchten Sie vielleicht git clean -dfx. Der -xignoriert .gitignore. Normalerweise befinden sich Ihre Build-Produkte in .gitignore.
Paul Draper

384

Wie Igel finde ich die Antworten schrecklich. Aber obwohl Hedgehogs Antwort vielleicht besser ist, denke ich nicht, dass es so elegant ist, wie es sein könnte. Die Art und Weise, wie ich dies fand, war die Verwendung von "Abrufen" und "Zusammenführen" mit einer definierten Strategie. Dadurch sollten Ihre lokalen Änderungen erhalten bleiben, solange sie nicht zu den Dateien gehören, mit denen Sie ein Überschreiben erzwingen möchten.

Machen Sie zuerst ein Commit Ihrer Änderungen

 git add *
 git commit -a -m "local file server commit message"

Rufen Sie dann die Änderungen ab und überschreiben Sie sie, wenn ein Konflikt vorliegt

 git fetch origin master
 git merge -s recursive -X theirs origin/master

"-X" ist ein Optionsname und "ihrer" ist der Wert für diese Option. Sie verwenden "ihre" Änderungen anstelle von "Ihren" Änderungen, wenn ein Konflikt vorliegt.


56
Dies ist die beste Antwort, die ich bisher gesehen habe. Ich habe es nicht ausprobiert, aber im Gegensatz zu anderen Antworten versucht dies nicht, alle Ihre nicht verfolgten Dateien zu zerstören, was aus offensichtlichen Gründen sehr gefährlich ist.
Huyz

5
Das Gleiche gilt für mich, als ich eine sehr große Zusammenführung (GitHub-Pull-Anfrage) durchführte, bei der ich alles zusätzlich zu dem, was ich hatte, akzeptieren wollte. Gute Antwort! In meinem Fall waren die letzten beiden Befehle: 1) get fetch other-repo; 2)git merge -s recursive -X theirs other-repo/master
quux00

2
Dadurch werden Konflikte mit den Repositorys und nicht mit Ihren lokalen Dateien überschrieben. Richtig?
Nathan F.

2
Beste Antwort. Die am höchsten akzeptierte Antwort ließ mich in meinem Fall auf losgelöstem Kopf zurück. Ich wechselte zurück zur örtlichen Hauptniederlassung und liefgit merge -X theirs origin/master
Petergus

2
Das Problem bei dieser (ausgezeichneten) Antwort ist, dass alle lokalen Dateien hinzugefügt werden, was manchmal nicht das ist, was Sie wollen. Möglicherweise möchten Sie nur die spezifischen Dateien hinzufügen, die weggelassen wurden. Aber das Beste daran ist, dass er das tut, was er hätte tun sollen - sie lokal hinzufügen. Sie werden wahrscheinlich die Strategie -X nicht benötigen, da sie das gleiche Image haben. Tatsächlich würde ich vorschlagen, es zuerst wegzulassen, nur um herauszufinden, ob es irgendwelche Anomalien gibt, und es hinzuzufügen, wenn es solche gibt, nachdem überprüft wurde, dass "ihre" immer die richtige Wahl ist. Aber dann bin ich paranoid.
Bob Kerns

279

Anstatt zu tun:

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

Ich würde empfehlen, Folgendes zu tun:

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

Sie müssen nicht alle Fernbedienungen und Zweige abrufen, wenn Sie auf den Ursprungs- / Hauptzweig zurücksetzen möchten, oder?


3
Ihre Antwort ist genau das, was Sie für Ihren Repräsentanten brauchten. Ich muss fragen, entfernt dies auch alle nicht verfolgten Dateien?
Nicolas De Jay

5
Ja, der größte Teil meines Vertreters kommt von hier :) Dadurch werden auch alle nicht verfolgten Dateien entfernt. Etwas, das ich vergessen hatte und an das ich vor 2 Tagen schmerzhaft erinnert wurde ...
Johanneke

1
Siehe die Kommentare zu dieser anderen Antwort: stackoverflow.com/a/8888015/2151700
Johanneke

Dadurch wurden meine nicht verfolgten Dateien nicht entfernt. Das ist eigentlich das, was ich erwarten würde. Gibt es einen Grund für manche Menschen und nicht für andere?
Arichards

Nicht verfolgte Dateien sind vom Zurücksetzen des Git nicht betroffen. Wenn Sie möchten, dass sie auch entfernt werden, tun Sie dies git add .zuerst, bevorgit reset --hard
Johanneke

131

Es sieht so aus, als wäre es am besten, zuerst Folgendes zu tun:

git clean

Um alle nicht verfolgten Dateien zu löschen und dann mit den üblichen git pull...


4
Ich habe versucht, das gleiche Problem mit "git clean" zu lösen, aber es wurde nicht behoben. Der Git-Status lautet "Ihr Zweig und 'Ursprung / Master' sind auseinander gegangen, # und haben jeweils 2 und 9 verschiedene Commits." und git pull sagt etwas ähnliches wie oben.
Slacy

43
git clean ist ein ziemlich stumpfes Instrument und könnte viele Dinge wegwerfen, die Sie vielleicht behalten möchten. Es ist besser, die Dateien, über die sich git beschwert, zu entfernen oder umzubenennen, bis der Pull erfolgreich ist.
Neil Mayhew

2
Ich denke nicht, dass dies im Allgemeinen funktioniert. Gibt es nicht eine Möglichkeit, eine Git-Klon-Fernbedienung über einen erzwungenen Git-Pull durchzuführen?
Mathtick

10
@mathick:git fetch origin && git reset --hard origin/master
Arrowmaster

3
Ist git cleandie beste Antwort hier? Das Entfernen von Dateien scheint nicht unbedingt das zu sein, was das OP will. Sie baten um "Überschreiben lokaler Dateien", nicht um Löschen.
JohnAllen

111

Warnung: Wenn Sie dies tun, werden Ihre Dateien dauerhaft gelöscht, wenn Ihre gitignore-Datei Verzeichnis- / * -Einträge enthält.

Einige Antworten scheinen schrecklich zu sein. Schrecklich im Sinne dessen, was mit @Lauri passiert ist, wenn man dem Vorschlag von David Avsajanishvili folgt.

Eher (git> v1.7.6):

git stash --include-untracked
git pull

Später können Sie den Stash-Verlauf bereinigen.

Manuell eins nach dem anderen:

$ git stash list
stash@{0}: WIP on <branch>: ...
stash@{1}: WIP on <branch>: ...

$ git stash drop stash@{0}
$ git stash drop stash@{1}

Brutal auf einmal:

$ git stash clear

Natürlich, wenn Sie zu dem zurückkehren möchten, was Sie versteckt haben:

$ git stash list
...
$ git stash apply stash@{5}

2
Nein, das glaube ich nicht. Durch das Verstauen werden nur nicht festgeschriebene Dateien aus dem Weg geräumt. Das oben Gesagte verschiebt (versteckt) auch Dateien, die git nicht verfolgt. Dies verhindert, dass Dateien, die der Fernbedienung hinzugefügt wurden, die noch nicht auf Ihren Computer heruntergezogen wurden - aber die Sie erstellt haben (!) -, heruntergezogen werden. Alles ohne die unverbindliche Arbeit zu zerstören. Hoffe das macht Sinn?
Igel

3
Wenn Sie nicht über 1.7.6 verfügen, können Sie dies --include-untrackedeinfach nachahmen , indem Sie git addIhr gesamtes Repo vorübergehend speichern und es dann sofort verstauen.
Nategood

3
Ich stimme Hedgehog zu. Wenn Sie hier die populären Antworten geben, werden Sie höchstwahrscheinlich feststellen, dass Sie versehentlich eine Menge Dinge getötet haben, die Sie nicht wirklich verlieren wollten.
Guardius

1
Ich hatte andere nicht verfolgte Dateien - außer der, die das Zusammenführen / Ziehen überschreiben wollte, sodass diese Lösung am besten funktionierte. git stash applybrachte alle meine nicht verfolgten Dateien mit der Ausnahme (zu Recht) derjenigen zurück, die die Zusammenführung bereits erstellt hatte: "existiert bereits, keine Kasse." Hat perfekt funktioniert.
BigBlueHat

2
Dies ist die sauberste Antwort und sollte die akzeptierte sein. Um einige Eingaben zu speichern, können Sie die Kurzform verwenden : git stash -u.
ccpizza

93

Dieser Befehl kann hilfreich sein, um lokale Änderungen zu verwerfen:

git checkout <your-branch> -f

Führen Sie dann eine Bereinigung durch (entfernt nicht verfolgte Dateien aus dem Arbeitsbaum):

git clean -f

Wenn Sie nicht verfolgte Verzeichnisse zusätzlich zu nicht verfolgten Dateien entfernen möchten:

git clean -fd

Ich denke, die Beschreibung des Szenarios macht deutlich, dass er den Inhalt nicht wirklich wegwerfen möchte. Vielmehr will er aufhören, die Dateien zu überschreiben. Siehe meinen Vorschlag.
Igel

3
Obwohl diese Antwort möglicherweise nicht genau zur Beschreibung passt, hat sie mich dennoch vor der Frustration bewahrt, dass Git mit den Wagenrückläufen herumgespielt hat (Ereignis mit autocrlf false). Wenn git reset --hard HEAD keine "keine" geänderten Dateien hinterlässt, sind diese "-f" -Flaggen sehr hilfreich. Vielen Dank.
Kellindil

88

git pullVersuchen Sie Folgendes , anstatt mit zu verschmelzen :

git fetch --all

gefolgt von:

git reset --hard origin/master.


61

Das einzige, was für mich funktioniert hat, war:

git reset --hard HEAD~5

Dies bringt Sie fünf Commits zurück und dann mit

git pull

Ich fand das, indem ich nachschaute, wie man eine Git-Zusammenführung rückgängig macht .


Dies war es, was letztendlich für mich funktionierte, da ich meinen Zweig zwangsweise zum Ursprungs-Repo geschoben hatte und immer wieder Zusammenführungskonflikte bekam, wenn ich versuchte, ihn auf mein Remote-Repo zu ziehen.
jwfrench

Hallo, eigentlich ist das ein Trick für einen work aroundaber wirklich effektiven. Da einige Konflikte nur in wenigen Commits auftreten können, wird durch das Zurücksetzen von 5 Commits sichergestellt, dass keine Konflikte mit Remotecode auftreten.
Hoang Le

54

Das Problem bei all diesen Lösungen ist, dass sie entweder alle zu komplex sind oder, ein noch größeres Problem, dass sie alle nicht verfolgten Dateien vom Webserver entfernen, was wir nicht wollen, da immer benötigte Konfigurationsdateien aktiv sind der Server und nicht im Git-Repository.

Hier ist die sauberste Lösung, die wir verwenden:

# Fetch the newest code
git fetch

# Delete all files which are being added, so there
# are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done

# Finally pull all the changes
# (you could merge as well e.g. 'merge origin/master')
git pull
  • Der erste Befehl ruft die neuesten Daten ab.

  • Der zweite Befehl prüft, ob Dateien zum Repository hinzugefügt werden, und löscht die nicht verfolgten Dateien aus dem lokalen Repository, die Konflikte verursachen würden.

  • Der dritte Befehl checkt alle Dateien aus, die lokal geändert wurden.

  • Schließlich versuchen wir, auf die neueste Version zu aktualisieren, diesmal jedoch ohne Konflikte, da nicht verfolgte Dateien, die sich im Repo befinden, nicht mehr vorhanden sind und alle lokal geänderten Dateien bereits dieselben wie im Repository sind.


Die Verwendung von "Git Merge Origin / Master" als letzte Zeile (wie Sie in Ihrer Notiz sagen) anstelle von "Git Pull" ist schneller, da Sie bereits alle Änderungen aus dem Git Repo entfernt haben.
Josh

1
Ja natürlich, git merge origin/masterwird schneller und wahrscheinlich noch sicherer. Da, wenn jemand beim Entfernen von Dateien dieses Skripts neue Änderungen vorgenommen hat (was wahrscheinlich nicht möglich, aber möglich ist), kann der gesamte Pull fehlschlagen. Der einzige Grund, den ich pulldort eingegeben habe, ist, dass möglicherweise nicht jemand am Hauptzweig arbeitet, sondern an einem anderen Zweig, und ich wollte, dass das Skript universell ist.
Strahinja Kustudic

Wenn Sie lokal erstellte Dateien wie Optionsdateien erstellt haben, fügen Sie diese ein .gitignore.
Sebi

52

Versuchen Sie zunächst den Standardweg:

git reset HEAD --hard # To remove all not committed changes!
git clean -fd         # To remove all untracked (non-git) files and folders!

Warnung : Die oben genannten Befehle können nur dann zum Verlust von Daten / Dateien führen, wenn Sie sie nicht festgeschrieben haben! Wenn Sie sich nicht sicher sind, erstellen Sie zuerst die Sicherung Ihres gesamten Repository-Ordners.

Dann ziehen Sie es wieder.

Wenn das oben Gesagte nicht hilft und Sie sich nicht um Ihre nicht verfolgten Dateien / Verzeichnisse kümmern (machen Sie zuerst die Sicherung für alle Fälle), versuchen Sie die folgenden einfachen Schritte:

cd your_git_repo  # where 'your_git_repo' is your git repository folder
rm -rfv *         # WARNING: only run inside your git repository!
git pull          # pull the sources again

Dadurch werden alle Git-Dateien ENTFERNT (Ausnahmeverzeichnis .git/, in dem Sie alle Commits haben) und erneut abgerufen .


Warum git reset HEAD --hardkönnte in einigen Fällen scheitern?

  1. Benutzerdefinierte Regeln in .gitattributes file

    Eine eol=lfRegel in .gitattributes kann dazu führen, dass git einige Dateiänderungen ändert, indem CRLF-Zeilenenden in einigen Textdateien in LF konvertiert werden.

    In diesem Fall müssen Sie diese CRLF / LF-Änderungen festschreiben (indem Sie sie überprüfen git status) oder versuchen git config core.autcrlf false, sie vorübergehend zu ignorieren.

  2. Inkompatibilität des Dateisystems

    Wenn Sie ein Dateisystem verwenden, das keine Berechtigungsattribute unterstützt. Beispiel: Sie haben zwei Repositorys, eines unter Linux / Mac ( ext3/ hfs+) und eines unter FAT32 / NTFS-basiertem Dateisystem.

    Wie Sie bemerken, gibt es zwei verschiedene Arten von Dateisystemen, sodass dasjenige, das keine Unix-Berechtigungen unterstützt, die Dateiberechtigungen auf einem System, das diese Art von Berechtigungen nicht unterstützt, grundsätzlich nicht zurücksetzen kann, also egal wie --hardSie es versuchen, git Erkennen Sie immer einige "Änderungen".


47

Ich hatte das gleiche Problem. Niemand hat mir diese Lösung gegeben, aber sie hat bei mir funktioniert.

Ich habe es gelöst durch:

  1. Löschen Sie alle Dateien. Verlasse nur das .gitVerzeichnis.
  2. git reset --hard HEAD
  3. git pull
  4. git push

Jetzt funktioniert es.


1
Hier gilt das gleiche. Manchmal funktioniert nur die sehr harte Lösung, es kommt oft vor, dass nur Zurücksetzen und Reinigen irgendwie nicht ausreichen ...
Jdehaan

41

Bonus:

Wenn ich in den vorherigen Antworten von Pull / Fetch / Merge spreche, möchte ich einen interessanten und produktiven Trick teilen:

git pull --rebase

Dieser obige Befehl ist der nützlichste Befehl in meinem Git-Leben, der viel Zeit gespart hat.

Versuchen Sie diesen Befehl, bevor Sie Ihr neues Commit auf den Server übertragen. Es synchronisiert automatisch die neuesten Serveränderungen (mit einem Abruf + Zusammenführen) und platziert Ihr Commit oben im Git-Protokoll. Sie müssen sich keine Gedanken über manuelles Ziehen / Zusammenführen machen.

Details finden Sie unter Was macht "git pull --rebase"? .


3
Kurzum : git pull -r.
Kenorb

29

Ich hatte ein ähnliches Problem. Ich musste das machen:

git reset --hard HEAD
git clean -f
git pull

6
Verwendung nur git cleanmit Vorsicht
nategood

29

Ich habe andere Antworten zusammengefasst. Sie können git pullfehlerfrei ausführen :

git fetch --all
git reset --hard origin/master
git reset --hard HEAD
git clean -f -d
git pull

Warnung : Dieses Skript ist sehr leistungsfähig, sodass Sie Ihre Änderungen verlieren können.


2
Dadurch werden geänderte Dateien (zuvor eingecheckte Dateien) überschrieben und nicht verfolgte Dateien (Dateien, die noch nie eingecheckt wurden) entfernt. Genau das, wonach ich gesucht habe, danke!
Styfle

3
Ich vermute, dass die dritte Zeile git reset --hard HEADüberflüssig ist. Meine lokale Manpage (2.6.3) sagt, dass resetin der zweiten Zeile git reset --hard origin/master "standardmäßig HEAD in allen Formen" verwendet wird.
Arichards

2
@arichards Ich denke, Ihr Verdächtiger hat Recht, aber wenn die zweite Zeile (aus irgendeinem Grund) nicht funktioniert, funktioniert die dritte Zeile gut zum Zurücksetzen. Diese Lösung muss nicht optimiert werden. Ich habe gerade andere Antworten zusammengefasst. Das ist alles. Danke für deinen Kommentar. :)
Robert Moon

28

Aufgrund meiner eigenen ähnlichen Erfahrungen ist die von Strahinja Kustudic oben angebotene Lösung bei weitem die beste. Wie andere bereits betont haben, werden durch einfaches Zurücksetzen alle Elemente entfernt nicht verfolgten Dateien entfernt, die viele Dinge enthalten können, die Sie nicht entfernen möchten, z. B. Konfigurationsdateien. Was sicherer ist, ist, nur die Dateien zu entfernen, die hinzugefügt werden sollen. In diesem Fall möchten Sie wahrscheinlich auch alle lokal geänderten Dateien auschecken, die aktualisiert werden sollen.

Vor diesem Hintergrund habe ich Kustudics Skript aktualisiert, um genau das zu tun. Ich habe auch einen Tippfehler behoben (ein Fehlen im Original).

#/bin/sh

# Fetch the newest code
git fetch

# Delete all files which are being added,
# so there are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    echo "Deleting untracked file $file..."
    rm -vf "$file"
done

# Checkout all files which have been locally modified
for file in `git diff HEAD..origin/master --name-status | awk '/^M/ {print $2}'`
do
    echo "Checking out modified file $file..."
    git checkout $file
done

# Finally merge all the changes (you could use merge here as well)
git pull

Die Verwendung von "Git Merge Origin / Master" als letzte Zeile (wie Sie in Ihrer Notiz sagen) anstelle von "Git Pull" ist schneller, da Sie bereits alle Änderungen aus dem Git Repo entfernt haben.
Josh

Das Auschecken geänderter Dateien ist erforderlich, sodass dies zu 100% funktioniert. Ich habe mein Skript damit vor langer Zeit aktualisiert, aber auch hier vergessen, es zu aktualisieren. Ich benutze es auch ein bisschen anders als du. Ich checke Dateien aus, die irgendeine Art von Modifikation haben, nicht nur M, damit es die ganze Zeit funktioniert.
Strahinja Kustudic

24

Ich glaube, es gibt zwei mögliche Konfliktursachen, die separat gelöst werden müssen, und soweit ich das beurteilen kann, befasst sich keine der obigen Antworten mit beiden:

  • Lokale Dateien, die nicht verfolgt werden, müssen entweder manuell (sicherer) oder wie in anderen Antworten vorgeschlagen von gelöscht werden git clean -f -d

  • Lokale Commits, die sich nicht in der Remote-Verzweigung befinden, müssen ebenfalls gelöscht werden. IMO ist der einfachste Weg, dies zu erreichen, mit: git reset --hard origin/master(Ersetzen Sie 'master' durch den Zweig, an dem Sie arbeiten, und führen Sie einen git fetch originersten aus.)


22

Ein einfacher Weg wäre:

git checkout --theirs /path/to/file.extension
git pull origin master

Dadurch wird Ihre lokale Datei mit der Datei auf Git überschrieben


21

Es scheint, dass sich die meisten Antworten hier auf den masterZweig konzentrieren; Es gibt jedoch Zeiten, in denen ich an zwei verschiedenen Stellen an demselben Feature-Zweig arbeite und ich möchte, dass sich eine Rebase in einer in der anderen widerspiegelt, ohne dass viel durch die Reifen gesprungen wird.

Basierend auf einer Kombination von Antwort der RNA und torek Antwort auf eine ähnliche Frage , ich habe mit diesem kommen , die hervorragend funktioniert:

git fetch
git reset --hard @{u}

Führen Sie dies von einem Zweig aus und es wird nur Ihr lokaler Zweig auf die Upstream-Version zurückgesetzt.

Dies kann auch gut in einen Git-Alias ​​( git forcepull) eingefügt werden:

git config alias.forcepull "!git fetch ; git reset --hard @{u}"

Oder in Ihrer .gitconfigDatei:

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"

Genießen!


Diese Antwort ist auch schön, weil sie funktioniert, unabhängig davon, auf welchem ​​Zweig Sie sich befinden!
Blattmehl

19

Ich hatte das gleiche Problem und aus irgendeinem Grund git clean -f -dwürde es sogar ein nicht tun. Hier ist der Grund: Aus irgendeinem Grund, wenn Ihre Datei von Git ignoriert wird (ich nehme an, über einen .gitignore-Eintrag), stört es immer noch, dies mit einem späteren Pull zu überschreiben , aber eine Bereinigung wird sie nicht entfernen, es sei denn, Sie fügen hinzu -x.


19

Ich kenne eine viel einfachere und weniger schmerzhafte Methode:

$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

Das ist es!


18

Ich habe das gerade selbst gelöst durch:

git checkout -b tmp # "tmp" or pick a better name for your local changes branch
git add -A
git commit -m 'tmp'
git pull
git checkout master # Or whatever branch you were on originally
git pull
git diff tmp

Dabei gibt der letzte Befehl eine Liste Ihrer lokalen Änderungen an. Ändern Sie den Zweig "tmp" so lange, bis er akzeptabel ist, und fügen Sie ihn dann wieder auf den Master ein mit:

git checkout master && git merge tmp

Für das nächste Mal können Sie dies wahrscheinlich sauberer handhaben, indem Sie nach "git stash branch" suchen, obwohl stash bei den ersten Versuchen wahrscheinlich Probleme verursacht. Experimentieren Sie also zuerst mit einem unkritischen Projekt ...


17

Ich habe eine seltsame Situation, die weder funktioniert git cleannoch git resetfunktioniert. Ich muss die widersprüchliche Datei entfernen, git indexindem ich für jede nicht verfolgte Datei das folgende Skript verwende:

git rm [file]

Dann kann ich ganz gut ziehen.


16

git fetch --all && git reset --hard origin/master && git pull


14

Trotz der ursprünglichen Frage können die häufigsten Antworten Probleme für Personen verursachen, die ein ähnliches Problem haben, aber ihre lokalen Dateien nicht verlieren möchten. Siehe zum Beispiel die Kommentare von Al-Punk und crizCraig.

In der folgenden Version werden Ihre lokalen Änderungen in einen temporären Zweig ( tmp) übernommen, der ursprüngliche Zweig (von dem ich annehme master) ausgecheckt und die Aktualisierungen zusammengeführt. Sie könnten dies mit tun stash, aber ich habe festgestellt, dass es normalerweise einfacher ist, einfach den Branch / Merge-Ansatz zu verwenden.

git checkout -b tmp
git add *; git commit -am "my temporary files"
git checkout master

git fetch origin master
git merge -s recursive -X theirs origin master

wo wir das übernehmen andere Repository ist origin master.


13

Diese vier Befehle funktionieren für mich.

git reset --hard HEAD
git checkout origin/master
git branch -D master
git checkout -b master

Zum Überprüfen / Ziehen nach Ausführung dieser Befehle

git pull origin master

Ich habe viel versucht, aber schließlich Erfolg mit diesen Befehlen.


2
"git branch -D master" löscht den Zweig. Also sei vorsichtig damit. Ich bevorzuge die Verwendung von "git checkout origin / master -b <Name des neuen Zweigs>", um einen neuen Zweig mit einem neuen Namen zu erstellen, und Sie benötigen 3,4 Zeilen. Es wird auch empfohlen, auch "git clean -f" zu verwenden.
Chand Priyankara

13

Mach einfach

git fetch origin branchname
git checkout -f origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge origin/branchname

So vermeiden Sie alle unerwünschten Nebenwirkungen wie das Löschen von Dateien oder Verzeichnissen, die Sie behalten möchten usw.


12

Setzen Sie den Index und den Kopf auf zurück origin/master, aber setzen Sie den Arbeitsbaum nicht zurück:

git reset origin/master

Ich persönlich fand das am nützlichsten. Anschließend bleibt Ihr Arbeitsbaum erhalten, sodass Sie ihn erneut einchecken können. Bei meinem Problem wurden dieselben Dateien gelöscht wie beim Hinzufügen, sodass sie nicht mehr funktionieren. Seltsam, ich weiß.
Jason Sebring

12

Bedarf:

  1. Verfolgen Sie lokale Änderungen, damit niemand hier sie jemals verliert.
  2. Stellen Sie sicher, dass das lokale Repository mit dem Remote-Ursprungs-Repository übereinstimmt.

Lösung:

  1. Verstecken Sie die lokalen Änderungen.
  2. Fetch mit einem sauberen von Dateien und Verzeichnissen zu ignorieren .gitignore und Hard - Reset auf Herkunft .

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.