Domanda

Supponi di avere una cronologia contenente i tre commit A, B e C :

A-B-C

Vorrei combinare i due commit A e B in un unico commit AB :

AB-C

Ho provato

git rebase -i A

che apre il mio editor con i seguenti contenuti:

pick e97a17b B
pick asd314f C

Lo cambio a

squash e97a17b B
pick asd314f C

Quindi Git 1.6.0.4 dice:

Cannot 'squash' without a previous commit

C'è un modo o è semplicemente impossibile?

È stato utile?

Soluzione

Usa git rebase -i --root a partire da Git versione 1.7.12 .

Nel file rebase interattivo, modifica la seconda riga di commit B in squash e lascia le altre righe su pick :

pick f4202da A
squash bea708e B
pick a8c6abc C

Questo combinerà i due commit A e B in un commit AB .

Trovato in questa risposta .

Altri suggerimenti

Hai provato:

git rebase -i A

È possibile iniziare così se si continua con modifica anziché squash :

edit e97a17b B
pick asd314f C

quindi esegui

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

Fatto.

A era il commit iniziale, ma ora vuoi che B sia il commit iniziale. i commit git sono alberi interi, non diff anche se sono normalmente descritti e visualizzati in termini di diff che introducono.

Questa ricetta funziona anche se ci sono più commit tra A e B e B e C.

# 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

Nel caso di rebase interattivo, devi farlo prima di A in modo che l'elenco sia:

pick A
pick B
pick C

diventare:

pick A
squash B
pick C

Se A è il commit iniziale, devi avere un commit iniziale diverso prima che A. Git pensi alle differenze, funzionerà sulla differenza tra (A e B) e (B e C). Quindi la zucca non funziona nel tuo esempio.

Nel caso in cui tu abbia centinaia o migliaia di commit, usando la risposta di kostmo di

git rebase -i --root

può essere poco pratico e lento, solo a causa dell'elevato numero di commit che lo script rebase deve elaborare due volte , una volta per generare l'elenco dell'editor di rebase interattivo (dove si seleziona quale azione intraprendere per ogni commit) e una volta per eseguire effettivamente la re-applicazione dei commit.

Ecco una soluzione alternativa che eviterà in primo luogo il costo di generazione dell'elenco dell'editor di rebase interattivo non utilizzando un rebase interattivo . In questo modo, è simile a Soluzione di Charles Bailey . È sufficiente creare un ramo orfano dal secondo commit, quindi rifare tutti i commit discendenti su di esso:

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

Documentazione

In una domanda correlata, sono riuscito a trovare un approccio diverso alla necessità di schiacciare il primo commit, che è, beh, quello di renderlo il secondo.

Se sei interessato: git: come inserire un commit come primo, spostando tutti gli altri?

Comando Git per squadra: git rebase -i HEAD ~ [numero di commit]

Diciamo che hai una cronologia di commit inferiore a git:


pick 5152061 feat: Aggiunto supporto per il salvataggio dell'immagine. (UN)
pick 39c5a04 Correzione: correzioni di errori. (B)
pick 839c6b3 fix: conflitto risolto. (C)

Ora vuoi schiacciare A e B su AB, esegui i passaggi seguenti:


pick 5152061 feat: Aggiunto supporto per il salvataggio dell'immagine. (UN)
s 39c5a04 Correzione: correzioni di errori. (B)
pick 839c6b3 fix: conflitto risolto. (C)

Nota: per il commit di squash possiamo usare squash o s. Il risultato finale sarà:
pick 5152061 feat: Aggiunto supporto per il salvataggio dell'immagine. (AB)
pick 839c6b3 fix: conflitto risolto. (C)

Devi eseguire un po 'di magia da riga di comando.

git checkout -b a A
git checkout B <files>
git commit --amend
git checkout master
git rebase a

Questo dovrebbe lasciarti con un ramo che ha AB e C come commit.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top