Es gibt eine Datei, die von Git verfolgt wurde, aber jetzt ist die Datei in der .gitignore
Liste.
Diese Datei taucht jedoch weiterhin in git status
nachdem es bearbeitet wurde. Wie kann man Git zwingen, es komplett zu vergessen?
Es gibt eine Datei, die von Git verfolgt wurde, aber jetzt ist die Datei in der .gitignore
Liste.
Diese Datei taucht jedoch weiterhin in git status
nachdem es bearbeitet wurde. Wie kann man Git zwingen, es komplett zu vergessen?
Die Verwendung des git rm --cached
Befehl keine Antwort auf die ursprüngliche Frage:
Wie zwingt man
git
[eine Datei] komplett zu vergessen?
Diese Lösung führt nämlich dazu, dass die Datei gelöscht in jeder anderen Instanz des Repositorys bei der Ausführung einer git pull
!
Die korrekte Vorgehensweise, um Git zu zwingen, eine Datei zu vergessen, ist bei GitHub dokumentiert aquí .
Ich empfehle, die Dokumentation zu lesen, aber im Grunde genommen:
git fetch --all
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch full/path/to/file' --prune-empty --tag-name-filter cat -- --all
git push origin --force --all
git push origin --force --tags
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now
Einfach ersetzen full/path/to/file
mit dem vollständigen Pfad der Datei. Stellen Sie sicher, dass Sie die Datei zu Ihrem .gitignore
Datei.
Außerdem müssen Sie (vorübergehend) nicht-schnelle Weiterleitungen in Ihr Repository erlauben da Sie Ihren Git-Verlauf ändern.
Verschieben oder kopieren Sie die Datei an einen sicheren Ort, damit sie nicht verloren geht. Dann "git rm" die Datei und Commit.
Die Datei wird immer noch angezeigt, wenn Sie zu einem dieser früheren Commits oder einem anderen Zweig zurückkehren, aus dem sie nicht entfernt wurde. In allen zukünftigen Übertragungen werden Sie die Datei jedoch nicht mehr sehen. Wenn sich die Datei im Git-Ignore befindet, können Sie sie zurück in den Ordner verschieben, und Git wird sie nicht mehr sehen.
El Antwort von Matt Frear war IMHO am wirksamsten. Im Folgenden finden Sie ein PowerShell-Skript für Windows-Nutzer, mit dem nur Dateien aus dem Git-Repository entfernt werden, die der Ausschlussliste entsprechen.
# Get files matching exclusionsfrom .gitignore
# Excluding comments and empty lines
$ignoreFiles = gc .gitignore | ?{$_ -notmatch "#"} | ?{$_ -match "\S"} | % {
$ignore = "*" + $_ + "*"
(gci -r -i $ignore).FullName
}
$ignoreFiles = $ignoreFiles| ?{$_ -match "\S"}
# Remove each of these file from Git
$ignoreFiles | % { git rm $_}
git add .
Die akzeptierte Antwort macht nicht "Git "vergessen" über eine Akte..." (historisch). Es macht nur Git ignorieren. die Datei in der Gegenwart/Zukunft.
Diese Methode macht Git völlig vergessen ignorierte Dateien ( Vergangenheit /Gegenwart/Zukunft), aber es ist no alles aus dem Arbeitsverzeichnis zu löschen (auch wenn es aus der Ferne neu geholt wird).
Diese Methode erfordert die Verwendung der Datei /.git/info/exclude
(bevorzugt) ou a bereits existierende .gitignore
en todo die Commits, die Dateien haben, die ignoriert/vergessen werden sollen. 1
Alle Methoden zur nachträglichen Durchsetzung des Git-Ignorierverhaltens schreiben die Geschichte um und haben daher erhebliche Auswirkungen für alle öffentlichen/gemeinsamen/kollaborativen Repositories, die nach diesem Prozess gezogen werden könnten. 2
Allgemeine Hinweise: mit einem sauberen Repository beginnen - alles übertragen, nichts im Arbeitsverzeichnis oder im Index ausstehend, und eine Sicherungskopie erstellen !
Auch die Kommentare/ Revisionsgeschichte de diese Antwort ( und Revisionsgeschichte de diese Frage ) kann nützlich/erhellend sein.
#Commit up-to-date .gitignore (if not already existing)
#This command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"
#Apply standard Git ignore behavior only to the current index, not the working directory (--cached)
#If this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#This command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached
#Commit to prevent working directory data loss!
#This commit will be automatically deleted by the --prune-empty flag in the following command
#This command must be run on each branch
git commit -m "ignored index"
#Apply standard git ignore behavior RETROACTIVELY to all commits from all branches (--all)
#This step WILL delete ignored files from working directory UNLESS they have been dereferenced from the index by the commit above
#This step will also delete any "empty" commits. If deliberate "empty" commits should be kept, remove --prune-empty and instead run git reset HEAD^ immediately after this command
git filter-branch --tree-filter 'git ls-files -z --ignored --exclude-standard | xargs -0 git rm -f --ignore-unmatch' --prune-empty --tag-name-filter cat -- --all
#List all still-existing files that are now ignored properly
#If this command returns nothing, it's time to restore from backup and start over
#This command must be run on each branch
git ls-files --other --ignored --exclude-standard
Folgen Sie schließlich dem Rest dieser GitHub-Anleitung (beginnend bei Schritt 6) die wichtige Warnungen/Informationen zu den folgenden Befehlen enthält .
git push origin --force --all
git push origin --force --tags
git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now
Andere Entwickler, die von dem nun geänderten entfernten Repository beziehen, sollten ein Backup erstellen und dann:
#fetch modified remote
git fetch --all
#"Pull" changes WITHOUT deleting newly-ignored files from working directory
#This will overwrite local tracked files with remote - ensure any local modifications are backed-up/stashed
git reset FETCH_HEAD
1 Denn /.git/info/exclude
kann mit den obigen Anweisungen auf alle historischen Übertragungen angewandt werden, vielleicht auch auf Details zum Erhalt einer .gitignore
Datei in die historische(n) Verpflichtung(en), die dies erfordern, übersteigt den Rahmen dieser Antwort. Ich wollte eine richtige .gitignore
Datei im Root-Commit, als ob es das erste wäre, was ich getan habe. Andere mag das nicht interessieren, da /.git/info/exclude
kann dasselbe bewirken, unabhängig davon, wo die .gitignore
Datei in der Commit-Historie existiert, und das Umschreiben der Historie ist eindeutig eine sehr heikles Thema, selbst wenn man sich der Verzweigungen .
FWIW, mögliche Methoden können sein git rebase
oder eine git filter-branch
die eine Kopie eines extern .gitignore
in jeder Übergabe, wie die Antworten auf diese Frage .
2 Erzwingen des Git-Ignorierverhaltens im Nachhinein durch Übertragen der Ergebnisse einer eigenständigen git rm --cached
kann zu einer neu ignorierten Datei führen Löschung in Zukunft von der kraftbetriebenen Fernbedienung abziehen. Die --prune-empty
Flagge im Folgenden git filter-branch
Befehl vermeidet dieses Problem, indem er automatisch den vorherigen "Alle ignorierten Dateien löschen"-Commit entfernt, der nur den Index betrifft. Das Umschreiben der Git-Historie ändert auch die Commit-Hashes, was dazu führt, dass Verheerungen anrichten bei künftigen Abrufen aus öffentlichen/gemeinsamen/kollaborativen Repositories. Bitte verstehen Sie die Verzweigungen bevor Sie dies mit einem solchen Repository tun. Diese GitHub-Anleitung spezifiziert das Folgende:
Sagen Sie Ihren Mitarbeitern, dass sie neu gründen , no zusammenführen, alle Zweige, die sie aus Ihrer alten (verdorbenen) Repository-Historie erstellt haben. Ein einziger Merge-Commit könnte einen Teil oder die gesamte verunreinigte Historie wieder einführen, die Sie gerade mühsam bereinigt haben.
Alternative Lösungen, die nicht das entfernte Repository betreffen, sind git update-index --assume-unchanged </path/file>
o git update-index --skip-worktree <file>
Beispiele dafür finden Sie unter aquí .
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.