2015-04-08 15 views
30

Sto provando a eseguire il rebasing dello script e il mio script avrà percorsi diversi a seconda che il rebase abbia dei conflitti.Esiste una sorta di 'git rebase --dry-run', che mi avviserebbe in anticipo dei conflitti?

C'è un modo per determinare se un rebase provocherebbe conflitti prima di eseguire il rebase?

+0

Qual è la forma esatta del comando 'git rebase' che stai utilizzando? Stai usando delle bandiere opzionali? E quale linguaggio di scripting stai usando? Conchiglia? – Jubobs

+3

Se si esegue 'git rebase' e ​​si verifica un conflitto di unione, il processo si interromperà e si chiuderà con uno stato diverso da zero. È possibile controllare lo stato di uscita dell'operazione rebase e, se è diverso da zero, eseguire 'git rebase --abort' per annullare l'operazione. – Jubobs

+1

Hai trovato un modo per farlo? – crmpicco

risposta

25

Al momento della scrittura (Git V2.6.1 v2.10.0), il comando git rebase offre alcuna opzione --dry-run. Non c'è modo di saperlo, prima di tentare effettivamente un rebase, se o meno si imbatteranno in conflitti.

Tuttavia, se si esegue git rebase e si verifica un conflitto, il processo si interromperà e si chiuderà con uno stato diverso da zero. Che cosa si potrebbe fare è controllare lo stato di uscita del funzionamento rebase, e, se è diverso da zero, eseguire git rebase --abort per annullare il rebase:

git rebase ... || git rebase --abort 
+1

E se il rebase ha successo, ma mi rendo conto che voglio tornare indietro? Ad esempio, perché non voglio forzare la spinta. – bluenote10

+0

@ bluenote10 È possibile utilizzare il [reflog] del ramo (https://git-scm.com/docs/git-reflog) per reimpostarlo sul commit che viene utilizzato per puntare prima del rebase. – Jubobs

4

Ho il sospetto che git rebase ... --dry-run non è possibile, per il seguente motivo.

Quando si esegue uno git rebase, git eseguirà il rollback al punto di partenza, quindi applicherà in modo incrementale le patch per ogni commit per aggiornare il ramo. Se incontra un conflitto, si fermerà & e attendi che tu risolva il conflitto prima di continuare. Il percorso intrapreso da rebase dopo tale conflitto dipende dal modo in cui risolvi il conflitto: se lo risolvi in ​​un determinato modo, ciò potrebbe introdurre (o eliminare) conflitti successivi.

Così, git rebase ... --dry-run sarebbe solo in grado di darvi il conflitto prima - segnalazioni di conflitti successivi dipenderà da come quel primo conflitto è risolto.

L'unico modo in cui posso pensare di farlo sarebbe tramite git diff tra la posizione corrente e l'ultimo commit nel ramo a cui si sta riposizionando. Ma questo non ti darà davvero quello che stai cercando - hai solo bisogno di un elenco di in conflitto tra cambiamenti tra i due punti. Ci potrebbe essere un modo per farlo con git diff, ma non è una patch normale.

3

È ancora possibile eseguire git rebase, giocare con esso come si desidera, piuttosto che recuperare tutte le modifiche precedenti. Supponendo di aver fatto il vostro rebase di qualche ramo in master, e non piace:

  1. git reflog -20 - ti dà ultime 20 posizioni della testa con una piccola descrizione
  2. git checkout <the_branch_name> - pone la vostra TESTA sul ramo
  3. git reset --hard <old_sha1_found_in_reflog> - posiziona il TESTO e il ramo sul vecchio riferimento, in questo modo è possibile recuperare il vecchio ramo.

ci sono alcuni meccanici per capire qui:

  1. È Non eliminare mai nulla in git, non con i comandi, in ogni caso. È il garbage collector che passa attraverso e cancella rami non referenziati (predefinito 3 mesi). Quindi il tuo ramo, da prima del rebase, esiste ancora.
  2. Lo stesso vale per lo stesso rebase del ramo, è solo un nuovo albero riscritto accanto a quello vecchio.
  3. Tutta la storia del rebase e l'altra su manipolazioni HEAD è scritto nel reflog
  4. È possibile utilizzare @{N} annotazioni da reflog

Quindi, nulla è perduto dopo la rebase, basta sapere come per trovarlo e recuperarlo.

Ad esempio, è possibile inserire un tag prima dello rebase piuttosto che ripristinarlo o eliminarlo. ti sfugge tutti i passaggi di ricerca SHA1.

1

Se si desidera solo per vedere se il rebase sarebbe successo, ma poi si vuole "rollback", si può sempre puntuale reposition the branch tip nuovo all'originale commettere. Basta taggare o prendere nota dello SHA originale.

O forse più facile, creare un nuovo ramo temporaneo in cui "mettere in scena" la rebase:

git checkout your-branch 
git checkout -b tmp 
git rebase other-branch 

Se fosse successo, ma si vuole "rollback", your-branch è intatta. Solo git branch -D tmp e sei di nuovo al punto di partenza.

Se ci sono stati conflitti e hai fatto un po 'di lavoro per risolverli e tu ora vuoi mantenere il rebase, basta riposizionare il tuo diramazione a tmp (e poi git branch -D tmp).