Wie erzwinge ich, dass Git Pull bei jedem Zug alles überschreibt?


203

Ich habe ein nacktes CENTRAL-Repository, in dem drei Entwickler-Repositorys normal abgerufen und verschoben werden.

Ich habe auch zwei andere Repositorys, die vom CENTRAL Bare Repo abgerufen werden: eines ist der Live-Server und das andere ist ein Test- / Stage-Server - jedes wird von seinem jeweiligen Zweig abgerufen.

Das Szenario ist das folgende: Ich habe ein post-updateHook-Skript im CENTRAL-Repo, das automatisch auf die Test- und Live-Repos zugreift und für jedes einen Pull-Befehl ausführt. Dadurch werden sowohl Test- als auch Live-Server aktualisiert, je nachdem, welcher Zweig neue Commits hat. Das alles funktioniert super.

Das Problem ist folgendes: Es kann vorkommen, dass im Notfall Dateien direkt auf dem Server aktualisiert werden (über FTP oder was auch immer) und das CENTRAL-Skript nach dem Update fehlschlägt, da Konflikte beim Zusammenführen / Überschreiben auftreten. Es gibt keine Möglichkeit, dieses Szenario zu vermeiden, und es ist unvermeidlich.

Was ich gerne hätte, ist Folgendes: Ich möchte, dass der Pull von den Live- und Test-Sites beim Pull immer überschrieben / zusammengeführt wird. Immer. Diese Repos sind nur zum Ziehen bestimmt, da sie nicht für die Entwicklung bestimmt sind.

Bei all meinen Nachforschungen kann ich keine gute Lösung finden, bei der ein Pull immer ein Überschreiben der lokalen Dateien erzwingt. Ist das überhaupt möglich? Wenn ja, wäre dies ein großartiges Entwicklungsszenario.


1
Ich habe zwar unten für die Antwort "Zurücksetzen auf das, was Sie gerade abgerufen haben" gestimmt, aber ich denke, die Lösung für Ihr eigentliches Problem besteht darin, keine Änderungen außerhalb des Bandes vorzunehmen. Egal wie dringend Änderungen sollten immer die Versionskontrolle durchlaufen. Niemand außer den Betreibern sollte direkten Zugriff auf die laufenden Websites haben (z. B. keine Entwickler). Wenn Sie die Versionskontrolle konsistent verwenden, haben Sie Aufzeichnungen darüber, wann Änderungen vorgenommen wurden und wer sie vorgenommen hat, sowie über bessere Tools, um mit ihnen zu arbeiten. Warum es untergraben, ohne wirklichen Nutzen?
Phil Miller

1
@ Novelocrat richtig, ich verstehe, was Sie sagen. Leider gibt es eine Reihe von Szenarien, in denen jemand eine Datei direkt auf den Server hochladen könnte. In diesem Fall müsste ich eine Reihe von Befehlen ausführen, um die Repos neu zu synchronisieren. Zuvor haben wir ein FTP-Skript verwendet, um Dateien vom Repo auf den Server zu verschieben. Das oben vorgeschlagene Verfahren würde einfach den FTP-Schritt eliminieren, der in der Vergangenheit sehr gut funktioniert hat.
Bmilesp

3
Lassen Sie also keine Personen direkt auf den Server zugreifen. Sperren Sie den FTP- und SSH-Zugriff oder teilen Sie ihnen mit, dass sie wegen unerklärlicher Änderungen entlassen werden. Wenn Sie diese Art von Übung fortsetzen, tun Sie und Ihr Team auf lange Sicht nur weh.
Phil Miller

Antworten:


510

Wirklich der ideale Weg, dies zu tun, ist überhaupt nicht zu verwenden pull, sondern fetchund reset:

git fetch origin master
git reset --hard FETCH_HEAD
git clean -df

(Wechseln masterzu dem Zweig, dem Sie folgen möchten.)

pulldient dazu, Änderungen auf irgendeine Weise zusammenzuführen, während resetIhre lokale Kopie einfach mit einem bestimmten Commit übereinstimmt.

cleanJe nach den Anforderungen Ihres Systems möchten Sie möglicherweise etwas andere Optionen in Betracht ziehen .


3
@ user730569 reset --hardist ein Befehl, mit dem der Status des Arbeitsverzeichnisses (und des aktuellen Zweigs) in einen Status versetzt wird, der dem eines bestimmten Commits entspricht.
Amber

25
FETCH_HEADist eine Referenz, die automatisch erstellt wird fetch, um die abgerufene Referenz darzustellen. Es wird nicht zusammengeführt, sondern bei jedem Abruf direkt überschrieben. cleanist ein Befehl, der Dateien entfernt, die nicht von verfolgt werden git. Die -dfFlags weisen ihn an, Verzeichnisse zu entfernen ( -d) und das Entfernen tatsächlich durchzuführen ( -f).
Amber

4
Warum gibt es dafür kein Schlüsselwort? Ich brauche das viel öfter als ziehen.
Wolfgang Fahl

14
Möglicherweise möchten Sie git clean -dnvor der Verwendung verwenden, git clean -dfdamit Sie sehen, welche Dateien / Ordner gelöscht werden. git clean -dfkann nur rückgängig gemacht werden, wenn Sie ein Backup hatten
Ibrahim Lawal

1
@NickMiddleweek Ich hatte Angst git clean -df, dass auch gitignored Dateien entfernt werden, aber es stellt sich heraus, dass dies nicht der Fall ist. git clean --helpsagt: "Normalerweise werden nur Dateien entfernt, die Git nicht bekannt sind. Wenn jedoch die Option -x angegeben ist, werden auch ignorierte Dateien entfernt. Dies kann beispielsweise nützlich sein, um alle Build-Produkte zu entfernen."
Nickang


6

Ich bin nicht sicher, wie ich es in einem Befehl machen soll, aber Sie könnten etwas tun wie:

git reset --hard
git pull

oder auch

git stash
git pull

So führen Sie einen Befehl aus : git reset --hard && git pull. Alternativ, aber nicht besser git reset --hard; git pull. Mit &&wird der zweite Befehl nur ausgeführt, wenn der erste Befehl erfolgreich war. ;führt es unabhängig vom Exit-Code des ersten Befehls aus.
Mazunki

5

Um eine Kopie des Zweigs abzurufen und das Überschreiben lokaler Dateien vom Ursprung zu erzwingen, verwenden Sie:

git reset --hard origin/current_branch

Alle aktuellen Arbeiten gehen verloren und sind dann mit dem Ursprungszweig identisch


5
git reset --hard HEAD
git fetch --all
git reset --hard origin/your_branch

2

Sie können den Haken ändern, um alles sauber zu wischen.

# Danger! Wipes local data!

# Remove all local changes to tracked files
git reset --hard HEAD

# Remove all untracked files and directories
git clean -dfx

git pull ...

2
Was macht x? Bitte erklären Sie die Schalter
Steve K

2
Das x soll alle nicht verfolgten Dateien entfernen, denke ich. In Manpage-Sprache schwer zu sagen, weshalb wir SO haben.
JosephK

2
@ JosephK: Das ist falsch. Der Hauptzweck von git cleanist bereits "Nicht verfolgte Dateien aus dem Arbeitsbaum entfernen" (oben auf der Seite). Normalerweise enthält dies keine ignorierten Dateien, -xweist jedoch darauf hin git clean, dass auch ignorierte Dateien eingeschlossen werden sollen (außer dies wirkt sich nicht auf Dateien aus, die von der -eOption ignoriert werden ).
Dietrich Epp

2

Wenn Sie die lokalen Änderungen seit dem letzten Pull / Clone noch nicht festgeschrieben haben, können Sie Folgendes verwenden:

git checkout *
git pull

checkoutpulllöscht Ihre lokalen Änderungen mit dem letzten lokalen Commit und sinkronisiert sie in das Remote-Repository

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.