Was bedeutet es, Commits in Git zu quetschen?

Lesezeit: 8 Minuten

Was bedeutet es Commits in Git zu quetschen
Lakshmanan Meiyappan

Was bedeutet Squashing-Commits in Git? Wie squash ich Commits in Github?

Ich bin neu bei Git und habe darum gebeten, einem Newcomer-Bug in Coala-Analyzer zugewiesen zu werden. Ich habe den Fehler behoben, und jetzt wurde ich gebeten, meine Commits zu quetschen. Wie mache ich es?

Was bedeutet es Commits in Git zu quetschen
Margaret Bloom

Sie können sich Git als eine erweiterte Datenbank mit Snapshots Ihrer Arbeitsverzeichnisse vorstellen.

Ein sehr nettes Feature von Git ist die Möglichkeit, den Verlauf von Commits umzuschreiben.
Der Hauptgrund dafür ist, dass ein Großteil dieser Historie nur für den Entwickler relevant ist, der sie erstellt hat, sodass sie vereinfacht oder ansprechender gestaltet werden muss, bevor sie an ein gemeinsam genutztes Repository gesendet wird.

Einen Commit quetschen bedeutet aus idiomatischer Sicht, die Änderungen, die in diesem Commit eingeführt wurden, in sein übergeordnetes Commit zu verschieben, sodass Sie am Ende mit einem Commit anstelle von zwei (oder mehr) enden.
Wenn Sie diesen Vorgang mehrmals wiederholen, können Sie reduzieren n sich auf einen einzigen festlegen.

Visuell, wenn Sie Ihre Arbeit mit dem Commit-Tag begonnen haben Anfangdu willst das

Git begeht Squashing

Sie werden vielleicht bemerken, dass der neue Commit einen etwas dunkleren Blauton hat. Dies ist Absicht.

In Git wird Squashing mit a erreicht Rebaseeiner speziellen Form namens Interaktives Rebase.
Vereinfachen, wenn Sie eine Reihe von Commits in einen Branch rebasen Bwenden Sie alle durch diese Commits eingeführten Änderungen so an, wie sie durchgeführt wurden, beginnend mit B anstelle ihres ursprünglichen Vorfahren.

Ein visueller Hinweis

Geben Sie hier die Bildbeschreibung ein

Beachten Sie noch einmal die verschiedenen Blautöne.

Mit einem interaktiven Rebase können Sie auswählen, wie Commits rebasiert werden sollen. Wenn Sie diesen Befehl ausführen:

 git rebase -i branch

Sie würden am Ende eine Datei erhalten, die die Commits auflistet, die rebasiert werden

 pick ae3...
 pick ef6...
 pick 1e0...
 pick 341...

Ich habe die Commits nicht benannt, aber diese vier sollen die Commits von sein Anfang zu Kopf

Das Schöne an dieser Liste ist das es ist editierbar.
Sie können Commits weglassen, oder Sie können zerquetsche sie.
Alles, was Sie tun müssen, ist, das erste Wort in zu ändern quetschen.

 pick ae3...
 squash ef6...
 squash 1e0...
 squash 341...

Wenn Sie den Editor schließen und keine Zusammenführungskonflikte gefunden werden, erhalten Sie diesen Verlauf:

Geben Sie hier die Bildbeschreibung ein

In Ihrem Fall möchten Sie nicht in einen anderen Zweig rebasen, sondern in einen früheren Commit.
Um den Verlauf wie im allerersten Beispiel gezeigt umzuwandeln, müssen Sie so etwas wie ausführen

git rebase -i HEAD~4

Ändern Sie die “Befehle” in quetschen für alle Commits außer dem ersten, und schließen Sie dann Ihren Editor.


Hinweis zum Ändern des Verlaufs

In Git werden Commits nie bearbeitet. Sie können gekürzt, unerreichbar gemacht, geklont, aber nicht verändert werden.
Wenn Sie rebasen, erstellen Sie tatsächlich neue Commits.
Die alten sind für keine Schiedsrichter mehr erreichbar, werden also nicht in der Historie angezeigt, sind aber immer noch da!

Das erhalten Sie tatsächlich für eine Rebase:

Geben Sie hier die Bildbeschreibung ein

Wenn Sie sie bereits irgendwo verschoben haben, wird das Umschreiben der Geschichte tatsächlich einen Zweig machen!

  • Schön – was passiert jedoch mit den ursprünglichen Commit-Kommentaren – werden sie zu einem einzigen großen Commit-Kommentar kombiniert oder gehen sie verloren?

    – PaulR

    29. Februar 16 um 16:46 Uhr

  • Von man git rebase: Die vorgeschlagene Commit-Nachricht für das gefaltete Commit ist die Verkettung der Commit-Nachrichten des ersten Commit und derjenigen mit dem “squash”-Befehl

    – Margaret Bloom

    1. März 16 um 7:55 Uhr


  • Dies ist die beste Erklärung, die ich für das Rebasing gesehen habe, danke.

    – Kerry Jones

    12. März 19 um 18:28 Uhr

  • Über das Squashing in Ihrem ersten Bild: Können Sie ein Beispiel machen, bei dem HEAD vor (hellblau) und nach (dunkelblau) dem Squashing ein anderes Arbeitsverzeichnis hat? In allen Beispielen, die ich versucht habe zu quetschen, sah es so aus, als ob es nur die drei Commits zwischen START und HEAD gelöscht hätte.

    – aktueller_panda

    6. Juli 2020 um 0:32 Uhr


  • @alper Andere Leute werden ihren Commit nicht verlieren, sie werden den Remote-Ref auf einem Commit sehen, der nicht in ihrem Verlauf ist, und git wird sie daran hindern, zu pushen, es sei denn, sie ziehen die Änderungen ein oder sie erzwingen ihren Weg. Wenn Sie alleine arbeiten, können Sie den Upstream-Verlauf umschreiben. Git löscht Commits nicht wirklich, Sie müssten es verwenden git prune unerreichbare Objekte zu entfernen. Ich weiß nicht, wie GitHub funktioniert, je mehr Zeit vergeht, desto weniger hat diese Site mit Git zu tun und mehr mit einem rechthaberischen SVC eines Drittanbieters.

    – Margaret Bloom

    28. August 21 um 22:35 Uhr

Der rebase-Befehl hat einige großartige Optionen in seiner --interactive (oder -i)-Modus, und einer der am häufigsten verwendeten ist die Fähigkeit, Commits zu squashen. Dadurch werden kleinere Commits genommen und zu größeren kombiniert, was nützlich sein kann, wenn Sie die Tagesarbeit abschließen oder wenn Sie Ihre Änderungen einfach anders verpacken möchten. Wir erklären Ihnen, wie Sie dies ganz einfach tun können.

Ein Wort der Vorsicht: Tun Sie dies nur bei Commits, die nicht in ein externes Repository gepusht wurden. Wenn andere basierend auf den Commits gearbeitet haben, die Sie löschen werden, können viele Konflikte auftreten. Schreiben Sie Ihren Verlauf nur nicht neu, wenn er mit anderen geteilt wurde.

Nehmen wir also an, Sie haben gerade ein paar kleine Commits vorgenommen und möchten daraus einen größeren Commit machen. Der Verlauf unseres Repositorys sieht derzeit so aus:

Geben Sie hier die Bildbeschreibung ein

Die letzten 4 Commits wären viel glücklicher, wenn sie zusammengepackt würden, also machen wir genau das durch interaktives Rebasing:

$ git rebase -i HEAD~4

pick 01d1124 Adding license
pick 6340aaa Moving license into its own file
pick ebfd367 Jekyll has become self-aware.
pick 30e0ccb Changed the tagline in the binary, too.

# Rebase 60709da..30e0ccb onto 60709da
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

Hier hat sich also einiges getan. Zuerst habe ich Git gesagt, dass ich mit den letzten vier Commits, von denen der HEAD ist, mit HEAD~4 rebaseen möchte. Git hat mich jetzt in einen Editor mit dem obigen Text und einer kleinen Erklärung gebracht, was getan werden kann. Auf diesem Bildschirm stehen Ihnen viele Optionen zur Verfügung, aber im Moment werden wir einfach alles in einem Commit zusammendrücken. Wenn Sie also die ersten vier Zeilen der Datei wie folgt ändern, wird der Trick ausreichen:

pick 01d1124 Adding license
squash 6340aaa Moving license into its own file
squash ebfd367 Jekyll has become self-aware.
squash 30e0ccb Changed the tagline in the binary, too.

Im Grunde weist dies Git an, alle vier Commits zum ersten Commit in der Liste zu kombinieren. Sobald dies erledigt und gespeichert ist, erscheint ein weiterer Editor mit Folgendem:

# This is a combination of 4 commits.
# The first commit's message is:
Adding license

# This is the 2nd commit message:

Moving license into its own file

# This is the 3rd commit message:

Jekyll has become self-aware.

# This is the 4th commit message:

Changed the tagline in the binary, too.

    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    # Explicit paths specified without -i nor -o; assuming --only paths...
    # Not currently on any branch.
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #   new file:   LICENSE
    #   modified:   README.textile
    #   modified:   Rakefile
    #   modified:   bin/jekyll
    #

Da wir so viele Commits kombinieren, erlaubt Ihnen Git, die Nachricht des neuen Commits basierend auf den übrigen am Prozess beteiligten Commits zu ändern. Bearbeiten Sie die Nachricht nach Belieben, speichern Sie sie und beenden Sie sie. Sobald dies erledigt ist, wurden Ihre Commits erfolgreich gequetscht!

Created commit 0fc4eea: Creating license file, and making jekyll self-aware.
 4 files changed, 27 insertions(+), 30 deletions(-)
  create mode 100644 LICENSE
    Successfully rebased and updated refs/heads/master.

Und wenn wir uns die Geschichte noch einmal anschauen…
Geben Sie hier die Bildbeschreibung ein

Also, das war bisher relativ schmerzlos. Wenn Sie während des Rebase auf Konflikte stoßen, sind diese normalerweise recht einfach zu lösen, und Git führt Sie so weit wie möglich durch. Die Grundlagen dafür sind die Lösung des betreffenden Konflikts, git add die Datei, und dann git rebase --continue wird den Vorgang fortsetzen. Natürlich macht man a git rebase --abort bringt Sie auf Wunsch in Ihren vorherigen Zustand zurück. Wenn Sie aus irgendeinem Grund ein Commit in der Rebase verloren haben, können Sie es mit dem Reflog wiederherstellen.

Einzelheiten finden Sie hier Verknüpfung.

  • Danke schön! Falls sich jemand mit VIM so unwohl fühlt wie ich … wenn Sie an den Punkt kommen, an dem Sie Aktionen zum Bearbeiten eingeben, drücken Sie ‘i’, um in den Bearbeitungsmodus zu gelangen. Wenn Sie mit den Änderungen fertig sind, drücken Sie die Escape-Taste und geben Sie dann „:wq“ ein, und es wird Sie vorwärts bewegen. (Mac)

    – Farasi78

    12. September 18 um 18:54 Uhr

  • +1 für die Vorsicht und den Kontext, wann dies zu tun ist. Meiner persönlichen Erfahrung nach ist es gut, wenn Sie alleine an einem Feature-Branch arbeiten und eine Menge trivialer Commits wie „aktualisierte Readme“, „hat etwas getan, das niemanden interessiert“ haben und bereit sind, den Branch zusammenzuführen, vielleicht so Nun, quetschen Sie diese einfach alle in einem Commit. Niemand wird zu Ihrem “hat etwas getan, das niemanden interessiert” zurückkehren wollen und es verschmutzt den Commit-Verlauf

    – Adam Hughes

    28. Februar 20 um 15:54 Uhr

  • Tut git reset --soft HEAD~2 mach das gleiche wie git rebase -i HEAD~2

    – Alper

    29. August 21 um 9:18 Uhr

1643912296 140 Was bedeutet es Commits in Git zu quetschen
Julien López

Es bedeutet, mehrere Commits zu einem zu kombinieren. Schau mal rein:

Squash meine letzten X Commits zusammen mit Git

  • Dein erster Link scheint kaputt zu sein.

    – jdhao

    8. Januar um 15:59 Uhr

  • @jdhao Danke! Ich habe es entfernt.

    – Julien López

    8. Januar um 16:18 Uhr

.

758550cookie-checkWas bedeutet es, Commits in Git zu quetschen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy