2011-09-20 2 views
10

Diciamo che ho la seguente situazione:Git diff sul ramo dell'argomento, escluso il commit di unione che è accaduto nel frattempo?

B---D---F---G topic 
/ /
--A---C---E master 

a scopo di revisione del codice, vorrei tirare fuori un diff dal commettere un commettere G, ma non compresi commit E e C, che è accaduto sul ramo principale e inoltre non include il commit F che è un commit di unione.

In altre parole, vorrei generare un diff che contiene le modifiche da F a G e aggregare tali modifiche con modifiche dalla A alla D.

In altre-altre parole, voglio che la revisione diff di contenere solo le mie modifiche dal ramo dell'argomento, non includendo un gruppo di codice dal master che è accaduto nel frattempo.

È possibile? Se git non è in grado di gestire tali "aggregazioni di diff", sarei molto grato se qualcuno possa fornire alcuni suggerimenti su come un comando esterno può farlo (in modo che possa provare a scrivere uno script bash che farebbe il trucco).

+0

Che dire del checkout del file in A e G commit separatamente e fare una vim diff ??? –

+0

Ho bisogno del diff per tutti i file, non un singolo file. Inoltre, penso che ciò che stai suggerendo includerà anche le modifiche introdotte dal merge commit. –

risposta

4

Se non ti interessa cosa c'è nella parte "contesto" delle diff, allora git diff master..topic ti darà quello che vuoi. Eventuali modifiche introdotte in C e E sono considerate parte della "base" del diff, quindi le modifiche da master saranno presenti nel contesto, ma solo le modifiche effettive apportate nel ramo dell'argomento saranno contrassegnate con + o - come modifiche . Di solito è ciò che le persone vogliono per le revisioni del codice.

Se invece si desidera agire come l'unione non è mai avvenuto, si dovrà rebase fuori:

git rebase --onto A master 
+2

Grazie a Karl, 'git diff master..topic' ha funzionato. Si scopre che ho dovuto fondere il master in topic prima di eseguire lo script diff. –

1

Che dire:

  1. argomento git checkout

  2. git checkout -b temperatura

  3. git tornare F

  4. git diff Un

Successivamente è possibile rimuovere felicemente il ramo temporaneo.

1

La risposta da Karl è fuorviante:

git diff non funziona mai su intervalli adeguati (cioè più commit), solo tra due commit!

La sintassi dell'intervallo ha un significato speciale per git diff.

git diff E..G è sempre uguale a git diff E G (e
git diff E...G è uguale a git diff E G in questo caso, poiché E è l'unione base tra i due).

git diff master...topic è ciò che si desidera in questo e nel caso generale: vi mostra tutti i cambiamenti del ramo argomento, confrontandola con l'ultimo merge-base (cioè contrapponendola a padroneggiare quando è stato fuso l'ultima volta , ignorando tutte le successive modifiche nel master che comunque non si trovano nel branch dell'argomento).

Nota: (? Per coincidenza) purtroppo l'effetto di x..y in git log, ecc è meglio rappresentato da x...y in git diff e viceversa!

+1

Sì, questa è la risposta giusta. Dal manuale: "git diff A ... B" è equivalente a "git diff $ (git-merge-base A B) B". – jmiserez