Ich habe derzeit ein lokales Git-Repository, das ich in ein Github-Repository pushe.
Das lokale Repository hat ~ 10 Commits, und das Github-Repository ist ein synchronisiertes Duplikat davon.
Ich möchte den gesamten Versionsverlauf aus dem lokalen Git-Repository entfernen, sodass der aktuelle Inhalt des Repositorys als einziges Commit angezeigt wird (und daher ältere Versionen von Dateien im Repository nicht gespeichert werden).
Ich möchte diese Änderungen dann gerne an Github weitergeben.
Ich habe Git Rebase untersucht, aber dies scheint besser geeignet zu sein, um bestimmte Versionen zu entfernen. Eine andere mögliche Lösung besteht darin, das lokale Repo zu löschen und ein neues zu erstellen - obwohl dies wahrscheinlich viel Arbeit verursachen würde!
ETA: Es gibt bestimmte Verzeichnisse / Dateien, die nicht verfolgt werden. Wenn möglich, möchte ich das Aufspüren dieser Dateien beibehalten.
quelle
Antworten:
Hier ist der Brute-Force-Ansatz. Außerdem wird die Konfiguration des Repositorys entfernt.
Hinweis : Dies funktioniert NICHT, wenn das Repository Submodule hat! Wenn Sie Submodule verwenden, sollten Sie z. B. interaktive Rebase verwenden
Schritt 1: Entfernen Sie den gesamten Verlauf ( Stellen Sie sicher, dass Sie eine Sicherung haben, diese kann nicht zurückgesetzt werden )
Schritt 2: Rekonstruieren Sie das Git-Repo nur mit dem aktuellen Inhalt
Schritt 3: Drücken Sie auf GitHub.
quelle
.gitignore
solltest damit umgehen, oder?git commit -m "Initial commit"
danach .git / config wiederherstellen , können Sie dengit remote add ...
Teil wahrscheinlich überspringen , vorausgesetzt, er war bereits in Ihrer Konfiguration enthalten, und direkt mit dem Push fortfahren. Es hat bei mir funktioniert.Die einzige Lösung, die für mich funktioniert (und Submodule am Laufen hält), ist
Das Löschen
.git/
verursacht immer große Probleme, wenn ich Submodule habe. Das Verwendengit rebase --root
würde irgendwie Konflikte für mich verursachen (und es würde lange dauern, seit ich viel Geschichte hatte).quelle
git push -f origin master
da der letzte Op und die Sonne wieder auf dein frisches Repo scheint! :)git gc --aggressive --prune all
den ganzen Sinn, die Geschichte zu verlieren, würde man sie verpassen.Dies ist mein bevorzugter Ansatz:
Dadurch wird ein neuer Zweig mit einem Commit erstellt, der alles in HEAD hinzufügt. Es ändert nichts anderes, also ist es absolut sicher.
quelle
git-rev-parse
Dokumenten. Was hier passiert,git-commit-tree
erfordert einen Verweis auf einen Baum (eine Momentaufnahme des Repos), ist aberHEAD
eine Überarbeitung. Um den mit einem Commit verknüpften Baum zu finden, verwenden wir das<rev>^{<type>}
Formular.git push --force <remote> new_branch_name:<remote-branch>
Die andere Option, die sich bei vielen Commits als viel Arbeit herausstellen könnte, ist eine interaktive Rebase (vorausgesetzt, Ihre Git-Version ist> = 1.7.12):
git rebase --root -i
Wenn in Ihrem Editor eine Liste mit Commits angezeigt wird:
Speichern und schließen. Git wird neu basiert.
Am Ende hätten Sie ein neues Root-Commit, das eine Kombination aller nachfolgenden Commits ist.
Der Vorteil ist, dass Sie Ihr Repository nicht löschen müssen und wenn Sie Bedenken haben, haben Sie immer einen Fallback.
Wenn Sie Ihren Verlauf wirklich nuklearisieren möchten, setzen Sie den Master auf dieses Commit zurück und löschen Sie alle anderen Zweige.
quelle
error: failed to push some refs to
git push --force-with-lease
. Force-with-Lease wird verwendet, weil es weniger destruktiv ist als --force.Variante der von Larsmans vorgeschlagenen Methode:
Speichern Sie Ihre Liste der nicht verfolgten Dateien:
Speichern Sie Ihre Git-Konfiguration:
Führen Sie dann die ersten Schritte von larsmans aus:
Stellen Sie Ihre Konfiguration wieder her:
Entfernen Sie nicht verfolgte Dateien:
Dann verpflichten Sie sich:
Und schließlich in Ihr Repository verschieben:
quelle
Unten finden Sie ein Skript, das aus der Antwort von @Zeelot übernommen wurde. Es sollte den Verlauf aus allen Zweigen entfernen, nicht nur aus dem Hauptzweig:
Es hat für meine Zwecke funktioniert (ich benutze keine Submodule).
quelle
git branch
wird neben Ihrem ausgecheckten Zweig ein Sternchen einfügen, das dann mit einem Globus versehen wird, sodass es in alle Dateien oder Ordner aufgelöst wird, als wären dies auch Zweignamen. Stattdessen habe ich verwendet,git branch --format="%(refname:lstrip=2)"
was mir nur die Filialnamen gab.git push --force origin master
odergit push --force-with-lease
? Anscheinend ist letzteres sicherer (siehe stackoverflow.com/questions/5509543/… )Sie könnten flache Klone verwenden (git> 1.9):
Weiterführende Literatur: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/
quelle
git filter-branch
ist das Hauptchirurgiewerkzeug.--parent-filter
bringt die Eltern auf stdin und sollte die umgeschriebenen Eltern auf stdout drucken; Unix wirdtrue
erfolgreich beendet und druckt nichts, also: keine Eltern.@^!
ist Git Abkürzung für " The Head Commit, aber keiner seiner Eltern". Löschen Sie dann alle anderen Refs und drücken Sie nach Belieben.quelle
Löschen Sie einfach das Github-Repo und erstellen Sie ein neues. Mit Abstand der schnellste, einfachste und sicherste Ansatz. Was müssen Sie schließlich tun, um all diese Befehle in der akzeptierten Lösung auszuführen, wenn Sie nur den Hauptzweig mit einem einzigen Commit benötigen?
quelle
Die folgende Methode ist genau reproduzierbar. Wenn beide Seiten konsistent sind, müssen Sie den Klon nicht erneut ausführen. Führen Sie das Skript einfach auch auf der anderen Seite aus.
Wenn Sie es dann bereinigen möchten, versuchen Sie dieses Skript:
http://sam.nipl.net/b/git-gc-all-ferocious
Ich habe ein Skript geschrieben, das den Verlauf für jeden Zweig im Repository "beendet":
http://sam.nipl.net/b/git-kill-history
Siehe auch: http://sam.nipl.net/b/confirm
quelle
git-hash: not found
undSupport for <GIT_DIR>/info/grafts is deprecated
git log HEAD~${1:-0} -n1 --format=%H
hier sam.aiki.info/b/git-hash. Es wäre besser, alles in einem Skript für den öffentlichen Verbrauch zusammenzufassen. Wenn ich es jemals wieder benutze, könnte ich herausfinden, wie es mit der neuen Funktion gemacht wird, die "Transplantate" ersetzt.Eine konzeptionellere Antwort:
git müll sammelt automatisch alte Commits, wenn keine Tags / Zweige / Refs auf sie verweisen. Sie müssen also einfach alle Tags / Zweige entfernen und ein neues verwaistes Commit erstellen, das jedem Zweig zugeordnet ist. Konventionell würden Sie den Zweig
master
auf dieses Commit verweisen lassen .Die alten, nicht erreichbaren Commits werden dann von niemandem mehr gesehen, es sei denn, sie graben mit Git-Befehlen auf niedriger Ebene. Wenn das für Sie ausreicht, würde ich einfach dort anhalten und den automatischen GC seine Arbeit machen lassen, wann immer er möchte. Wenn Sie sie sofort loswerden möchten, können Sie
git gc
(möglicherweise mit--aggressive --prune=all
) verwenden. Für das Remote-Git-Repository gibt es jedoch keine Möglichkeit, dies zu erzwingen, es sei denn, Sie haben Shell-Zugriff auf das Dateisystem.quelle
Bitte schön:
Auch hier gehostet: https://gist.github.com/Zibri/76614988478a076bbe105545a16ee743
quelle
Ich habe ein ähnliches Problem gelöst, indem ich einfach den
.git
Ordner aus meinem Projekt gelöscht und über IntelliJ wieder in die Versionskontrolle integriert habe. Hinweis: Der.git
Ordner ist ausgeblendet. Sie können es im Terminal mit anzeigenls -a
und dann mit entfernenrm -rf .git
.quelle
Verwenden Sie dazu den Shallow Clone-Befehl git clone --depth 1 URL - Klont nur den aktuellen HEAD des Repositorys
quelle
Mehr Infos hier.
Das Git-Tutoturial hier bietet Hilfe zum Löschen des Repositorys:
quelle