231 Stimmen

Die ersten beiden Übertragungen eines Git-Repositorys zusammenfassen?

Angenommen, Sie haben eine Historie, die die folgenden drei Übertragungen enthält A, B y C :

A-B-C

Ich möchte die beiden Übertragungen kombinieren A y B zu einer Verpflichtung AB :

AB-C

Ich habe versucht

git rebase -i A

der meinen Editor mit folgendem Inhalt öffnet:

pick e97a17b B
pick asd314f C

Ich ändere dies in

squash e97a17b B
pick asd314f C

Dann sagt Git 1.6.0.4:

Cannot 'squash' without a previous commit

Gibt es eine Möglichkeit oder ist das einfach unmöglich?

0 Stimmen

0 Stimmen

216voto

kostmo Punkte 5994

Utilice git rebase -i --root ab Git Version 1.7.12 .

Ändern Sie in der interaktiven rebase-Datei die zweite Zeile von commit B a Squash und lassen die anderen Zeilen bei Wählen Sie :

pick f4202da A
squash bea708e B
pick a8c6abc C

Dadurch werden die beiden Übertragungen kombiniert A y B zu einer Verpflichtung AB .

Gefunden in diese Antwort .

127voto

David Lichteblau Punkte 3533

Sie haben es versucht:

git rebase -i A

Es ist möglich, so zu beginnen, wenn Sie mit edit statt squash :

edit e97a17b B
pick asd314f C

dann laufen

git reset --soft HEAD^
git commit --amend
git rebase --continue

Erledigt.

4 Stimmen

Wenn Sie dies tun, um einen Github-Gist zu korrigieren, müssen Sie -m "initial" an den Commit anhängen ;-)

1 Stimmen

git rebase --abort neu anzufangen und es richtig zu machen (nicht den ersten Commit im Editor zu zerquetschen)

69voto

CB Bailey Punkte 693084

A war die erste Übergabe, aber jetzt wollen Sie B Git-Commits sind ganze Bäume, keine Diffs, auch wenn sie normalerweise als Diff beschrieben und betrachtet werden, das sie einführen.

Dieses Rezept funktioniert auch, wenn es mehrere Übertragungen zwischen A und B und B und C gibt.

# Go back to the last commit that we want
# to form the initial commit (detach HEAD)
git checkout <sha1_for_B>

# reset the branch pointer to the initial commit,
# but leaving the index and working tree intact.
git reset --soft <sha1_for_A>

# amend the initial tree using the tree from 'B'
git commit --amend

# temporarily tag this new initial commit
# (or you could remember the new commit sha1 manually)
git tag tmp

# go back to the original branch (assume master for this example)
git checkout master

# Replay all the commits after B onto the new initial commit
git rebase --onto tmp <sha1_for_B>

# remove the temporary tag
git tag -d tmp

1 Stimmen

Dies löst eine massive interaktive Umbasierung aus, wenn ich die git rebase --onto tmp <sha1_for_B>

0 Stimmen

In Anbetracht der Tatsache, dass ich ein brandneues Repo mit nur zwei Commits hatte (die ich zu einem zusammenfassen wollte), funktionierte dies perfekt für mich. Vielen Dank @CB Bailey

14voto

Wenn Sie Hunderte oder Tausende von Übertragungen haben, können Sie mit kostmo's Antwort von

git rebase -i --root

kann unpraktisch und langsam sein, da das Rebase-Skript eine große Anzahl von Übertragungen verarbeiten muss zweimal einmal, um die interaktive Rebase-Editor-Liste zu erstellen (in der Sie auswählen, welche Aktion für jeden Commit durchgeführt werden soll), und einmal, um die Wiederanwendung von Commits tatsächlich auszuführen.

Hier ist ein Alternativlösung das die Zeitkosten für die Erstellung der interaktiven Rebase-Editor-Liste vermeidet durch Verzicht auf eine interaktive Umbasierung an erster Stelle. Auf diese Weise ist es ähnlich wie Charles Baileys Lösung . Sie erstellen einfach eine verwaister Zweig aus dem zweiten Commit und dann alle nachfolgenden Commits darauf zurücksetzen:

git checkout --orphan orphan <second-commit-sha>
git commit -m "Enter a commit message for the new root commit"
git rebase --onto orphan <second-commit-sha> master

Dokumentation

10voto

Loki Punkte 28114

Im Falle einer interaktiven Umbasierung müssen Sie diese vor A durchführen, damit die Liste so aussieht:

pick A
pick B
pick C

zu werden:

pick A
squash B
pick C

Wenn A der initiale Commit ist, müssen Sie einen anderen initialen Commit vor A haben. Git denkt in Differenzen, es wird mit der Differenz zwischen (A und B) und (B und C) arbeiten. Daher funktioniert der Squash in Ihrem Beispiel nicht.

CodeJaeger.com

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.

Powered by:

X