überschreiben - how to do git force pull




Wie erzwinge ich "git pull", um lokale Dateien zu überschreiben? (20)

Wie erzwinge ich das Überschreiben lokaler Dateien bei einem git pull ?

Das Szenario ist folgendes:

  • Ein Teammitglied ändert die Vorlagen für eine Website, an der wir gerade arbeiten
  • Sie fügen dem Bilderverzeichnis einige Bilder hinzu (vergisst jedoch, sie unter Quellcodeverwaltung hinzuzufügen).
  • Sie schicken mir die Bilder später per Post
  • Ich füge die Bilder unter der Quellcodeverwaltung hinzu und übertrage 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:

error: Untracked working tree file 'public/images/icon.gif' would be overwritten by merge

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.


Wichtig: Wenn Sie lokale Änderungen haben, gehen diese verloren. Mit oder ohne --hard Option gehen alle lokalen Commits, die noch nicht gepusht wurden, 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>

Erläuterung:

git fetch lädt das neueste von remote herunter, ohne zu versuchen, etwas zusammenzuführen oder neu zu registrieren.

Dann setzt git reset den Master-Zweig 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

Aktuelle lokale Commits pflegen

[*] : Es ist erwähnenswert, dass es möglich ist, die aktuellen lokalen Commits beizubehalten, indem vor dem Zurücksetzen eine Zweigstelle vom master :

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 .

Nicht festgeschriebene Änderungen

Nicht festgeschriebene Änderungen gehen jedoch verloren (auch in Stufen). Stellen Sie sicher, dass Sie alles verstauen und festlegen, was Sie brauchen. Dafür können Sie Folgendes ausführen:

git stash

Und dann diese unverbindlichen Änderungen erneut anwenden:

git stash pop

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 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. Er synchronisiert die neuesten Serveränderungen automatisch (mit Abruf + Zusammenführen) und setzt Ihr Commit ganz oben in das Git-Protokoll. Manuelles Ziehen / Zusammenführen ist nicht zu befürchten.

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


Aufgrund meiner eigenen ähnlichen Erfahrungen ist die von Strahinja Kustudic angebotene Lösung bei weitem die beste. Wie andere bereits erwähnt haben, werden bei einem Hard Reset alle nicht aufgespürten Dateien entfernt, die viele Dinge enthalten könnten, die Sie nicht entfernen möchten, z. B. Konfigurationsdateien. Es ist sicherer, 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

Das Problem bei all diesen Lösungen ist, dass sie entweder zu komplex sind oder ein noch größeres Problem: Sie entfernen alle nicht protokollierten Dateien vom Webserver, die 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.


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.


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

Es scheint, dass sich die meisten Antworten hier auf den master Zweig konzentrieren. Es gibt jedoch Zeiten, in denen ich an zwei verschiedenen Stellen an demselben Feature-Zweig arbeite, und ich möchte, dass eine Re-Base in einem anderen Bereich reflektiert wird, ohne viel durch den Reifen zu springen.

Basierend auf einer Kombination aus der Antwort von RNA und der Antwort von Torek 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 ) git forcepull :

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!


Es sieht so aus, als wäre der beste Weg, zuerst zu tun:

git clean

Um alle nicht aufgespürten Dateien zu löschen und dann mit dem üblichen git pull fortzufahren ...


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 leistungsfähig, sodass Sie Ihre Änderungen verlieren könnten.


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

Der letzte Befehl gibt eine Liste der lokalen Änderungen an. Ändern Sie den Zweig "tmp" 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 handhaben, 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 hatte das gleiche Problem und aus irgendeinem Grund würde ein git clean -f -d es nicht tun. Hier ist der 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 entfernt sie nicht, es sei denn, Sie fügen -x .


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:

  1. Alle Dateien löschen. Lassen Sie nur das .git-Verzeichnis.
  2. git reset --hard HEAD
  3. git pull
  4. git push

Jetzt gehts.


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!


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

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

git reset origin/master

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?


Versuche dies:

git reset --hard HEAD
git pull

Es sollte tun, was Sie wollen.


Versuchen Sie zunächst die Standardmethode:

git reset HEAD --hard # Remove all not committed changes

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 .git/ dir, wo Sie alle Commits haben) und es erneut ziehen.

Warum kann git reset HEAD --hard in einigen Fällen fehlschlagen?

  1. Benutzerdefinierte Regeln in der .gitattributes file

    Wenn eol=lf rule in .gitattributes ist, kann git einige Dateiänderungen ändern, indem CRLF-Zeilenenden in LF in einigen Textdateien konvertiert werden.

    Wenn dies der Fall ist, müssen Sie diese CRLF / LF-Änderungen git config core.autcrlf false (indem Sie sie im git status überprüfen) oder versuchen: git config core.autcrlf false , um sie temporär zu ignorieren.

  2. Dateisystem-Inkompatibilität

    Wenn Sie ein Dateisystem verwenden, das Berechtigungsattribute nicht unterstützt. Im Beispiel haben Sie zwei Repositorys, eines unter Linux / Mac ( ext3 / hfs+ ) und eines auf 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 versuch, git erkennt immer einige "änderungen".


Achtung, dadurch werden Ihre Dateien endgültig gelöscht, wenn Sie Verzeichnis- / * -Einträge in Ihrer Gititore-Datei haben.

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, einzeln:

$ 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 hinterlegt haben:

$ git stash list
...
$ git stash apply [email protected]{5}

WARNUNG: git clean löscht alle Ihre 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.

--dry-run Sie zuerst die Verwendung des --dry-run -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
...




git-fetch