git reset
è tutto in movimento HEAD
, e in generale il ramo rif .
Domanda: che dire dell'albero di lavoro e dell'indice?
Se utilizzato con --soft
, si sposta HEAD
, aggiornando il ref spesso e solo ilHEAD
.
Questo differisce da commit --amend
come:
- non crea un nuovo commit.
- può effettivamente spostare HEAD su qualsiasi commit (poiché si
commit --amend
tratta solo di non spostare HEAD, pur consentendo di ripetere il commit corrente)
Ho appena trovato questo esempio di combinazione:
- una fusione classica
- un'unione di sottostruttura
tutti in uno (polpo, poiché ci sono più di due rami uniti) commettono unione.
Tomas "wereHamster" Carnecky spiega nel suo articolo "Sottotree Octopus merge" :
- La strategia di unione delle sottostrutture può essere utilizzata se si desidera unire un progetto in una sottodirectory di un altro progetto e successivamente mantenere aggiornato il sottoprogetto. È un'alternativa ai sottomoduli git.
- La strategia di unione polpo può essere utilizzata per unire tre o più rami. La normale strategia può unire solo due rami e se si tenta di unire più di questo, git ricade automaticamente sulla strategia del polpo.
Il problema è che puoi scegliere solo una strategia. Ma volevo combinare i due per ottenere una cronologia chiara in cui l'intero repository viene atomicamente aggiornato a una nuova versione.
Ho un superprogetto, chiamiamolo projectA
, e un sottoprogetto projectB
, che ho unito in una sottodirectory di projectA
.
(questa è la parte di unione dei sottotree)
Mantengo anche alcuni impegni locali.
ProjectA
viene regolarmente aggiornato, projectB
ha una nuova versione ogni paio di giorni o settimane e di solito dipende da una particolare versione di projectA
.
Quando decido di aggiornare entrambi i progetti, non mi limito a estrarre projectA
e projectB
poiché ciò creerebbe due commit per quello che dovrebbe essere un aggiornamento atomico dell'intero progetto .
Invece, creo un unico merge commit che unisce projectA
, projectB
e le mie commit locali .
La parte difficile qui è che questa è una fusione di polpo (tre teste), ma projectB
deve essere unita alla strategia di sottostruttura . Quindi questo è quello che faccio:
# Merge projectA with the default strategy:
git merge projectA/master
# Merge projectB with the subtree strategy:
git merge -s subtree projectB/master
Qui l'autore ha usato a reset --hard
, e quindi read-tree
per ripristinare ciò che le prime due fusioni avevano fatto sull'albero e sull'indice di lavoro, ma è qui che reset --soft
può aiutare:
come rifare quelle due fusioni , che hanno funzionato, ovvero il mio albero di lavoro e l'indice sono bene, ma senza dover registrare quei due commit?
# Move the HEAD, and just the HEAD, two commits back!
git reset --soft HEAD@{2}
Ora, possiamo riprendere la soluzione di Tomas:
# Pretend that we just did an octopus merge with three heads:
echo $(git rev-parse projectA/master) > .git/MERGE_HEAD
echo $(git rev-parse projectB/master) >> .git/MERGE_HEAD
# And finally do the commit:
git commit
Quindi, ogni volta:
- sei soddisfatto di ciò che finisci (in termini di albero di lavoro e indice)
- siete non soddisfatto con tutti i commit che hanno avuto voi per arrivarci:
git reset --soft
è la risposta.
git reset --soft
: stackoverflow.com/questions/6869705/...