Frage

    

Diese Frage bereits eine Antwort hier:

         

Mit git rebase --interactive <commit> können Sie beliebig viele quetschen von begeht zusammen in einen einzigen.

Das ist alles toll, wenn Sie zu zerquetschen wollen verpflichtet, in die Anfangs begehen. Das scheint unmöglich zu tun.

Gibt es Möglichkeiten, es zu erreichen?


Mäßig bezogen werden:

In einer verwandten Frage konnte ich mit einem anderen Ansatz, um die Notwendigkeit von Quetschen gegen den ersten verpflichten kommen, das ist gut, es ist die zweiter zu machen.

Wenn Sie Interesse: git: wie einfügen einer Festschreibung als die ersten, Verschieben aller anderen

War es hilfreich?

Lösung

Update Juni 2012 ( git 1.7.12 + )

Sie können nun rebase alle root verpflichtet auf, und wählen Sie die zweite begehen Y mit dem ersten X zerquetscht werden.

git rebase -i --root master

pick sha1 X
squash sha1 Y
pick sha1 Z
git rebase [-i] --root $tip
     

Mit diesem Befehl kann nun verwendet werden, die ganze Geschichte neu zu schreiben von „$tip“ bis auf die Wurzel führende commit.

Siehe verpflichten df5df20c1308f936ea542c86df1e9c6974168472 auf GitHub von Chris Webb (arachsys) .


Original Antwort (Februar 2009)

Ich glaube, Sie verschiedene Rezepte für die in der SO Frage finden " Wie ich die ersten beiden Commits eines Git Repository kombinieren Sie? "

Charles Bailey sofern die meisten ausführlicher Antwort , uns daran zu erinnern, dass eine Festschreibung ist ein Full-Baum (nicht nur Diffs aus einem früheren Staaten).
Und hier begehen die alte (die „Anfängliche commit“) und die neue commit (Ergebnis der Quetschung) wird keine gemeinsamen Vorfahren haben.
Das bedeutet man kann nicht „commit --amend“ die Anfänge in neue begehen, und dann rebase auf den neuen Anfang die Geschichte der früheren Anfänge begeht commit (viele Konflikte)

(Der letzte Satz ist nicht mehr wahr mit git rebase -i --root <aBranch>)

Rather (A mit der ursprünglichen „Anfängliche commit“ und eine nachfolgende B commit benötigt in gestaucht werden die anfänglichen):

  1. zum letzten Zurück verpflichten, dass wir die Anfänge bilden wollen commit (trennen HEAD):

    git checkout <sha1_for_B>
    
  2. Setzen Sie den Zweig Zeiger auf die Anfangs begehen, aber den Index verlassen und Arbeits Baum intakt:

    git reset --soft <sha1_for_A>
    
  3. Änderung des ursprünglichen Baum den Baum von 'B' mit:

    git commit --amend
    
  4. Zur Zeit markieren, diese neue Ausgangs commit (oder man könnte die neue begehen SHA1 manuell erinnern):

    git tag tmp
    
  5. Gehen Sie zurück zu dem ursprünglichen Zweig (nehmen Master für dieses Beispiel):

    git checkout master
    
  6. Replay all Commits nach B auf den neuen Anfang begehen:

    git rebase --onto tmp <sha1_for_B>
    
  7. Entfernen Sie den temporären Tag:

    git tag -d tmp
    

Auf diese Weise die „rebase --onto“ führt keine Konflikte während der Zusammenführung, da es Geschichte Rebasing , die nach der letzten commit (B) in den ersten ein zerquetscht werden (das war A) zu tmp (die die zerquetschten neue Anfangs Festschreibung): Trivial vorspulen verschmilzt nur.

Das ist für „A-B“ funktioniert, aber auch „A-...-...-...-B“ (eine beliebige Anzahl von Commits in die Ausgangs man diese Art und Weise zerquetscht werden kann)

Andere Tipps

Ich habe VonC Drehbuch überarbeitet alles zu tun, automatisch und fragen Sie mich nicht für alles. Sie geben ihm zwei SHA1s begehen und es wird alles zwischen ihnen in einer Festschreibung dem Namen „zerquetschten Geschichte“ Squash:

#!/bin/sh
# Go back to the last commit that we want
# to form the initial commit (detach HEAD)
git checkout $2

# reset the branch pointer to the initial commit (= $1),
# but leaving the index and working tree intact.
git reset --soft $1

# amend the initial tree using the tree from $2
git commit --amend -m "squashed history"

# remember the new commit sha1
TARGET=`git rev-list HEAD --max-count=1`

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

# Replay all the commits after $2 onto the new initial commit
git rebase --onto $TARGET $2

Für das, was es wert ist, vermeide ich dieses Problem, indem immer ein „no-op“ creating erster begehen, in denen das einzige, was im Repository ist eine leere .gitignore:

https://github.com/DarwinAwardWinner/ git-custom-Befehle / Blob / Master / bin / git-myinit

Auf diese Weise ist es nie ein Grund zu Chaos mit dem ersten begehen.

Wenn Sie einfach zerquetschen wollen, dass alle in einem einzigen verpflichtet, verpflichten initiale, nur das Repository zurückgesetzt und ändern die erste commit:

git reset hash-of-first-commit
git add -A
git commit --amend

Git-Reset wird den Arbeits Baum intakt lassen, so ist alles noch da. So fügen Sie einfach die Dateien mit git Befehle hinzufügen und ändern die erste mit diesen Änderungen. Im Vergleich zu rebase -i Sie die Fähigkeit verlieren würden, obwohl die git Kommentare zu fusionieren.

Dies wird zerquetschen zweites begehen in die ersten:

A-B-C-... -> AB-C-...

git filter-branch --commit-filter '
    if [ "$GIT_COMMIT" = <sha1ofA> ];
    then
        skip_commit "$@";
    else
        git commit-tree "$@";
    fi
' HEAD

Commit Nachricht für AB wird von B genommen werden (obwohl ich von A vorziehen würde).

Hat die gleiche Wirkung wie Uwe Kleine-König Antwort, funktioniert aber für nicht-Initiale A als auch.

Quetschen des ersten und zweiten begehen würde in der ersten neu geschrieben commit wird. Wenn Sie mehr als einen Zweig haben, dass die erste verpflichten basiert weg ist, würde man diesen Zweig abgeschnitten.

Betrachten Sie das folgende Beispiel:

a---b---HEAD
 \
  \
   '---d

a und b in eine neue begehen "ab" Quetschen in zwei verschiedene Bäume ergeben, die in den meisten Fällen ist nicht wünschenswert, da git-merge und git-rebase wird nicht mehr über die beiden Zweige arbeiten.

ab---HEAD

a---d

Wenn Sie wirklich wollen, es kann getan werden. Werfen Sie einen Blick auf git-filter-branch für ein leistungsfähiges (und gefährlich) Werkzeug für die Geschichte neu zu schreiben.

Sie können git filter-branch dafür. z.

git filter-branch --parent-filter \
'if test $GIT_COMMIT != <sha1ofB>; then cat; fi'

Dies führt zu einem AB-C den Commit-Log von A Wegwerfen.

Sie könnten rebase verwenden interaktive die letzten beiden Commits zu ändern, bevor sie zu einem entfernten geschoben haben

git rebase HEAD^^ -i

Es ist ein einfacher Weg, dies zu tun. Nehmen wir an, Sie auf dem master Zweig sind

Erstellen Sie einen neuen verwaisten Zweig, der alle begehen die Geschichte wird entfernen:

$ git checkout --orphan new_branch

Fügen Sie Ihre erste Nachricht begehen:

$ git commit -a

Lassen Sie sich von dem alten unmerged master-Zweig los:

$ git branch -D master

Benennen Sie Ihre aktuellen Zweig new_branch master:

$ git branch -m master
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top