[Linuxtrent] Re: git: annullare l'effetto di una serie di commit

  • From: Daniele Pizzolli <ors@xxxxxxxx>
  • To: "linuxtrent\@freelists.org" <linuxtrent@xxxxxxxxxxxxx>
  • Date: Thu, 26 Feb 2015 14:29:54 +0100

Michele Bert writes:

> Ciao esperti git.
> Mi sono perso in una ragnatela di branch, e vorrei una mano per
> ritrovre il bandolo!

Proviamoci, tieni conto che non ho verificato tutto perfettamente, anche
perché a volte non mi era chiara nemmeno la richiesta...

> Contesto: lavoro ad un progetto mantenuto su svn con git-svn.
> Sono partito da un branch git (BgBase) allineato con un branch svn 
> (BgBaseSvn).
> Da qui ho creato un branch git (BgAlt), a cui ho accodato alcuni commit.
> Poi sono tornato su BgBase, ed ho committato altre modifiche,
> fortemente in conflitto con quelle del branch BgAlt (sostanzialmente
> sono due possibili soluzioni allo stesso problema). Nel frattempo ho
> tenuto aggiornato il branch BgBase con le modifiche che gli altri
> facevano sul repository centrale.
> Mi trovo quindi in una soluzione del tipo:
>
>          C--D--E              (branch BgAlt)
>        /
> A--B--F--G--H--I--J         (branch BgBase)
>              |
>              |
>              BgBaseSvn

Per fare il disegno in automatico o quasi:

git log --all --graph --decorate --oneline # eventualmente anche 
--simplify-by-decoration

> Diciamo che F e G sono commit che arrivano dal repo remoto, mentre H,
> I, J sono le mie modifiche.

> A posteriori vorrei adottare la soluzione implementata in BgAlt.
> Quindi vorrei eliminare l'effetto dei commit H,I,J,

# teniamo un backup comodo 
git tag tag-su-J J

git reset --hard G

> ed applicare a
> partire da G i commit C, D, E. Però vorrei che il risultato mi
> apparisse come nuovo commit, successivo a J

tecnicamente applicare un commit non ha senso, si applica una patch... o
si fa un merge...

git merge --squash E

> , in modo da non perdere la
> storia. In pratica dovrebbe risultare una cosa tipo:

arrggghhhh! nuovo (unico?) commit e perdere la storia non sono
compatibili!

Forse fa per te merge senza --squash

>
>
>          C--D--E              (branch BgAlt)
>        /
> A--B--F--G--H--I--J--J'--C--D--E         (branch BgBase)
>              |
>              |
>        BgBaseSvn


Mi sono perso J'? Da dove viene? E non volevi eliminare H I J?

Ma li vuoi eliminare o fare il revert?


In ogni caso il risultato del reset e merge senza squash è:

>          C--D--E
>        /        \
> A--B--F-------G--X

> oppure:
>
>                   BgBaseSvn
>                            |
>          C--D--E--F--H              (branch BgAlt)
>        /
> A--B--F--G--H--I--J         (branch BgBase)

qui non ti seguo più!

> Potete darmi qualche suggerimento? Avete qualche suggerimento so come
> avrei potuto affrontare la situazione dall'inizio? (intendo il fatto
> di voler provare due soluzioni alternative, e solo a posteriori
> decidere quale delle due applicare alla "mainline")

git branch solution_a mainline_commit
git branch solution_b mainline_commit

....

git checkout mainline_branch
git merge solution_x

Potresti usare un rebase al posto del merge, ma (ogni soluzione ha pro e
contro, ben descritti in vari blog/post/manuali).

Inizia col merge, il rebase lo consiglio quando hai un po' di pratica,
rischia di confonderti più del dovuto.

Buon divertimento,
Daniele

PS: Tra parentesi ho presentato lunedì ai miei colleghi git in una 50 di
comandi in 40 minuti, se c'è interesse posso ristrutturare la
presentazione e fare una serata, mooolto informale.
--
Per iscriversi  (o disiscriversi), basta spedire un  messaggio con OGGETTO
"subscribe" (o "unsubscribe") a mailto:linuxtrent-request@xxxxxxxxxxxxx


Other related posts: