Wie erzwinge ich das Überschreiben lokaler Dateien in einem git pull
?
Das Szenario ist folgendes:
Dies ist der Fehler, den ich bekomme:
fehler: 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, so dass der Server über die neueste Version verfügt, die er nur auf seinem Computer aktualisieren muss.
--hard
-Option gehen alle nicht übertragenen lokalen Commits verloren.[*]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 einer anderen Branche befinden:
git reset --hard Origin/<branch_name>
git fetch
lädt die neuesten Daten aus der Ferne herunter, ohne zu versuchen, etwas zusammenzuführen oder neu zu registrieren.
Dann setzt git reset
den Hauptzweig 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/master
übereinstimmen.
[*]: Es ist erwähnenswert, dass es möglich ist, aktuelle lokale Commits beizubehalten, indem vor dem Zurücksetzen ein Zweig aus master
erstellt wird:
git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard Origin/master
Danach werden alle alten Commits in new-branch-to-save-current-commits
gespeichert.
Nicht festgeschriebene Änderungen gehen jedoch verloren (auch nicht vollständig). Stellen Sie sicher, dass Sie alles unterbringen, was Sie brauchen. Dafür können Sie Folgendes ausführen:
git stash
Und dann diese unverbindlichen Änderungen erneut anwenden:
git stash pop
Versuche dies:
git reset --hard HEAD
git pull
Es sollte tun, was Sie wollen.
WARNUNG: git clean
löscht alle Ihre nicht protokollierten Dateien/Verzeichnisse und kann nicht rückgängig gemacht werden.
Manchmal hilft nur clean -f
nicht. Falls Sie DIRECTORIES nicht erfasst haben, benötigte die Option -d zusätzlich:
# WARNING: this can't be undone!
git reset --hard HEAD
git clean -f -d
git pull
WARNUNG: git clean
löscht alle Ihre Dateien/Verzeichnisse und kann nicht rückgängig gemacht werden.
Verwenden Sie zuerst das Flag -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
...
Wie Igel finde ich die Antworten schrecklich. Aber obwohl Igels Antwort vielleicht besser ist, denke ich nicht, dass sie so elegant ist, wie sie sein könnte. Die Methode, die ich dazu gefunden habe, ist die Verwendung von "Abrufen" und "Zusammenführen" mit einer definierten Strategie. Dies sollte dazu führen, dass Ihre lokalen Änderungen erhalten bleiben, solange sie nicht zu den Dateien gehören, mit denen Sie ein Überschreiben erzwingen möchten.
git add *
git commit -a -m "local file server commit message"
git fetch Origin master
git merge -s recursive -X theirs Origin/master
"-X" ist ein Optionsname und "Ihre" ist der Wert für diese Option. Sie wählen "ihre" Änderungen und nicht "Ihre" Änderungen, wenn ein Konflikt vorliegt.
Statt zu tun:
git fetch --all
git reset --hard Origin/master
Ich würde folgendes empfehlen:
git fetch Origin master
git reset --hard Origin/master
Sie müssen nicht alle Fernbedienungen und Verzweigungen abrufen, wenn Sie zum Ursprungs-/Hauptzweig zurückkehren möchten, oder?
Es sieht so aus, als wäre der beste Weg, zuerst zu tun:
git clean
Löschen Sie alle nicht protokollierten Dateien und fahren Sie dann mit dem üblichen git pull
... fort.
Wenn Sie Verzeichnisse/* in Ihrer Gititore-Datei haben, werden Ihre Dateien dauerhaft gelöscht.
Einige Antworten scheinen schrecklich zu sein. Schrecklich im Sinne dessen, was @Lauri mit dem Vorschlag von David Avsajanishvili folgte.
Eher (git> v1.7.6):
git stash --include-untracked
git pull
Später können Sie die Vorratshistorie löschen.
Manuell, eins nach dem anderen:
$ git stash list
[email protected]{0}: WIP on <branch>: ...
[email protected]{1}: WIP on <branch>: ...
$ git stash drop [email protected]{0}
$ git stash drop [email protected]{1}
Brutal, alles auf einmal:
$ git stash clear
Natürlich, wenn Sie zu dem zurückkehren möchten, was Sie gespeichert haben:
$ git stash list
...
$ git stash apply [email protected]{5}
Dieser Befehl könnte hilfreich sein, um lokale Änderungen zu verwerfen:
git checkout <your-branch> -f
Führen Sie dann eine Bereinigung durch (entfernt nicht aufgespürte Dateien aus dem Arbeitsbaum):
git clean -f
Wenn Sie nicht protokollierte Verzeichnisse zusätzlich zu nicht protokollierten Dateien entfernen möchten:
git clean -fd
Versuchen Sie Folgendes, anstatt mit git pull
zu verschmelzen:
git fetch --all
gefolgt von:
git reset --hard Origin/master
.
Das einzige, was für mich funktionierte, war:
git reset --hard HEAD~5
Dies bringt Sie fünf Commits zurück und dann mit
git pull
Ich fand das, indem ich nachschlug, wie man eine Git merge rückgängig macht.
Das Problem bei all diesen Lösungen ist, dass sie entweder zu komplex sind, oder ein noch größeres Problem ist, dass sie alle nicht protokollierten Dateien vom Webserver entfernen, was wir nicht möchten, da immer Konfigurationsdateien vorhanden 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 protokollierten Dateien aus dem lokalen Repository, wodurch Konflikte verursacht werden.
Der dritte Befehl checkt alle Dateien aus, die lokal geändert wurden.
Zum Abschluss führen wir ein Update auf die neueste Version durch, diesmal jedoch ohne Konflikte, da nicht im Repo enthaltene Dateien nicht mehr vorhanden sind und alle lokal modifizierten Dateien bereits mit denen im Repository identisch sind.
Ich hatte das gleiche Problem. Niemand hat mir diese Lösung gegeben, aber es hat für mich funktioniert.
Ich habe es gelöst durch:
.git
.git reset --hard HEAD
git pull
git Push
Jetzt gehts.
Versuchen Sie zunächst die Standardmethode:
git reset HEAD --hard # To remove all not committed changes!
git clean -fd # To remove all untracked (non-git) files and folders!
Warnung : Obige Befehle können nur dann zum Verlust von Daten/Dateien führen, wenn sie nicht festgeschrieben sind! Wenn Sie sich nicht sicher sind, erstellen Sie zuerst die Sicherung Ihres gesamten Repository-Ordners.
Dann ziehen Sie es noch einmal.
Wenn oben nichts hilft und Sie sich nicht für Ihre nicht protokollierten Dateien/Verzeichnisse interessieren (machen Sie das Backup zuerst für den Fall), führen Sie die folgenden einfachen Schritte aus:
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
Dies wird alle Git-Dateien entfernen (excempt .git/
dir, wo Sie alle Commits haben) und ziehen es erneut.
Warum könnte git reset HEAD --hard
in einigen Fällen fehlschlagen?
Benutzerdefinierte Regeln in .gitattributes file
Die eol=lf
-Regel in .gitattributes kann dazu führen, dass git einige Dateiänderungen ändert, indem in einigen Textdateien CRLF-Zeilenenden in LF konvertiert werden.
Wenn dies der Fall ist, müssen Sie diese CRLF/LF-Änderungen festschreiben (indem Sie sie in git status
überprüfen) oder versuchen: git config core.autcrlf false
, um sie vorübergehend zu ignorieren.
Dateisystem-Inkompatibilität
Wenn Sie ein Dateisystem verwenden, das die Berechtigungsattribute nicht unterstützt. In diesem Beispiel haben Sie zwei Repositorys, eines unter Linux/Mac (ext3
/hfs+
) und eines unter einem FAT32/NTFS-basierten Dateisystem.
Wie Sie feststellen, gibt es zwei verschiedene Arten von Dateisystemen. Das Dateisystem, das keine Unix-Berechtigungen unterstützt, kann die Dateiberechtigungen auf einem System, das diese Art von Berechtigungen nicht unterstützt, grundsätzlich nicht zurücksetzen. Egal wie --hard
Sie versuchen, git erkennt immer einige "änderungen".
Wenn ich in den vorherigen Antworten von Pull/Fetch/Merge spreche, möchte ich einen interessanten und produktiven Trick teilen:
git pull --rebase
Dieser Befehl ist der nützlichste Befehl in meinem Git-Leben, der viel Zeit gespart hat.
Bevor Sie Ihr neues Commit auf den Server pushen, probieren Sie diesen Befehl aus, um die neuesten Serveränderungen (mit Abruf + Zusammenführen) automatisch zu synchronisieren und Ihr Commit ganz oben im Git-Protokoll zu platzieren. Manuelles Ziehen/Zusammenführen ist nicht nötig.
Details finden Sie in Was macht "git pull --rebase"?.
Ich hatte ein ähnliches Problem. Ich musste das tun:
git reset --hard HEAD
git clean -f
git pull
Ich habe andere Antworten zusammengefasst. Sie können git pull
ohne Fehler 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 mächtig, so dass Sie Ihre Änderungen verlieren könnten.
Aufgrund meiner eigenen ähnlichen Erfahrungen ist die von Strahinja Kustudic angebotene Lösung bei weitem die beste. Wie andere bereits erwähnt haben, werden durch das Zurücksetzen der Hardware alle die nicht protokollierten Dateien entfernt, die viele Dinge enthalten könnten, die Sie nicht entfernen möchten, z. B. Konfigurationsdateien. Sicherer ist es, nur die Dateien zu entfernen, die gerade hinzugefügt werden, und aus diesem Grund möchten Sie wahrscheinlich auch alle lokal geänderten Dateien, die aktualisiert werden sollen, auschecken.
Vor diesem Hintergrund habe ich Kustudics Skript aktualisiert, um genau das zu tun. Ich habe auch einen Tippfehler behoben (ein "fehlendes" 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
Ich glaube, dass es zwei mögliche Konfliktursachen gibt, die separat gelöst werden müssen, und soweit ich keine der oben genannten Antworten feststellen kann, handelt es sich um beide:
Lokale Dateien, die nicht verfolgt werden, müssen entweder manuell (sicherer) oder wie in anderen Antworten vorgeschlagen durch git clean -f -d
gelöscht werden.
Lokale Commits, die sich nicht im Remote-Zweig befinden, müssen ebenfalls gelöscht werden. Der einfachste Weg dies zu erreichen, ist IMO mit: git reset --hard Origin/master
(Ersetzen Sie 'master' durch den Zweig, an dem Sie gerade arbeiten, und führen Sie zuerst einen git fetch Origin
aus.)
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
Anscheinend konzentrieren sich die meisten Antworten hier auf den Zweig master
. 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 einem anderen Bereich widerspiegelt.
Basierend auf einer Kombination aus RNAs Antwort und toreks Antwort auf eine ähnliche Frage , habe ich mir das ausgedacht, was hervorragend funktioniert:
git fetch
git reset --hard @{u}
Führen Sie dies von einem Zweig aus aus, und der lokale Zweig wird nur 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 .gitconfig
-Datei:
[alias]
forcepull = "!git fetch ; git reset --hard @{u}"
Genießen!
Ich hatte das gleiche Problem und aus irgendeinem Grund würde ein git clean -f -d
es nicht tun. Hier ist der Grund: Aus irgendeinem Grund, wenn Ihre Datei von Git ignoriert wird (über einen .gitignore-Eintrag, nehme ich an), stört es immer noch das Überschreiben mit einem späteren pull , aber ein clean wird dies nicht entfernen Sie es, wenn Sie nicht -x
hinzufügen.
Ich habe es 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
der letzte Befehl gibt eine Liste der lokalen Änderungen an. Ändern Sie den "tmp" -Zweig so lange, bis er akzeptabel ist, und führen Sie ihn anschließend wieder mit master zusammen:
git checkout master && git merge tmp
Für das nächste Mal können Sie dies wahrscheinlich sauberer behandeln, indem Sie nach "git stash branch" suchen, obwohl stash Ihnen wahrscheinlich bei den ersten Versuchen Probleme bereitet. Versuchen Sie also zunächst, ein unkritisches Projekt zu erstellen ...
Ich habe eine seltsame Situation, die weder git clean
noch git reset
funktioniert. Ich muss die in Konflikt stehende Datei aus git index
entfernen, indem ich für jede nicht aufgezeichnete Datei das folgende Skript verwende:
git rm [file]
Dann kann ich ganz gut ziehen.
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!
Diese vier Befehle funktionieren für mich.
git reset --hard HEAD
git checkout Origin/master
git branch -D master
git checkout -b master
Nach dem Ausführen dieser Befehle prüfen/ziehen
git pull Origin master
Ich habe viel versucht, aber mit diesen Befehlen endlich Erfolg.
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 Nebeneffekte, wie das Löschen von Dateien oder Verzeichnissen, die Sie behalten wollten, usw.
Trotz der ursprünglichen Frage können die ersten Antworten Probleme für Leute verursachen, die ein ähnliches Problem haben, aber ihre lokalen Dateien nicht verlieren möchten. Siehe zum Beispiel Al-Punk und die Kommentare von crizCraig.
Die folgende Version bindet Ihre lokalen Änderungen an einen temporären Zweig (tmp
), prüft den ursprünglichen Zweig (der ich master
nehme) und führt die Aktualisierungen zusammen. Sie könnten dies mit stash
tun, aber ich habe festgestellt, dass es normalerweise einfacher ist, die Verzweigungs-/Zusammenführungsmethode 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 anderes Repository annehmen ist Origin master
.
Setzen Sie den Index und den Kopf auf Origin/master
zurück, setzen Sie den Arbeitsbaum jedoch nicht zurück:
git reset Origin/master
Bedarf:
Lösung:
Fetch mit einem clean von files und Verzeichnissen ignoring .gitignore und hard reset in Origin .
git stash --include-untracked
git fetch --all
git clean -fdx
git reset --hard Origin/master
Ich las alle Antworten durch, suchte aber nach einem einzigen Befehl, um dies zu tun. Hier ist was ich getan habe. Git-Alias zu .gitconfig hinzugefügt
[alias]
fp = "!f(){ git fetch ${1} ${2} && git reset --hard ${1}/${2};};f"
Führen Sie Ihren Befehl als aus
git fp Origin master
gleichwertig
git fetch Origin master
git reset --hard Origin/master
Verwenden Sie nicht git reset --hard
. Dadurch werden die Änderungen gelöscht, was durchaus unerwünscht ist. Stattdessen:
git pull
git reset Origin/master
git checkout <file1> <file2> ...
Sie können natürlich git fetch
anstelle von git pull
verwenden, da es offensichtlich nicht zusammengeführt wird. Wenn Sie jedoch normalerweise ziehen, ist es sinnvoll, hier weiterzuziehen.
Was hier passiert ist also, dass git pull
Ihre Origin/Master-Referenz aktualisiert ; git reset
aktualisiert Ihre lokale Zweigreferenz so, dass er mit Origin/master identisch ist, ohne Dateien zu aktualisieren, sodass Ihr ausgecheckter Status unverändert bleibt; dann git checkout
setzt Dateien nach Bedarf in Ihren lokalen Zweigindex zurück. In den Fällen, in denen genau dieselbe Datei live und im Upstream-Master hinzugefügt wurde, stimmt der Index nach dem Zurücksetzen bereits mit der Datei überein. In diesem Fall müssen Sie git checkout
überhaupt nicht ausführen.
Wenn der Upstream-Zweig auch Commits enthält, die Sie automatisch anwenden möchten, können Sie eine geringfügige Variation des Prozesses verfolgen:
git pull
git merge <commit before problem commit>
git reset <problem commit>
git checkout <file1> <file2> ...
git pull
Dies ist die bewährte Methode, um Änderungen rückgängig zu machen:
git commit
Bestätigen Sie Ihre inszenierten Änderungen, damit sie im - reflog gespeichert werden (siehe unten).git fetch
Ruft die neuesten Upstream-Änderungen abgit reset --hard Origin/master
Hartes Zurücksetzen auf den Origin-HauptzweigDas reflogzeichnet Zweige und andere Referenzen auf, die im lokalen Repository aktualisiert werden. Oder einfach gesagt - der reflog ist der Verlauf Ihrer Änderungen.
Daher ist es immer eine gute Praxis, sich zu verpflichten. Commits werden an den Reflog angehängt, um sicherzustellen, dass Sie den gelöschten Code jederzeit abrufen können.
Ich habe diesen Befehl verwendet, um die lokalen Dateien zu entfernen, die mich daran hindern, ein Ziehen/Zusammenführen durchzuführen. Aber sei vorsichtig! Führen Sie zuerst git merge …
aus, um zu sehen, ob nur die Dateien vorhanden sind, die Sie wirklich entfernen möchten.
git merge Origin/master 2>&1 >/dev/null | grep ^[[:space:]] | sed s/^[[:space:]]//g | xargs -L1 rm
git merge
listet unter anderem alle diese Dateien auf. Ihnen wird ein Leerzeichen vorangestellt.2>&1 >/dev/null
leitet die Fehlerausgabe auf die Standardausgabe um, sodass sie von grep
abgerufen wird.grep ^[[:space:]]
filtert nur die Zeilen mit Dateinamen.sed s/^[[:space:]]//g
schneidet den Leerraum von Anfang an ab.xargs -L1 rm
ruft rm
für jede dieser Dateien auf und löscht sie.Seien Sie vorsichtig: Bei jedem git merge
wird die rm
für jede Zeile aufgerufen, die mit einem Leerzeichen beginnt.
Ich habe versucht, den Material2-Zweig auf dem Angular2-Webpack-Starter zu verwenden, und hatte eine verdammte Zeit. Dies war die einzige Möglichkeit, diesen Zweig herunterzuladen und zu verwenden.
git clone --depth 1 https://github.com/angularclass/angular2-webpack-starter.git
cd angular2-webpack-starter/
git checkout -b material2
Öffnen Sie den Projektordner und löschen Sie alle nicht ausgeblendeten Dateien und Ordner. Lass alle versteckten.
git add .
git commit -m "pokemon go"
git reset --hard
git pull Origin material2
(Wenn der Editor angezeigt wird, drücken Sie ': wq' und dann Enter)
Nun bist du bereit.
Führen Sie unter Windows diesen einzigen Befehl aus:
git fetch --all & git reset --hard Origin/master
Sie könnten diese Datei mit einer Datei in Ihrem Projekt-Basisordner ignorieren:
.gitignore
public/images/*
Dann ziehen Sie die Änderungen und entfernen Sie diese Zeile aus Ihrer Gitignore-Datei.
git fetch --all && git reset --hard Origin/master && git pull
1: Zurücksetzen auf einen vorherigen Commit
git reset --hard HEAD
2: Nicht aufgerissene Dateien löschen
git clean -f
3: Ziehen Sie die Commits
git pull
Quellen:
Du könntest es versuchen
git pull --force
wenn Sie alle lokalen Dateien überschreiben möchten
git fetch --all
dann, wenn Sie in der Hauptniederlassung sind
git reset --hard Origin/master
else
git reset --hard Origin/master<branch_name>
wenn Sie den Remote-Tracking-Zweig generisch zurücksetzen möchten, verwenden Sie:
git fetch
git reset --keep Origin/$(git rev-parse --abbrev-ref HEAD)
wenn Sie auch Ihre lokalen Änderungen zurücksetzen möchten:
git fetch
git reset --hard Origin/$(git rev-parse --abbrev-ref HEAD)