Wie quetschen Sie Ihr gesamtes Repository bis zum ersten Commit?
Ich kann auf das erste Commit zurückgreifen, aber das würde mir 2 Commits lassen. Gibt es eine Möglichkeit, das Commit vor dem ersten zu referenzieren?
git
rebase
git-rebase
squash
git-rewrite-history
Verhogen
quelle
quelle
--root
ist eigentlich nicht die beste Lösung, um alle Commits zu quetschen, wenn viele davon zu quetschen sind): Kombinieren Sie die ersten beiden Commits eines Git-Repositorys? .Antworten:
Am einfachsten ist es vielleicht, einfach ein neues Repository mit dem aktuellen Status der Arbeitskopie zu erstellen. Wenn Sie alle Festschreibungsnachrichten behalten möchten, können Sie dies zuerst tun
git log > original.log
und dann für Ihre erste Festschreibungsnachricht im neuen Repository bearbeiten:oder
quelle
git rebase -i --root
. Siehe: stackoverflow.com/a/9254257/109618Ab Git 1.6.2 können Sie verwenden
git rebase --root -i
.Wechseln Sie für jedes Commit mit Ausnahme des ersten
pick
zusquash
.quelle
squash
für alle Commits verwenden. Das allererste muss seinpick
.Aktualisieren
Ich habe einen Alias gemacht
git squash-all
.Anwendungsbeispiel :
git squash-all "a brand new start"
.Vorsichtsmaßnahme : Denken Sie daran, einen Kommentar abzugeben, da sonst die Standard-Commit-Meldung "Ein neuer Start" verwendet wird.
Oder Sie können den Alias mit dem folgenden Befehl erstellen:
Einzeiler
Hinweis : Hier ist "
A new start
" nur ein Beispiel. Sie können auch Ihre eigene Sprache verwenden.TL; DR
Keine Notwendigkeit zu quetschen, verwenden
git commit-tree
, um ein Orphan Commit zu erstellen und damit zu gehen.Erklären
Erstellen Sie ein einzelnes Commit über
git commit-tree
Was
git commit-tree HEAD^{tree} -m "A new start"
tut ist:Der Ausdruck
HEAD^{tree}
bedeutet das BaumobjektHEAD
, das der Spitze Ihres aktuellen Zweigs entspricht. siehe Tree-Objects und Commit-Objects .Setzen Sie den aktuellen Zweig auf das neue Commit zurück
git reset
Setzen Sie dann einfach den aktuellen Zweig auf das neu erstellte Commit-Objekt zurück.Auf diese Weise wird nichts im Arbeitsbereich berührt, und es besteht keine Notwendigkeit für Rebase / Squash, was es sehr schnell macht. Die benötigte Zeit spielt für die Größe des Repositorys oder die Verlaufstiefe keine Rolle.
Variation: Neues Repo aus einer Projektvorlage
Dies ist nützlich, um das "anfängliche Festschreiben" in einem neuen Projekt unter Verwendung eines anderen Repositorys als Vorlage / Archetyp / Startwert / Skelett zu erstellen. Zum Beispiel:
Dadurch wird vermieden, dass das Vorlagen-Repo als Remote (
origin
oder auf andere Weise) hinzugefügt wird, und der Verlauf des Vorlagen-Repos wird in Ihrem anfänglichen Commit zusammengefasst.quelle
git push -f
für die Weitergabe verwendet wird.git clone
. Wenn Sie hinzufügen--hard
zugit reset
und SchalterHEAD
mitFETCH_HEAD
in dergit commit-tree
Sie eine erste begehen erstellen , nachdem die Vorlage Repo holen. Ich habe die Antwort mit einem Abschnitt am Ende bearbeitet, der dies demonstriert.${1?Please enter a message}
Wenn Sie nur alle Ihre Commits auf das Root-Commit reduzieren möchten, dann während
kann funktionieren, ist für eine große Anzahl von Commits (z. B. Hunderte von Commits) unpraktisch, da der Rebase-Vorgang wahrscheinlich sehr langsam ausgeführt wird, um die Commit-Liste des interaktiven Rebase-Editors zu generieren und die Rebase selbst auszuführen.
Hier sind zwei schnellere und effizientere Lösungen, wenn Sie eine große Anzahl von Commits quetschen:
Alternative Lösung Nr. 1: Waisenzweige
Sie können einfach einen neuen verwaisten Zweig an der Spitze (dh dem letzten Commit) Ihres aktuellen Zweigs erstellen. Dieser verwaiste Zweig bildet das anfängliche Root-Commit eines völlig neuen und separaten Commit-Verlaufsbaums, der effektiv dem Squashing aller Ihrer Commits entspricht:
Dokumentation:
Alternative Lösung Nr. 2: Soft-Reset
Eine andere effiziente Lösung besteht darin, einfach einen gemischten oder Soft-Reset für das Root-Commit zu verwenden
<root>
:Dokumentation:
quelle
git push origin master --force
.git push --force
Dadurch wird ein verwaistes Commit mit dem HEAD-Baum erstellt und dessen Name (SHA-1) auf stdout ausgegeben. Dann setzen Sie einfach Ihren Zweig dort zurück.
quelle
git reset $(git commit-tree HEAD^{tree} -m "commit message")
würde es einfacher machen.echo "message" | git commit-tree "HEAD^{tree}"
So habe ich das gemacht, nur für den Fall, dass es für jemand anderen funktioniert:
Denken Sie daran, dass es immer ein Risiko gibt, solche Dinge zu tun, und es ist nie eine schlechte Idee, vor dem Start einen sicheren Zweig zu erstellen.
Beginnen Sie mit der Protokollierung
Scrollen Sie zum ersten Commit und kopieren Sie SHA
Ersetzen Sie
<#sha#>
mit dem aus dem Protokoll kopierten SHAStellen Sie sicher, dass alles grün ist, sonst laufen
git add -A
Ändern Sie alle aktuellen Änderungen am aktuellen ersten Commit
Drücken Sie nun diesen Zweig mit Gewalt und er überschreibt, was sich dort befindet.
quelle
Ich habe etwas über die Verwendung von Transplantaten gelesen, aber nie viel untersucht.
Wie auch immer, Sie können die letzten 2 Commits manuell mit so etwas quetschen:
quelle
Am einfachsten ist es,
update-ref
den aktuellen Zweig mit dem Befehl 'plumbing' zu löschen.Sie können es nicht verwenden,
git branch -D
da es ein Sicherheitsventil hat, das Sie daran hindert, den aktuellen Zweig zu löschen.Dies versetzt Sie wieder in den Status "Erstes Festschreiben", in dem Sie mit einem neuen anfänglichen Festschreiben beginnen können.
quelle
Zerquetschen Sie zunächst alle Ihre Commits in einem einzigen Commit mit
git rebase --interactive
. Jetzt haben Sie zwei Commits zum Squash. Lesen Sie dazu eines vonquelle
In einer Zeile mit 6 Wörtern
quelle
git help checkout
über--orphan
git help checkout --orphan
Erstellen Sie ein Backup
auf das angegebene Commit zurücksetzen
Fügen Sie dann alle Dateien zum Staging hinzu
Festschreiben, ohne die Nachricht zu aktualisieren
Schieben Sie einen neuen Zweig mit gequetschten Commits zum Repo
quelle
<root>
Commit, auf das Sie zurückgesetzt haben.git commit --amend --no-edit
Übernimmt alle Änderungen an der aktuellen Festschreibung,<root>
ohne dass die Festschreibungsnachricht bearbeitet werden muss.Mit Transplantaten quetschen
Fügen Sie eine Datei hinzu
.git/info/grafts
und legen Sie dort den Commit-Hash ab, den Sie als Root verwenden möchtengit log
wird nun von diesem Commit ausgehenDamit es "echt" läuft
git filter-branch
quelle
Diese Antwort verbessert sich gegenüber den oben genannten Punkten (bitte stimmen Sie ab), vorausgesetzt, Sie möchten nicht nur das eine Commit erstellen (keine Eltern, keine Historie), sondern auch alle Commit-Daten dieses Commits beibehalten:
Natürlich wird sich die Commit-SHA des neuen / einzelnen Commits ändern, da sie eine neue (Nicht-) Historie darstellt und zu einem übergeordneten / Root-Commit wird.
Dies kann durch Lesen
git log
und Einstellen einiger Variablen für erfolgengit commit-tree
. Angenommen, Sie möchten ein einzelnes Commitmaster
in einem neuen Zweig erstellenone-commit
, wobei die oben genannten Commit-Daten beibehalten werden:quelle
Zu diesem Zweck können Sie Ihr lokales Git-Repository auf das erste Commit-Hashtag zurücksetzen, sodass alle Änderungen nach diesem Commit nicht mehr bereitgestellt werden. Anschließend können Sie das Commit mit der Option --amend durchführen.
Bearbeiten Sie dann bei Bedarf den ersten Commit-Namen und speichern Sie die Datei.
quelle
Bei mir hat es so funktioniert: Ich hatte insgesamt 4 Commits und habe die interaktive Rebase verwendet:
Das allererste Commit bleibt und ich habe 3 letzte Commits gemacht.
Falls Sie im Editor stecken bleiben, der als nächstes angezeigt wird, sehen Sie Folgendes:
Sie müssen zuerst ein Commit durchführen und andere darauf drücken. Was Sie haben sollten, ist:
Verwenden Sie dazu die INSERT-Taste, um den Einfüge- und den Bearbeitungsmodus zu ändern.
Verwenden Sie zum Speichern und Beenden des Editors
:wq
. Wenn sich Ihr Cursor zwischen diesen Festschreibungszeilen oder an einer anderen Stelle befindet, drücken Sie ESC und versuchen Sie es erneut.Als Ergebnis hatte ich zwei Commits: das allererste, das übrig blieb, und das zweite mit der Meldung "Dies ist eine Kombination aus 3 Commits."
Weitere Informationen finden Sie hier: https://makandracards.com/makandra/527-squash-several-git-commits-into-a-single-commit
quelle
Normalerweise mache ich das so:
Stellen Sie sicher, dass alles festgeschrieben ist, und notieren Sie sich die neueste Festschreibungs-ID, falls etwas schief geht, oder erstellen Sie einen separaten Zweig als Sicherung
Lauf
git reset --soft `git rev-list --max-parents=0 --abbrev-commit HEAD`
, um Ihren Kopf auf das erste Commit zurückzusetzen, aber lassen Sie Ihren Index unverändert. Alle Änderungen seit dem ersten Festschreiben werden nun zum Festschreiben bereit angezeigt.Ausführen
git commit --amend -m "initial commit"
, um Ihr Commit auf das erste Commit zu ändern und die Commit-Nachricht zu ändern. Wenn Sie die vorhandene Commit-Nachricht beibehalten möchten, können Sie sie ausführengit commit --amend --no-edit
Führen Sie aus
git push -f
, um Ihre Änderungen zu erzwingenquelle