Qual è il modo migliore per annullare una fusione Git che cancella i file dal repository?

10

Quindi immagina quanto segue (e che stiamo usando SourceTree):

  1. Stiamo lavorando tutti all'origine / sviluppo.
  2. Vado in vacanza per una settimana.
  3. Il mio collega ha lavorato a livello locale negli ultimi giorni senza fondere l'origine / sviluppare di nuovo la sua filiale di sviluppo locale.
  4. Prova a fare una spinta, gli viene detto che prima deve unirsi e poi fa un tiro.
  5. Ottiene un conflitto, interrompendo il commit automatico dopo la fusione.
  6. Supponendo che Git sia come SVN, il mio collega scarta i "nuovi" file nella sua copia di lavoro e poi commette l'unione - cancellando quei "nuovi" file dal capo di origine / sviluppo.
  7. Una settimana di lavoro di sviluppo continua su quella revisione.
  8. Torno dalle vacanze e scopro che mancano diversi giorni del mio lavoro.

Siamo tutti molto nuovi a Git (questo è il nostro primo progetto che lo utilizza), ma quello che ho fatto per risolverlo è stato:

  1. Rinomina "sviluppa" su "develop_old".
  2. Unisci develop_old in un nuovo ramo "develop_new".
  3. Reimposta il ramo develop_new sull'ultimo commit prima della brutta unione.
  4. Ciliegia sceglie ogni commit da allora, uno per uno, risolvendo i conflitti a mano.
  5. Sposta develop_old e develop_new fino all'origine.

A questo punto, develop_new è, spero, una copia "buona" di tutti i nostri cambiamenti con le settimane di lavoro successive riapplicate. Suppongo anche che il "reverse commit" faccia cose strane in un'unione, specialmente dal momento che le prossime settimane di lavoro si basano su di esso - e dato che quell'unione contiene molte cose che noi facciamo voglio insieme a cose che non facciamo.

Spero che questo non accada mai più, ma se dovesse succedere di nuovo, mi piacerebbe sapere un modo più semplice / migliore per aggiustare le cose. C'è un modo migliore per annullare un'unione "cattiva", quando nel repository si è lavorato molto sul repository basato su tale unione?

    
posta George 30.12.2013 - 04:27
fonte

2 risposte

4

Se ho capito bene, questa è la tua situazione:

    ,-c--c--c--c--M--a--a--X ← develop
o--o--y--y--y--y-´

Dopo un po 'di storia comune (o), hai impegnato e spinto il tuo lavoro (y). Il tuo collaboratore (c) ha funzionato nel suo repository locale e ha fatto una cattiva fusione (M). Successivamente potrebbero esserci ulteriori commit (a) in cima a M.

git reset --hard develop M^2
git branch coworker M^1

Ora il tuo grafico appare esattamente come prima della brutta unione:

    ,-c--c--c--c ← coworker
o--o--y--y--y--y ← develop

Fai una buona unione (G):

git checkout develop
git merge coworker

Risultato:

    ,-c--c--c--c-、
o--o--y--y--y--y--G ← develop

Ora trapianta i commit aggiuntivi:

git reset --hard X
git rebase --onto G M develop

Questo dà il risultato finale:

    ,-c--c--c--c-、
o--o--y--y--y--y--G--a--a--X ← develop

Tieni presente che questo potrebbe causare più conflitti di unione. Inoltre hai appena cambiato la cronologia, cioè tutti i tuoi colleghi devono duplicare / reimpostare / rebase nella nuova cronologia.

PS: ovviamente dovresti sostituire G , M e X nei tuoi comandi con l'id di commit corrispondente.

    
risposta data 09.01.2014 - 03:19
fonte
1

È bene che tu stia pensando a come aggiustare il repository, ma se i tuoi solo collaboratori hanno cancellato nuovi file e non hanno sovrascritto molti aggiornamenti, allora un approccio molto più semplice sarebbe semplicemente ripristina i file che sono stati cancellati.

Probabilmente comincerei provando a selezionare semplicemente (sulla testa attuale) i commit originali in cui hai aggiunto il codice che è scomparso. Se per qualsiasi motivo non funziona, controlla la vecchia revisione con i file che hai aggiunto e aggiungili nuovamente in un nuovo commit.

Quello che descrivi è in realtà un sottoinsieme di un noto anti-pattern di Git, che per la vita di me non riesco a ricordare il nome di - ma il succo è, facendo "modifiche manuali" durante l'unione di Git (Ad esempio, le modifiche che non risolvono i conflitti di merge ma apportano modifiche completamente non valide) sono considerate una pratica estremamente negativa perché sono essenzialmente mascherate dall'unione stessa e sono facilmente trascurate nelle revisioni del codice o nelle sessioni di debug.

Quindi, spiega chiaramente al tuo collega che questo è stato un fallimento epico, ma considera di prendere a schiaffi un cerotto prima di fare un intervento chirurgico maggiore.

    
risposta data 09.01.2014 - 03:50
fonte

Leggi altre domande sui tag