2013-09-24 4 views
8

Mattina tutto, Diciamo che ho una serie di commit nel modo seguente:escludere un singolo commit da una "git diff"

  • abc000
  • def111
  • abc222
  • def333
  • abc444
  • def555

So che posso usare

$ git diff -c --binary abc000..def555 > /tmp/abc000_def555.patch 

per produrre una patch per aggiornare un sistema da abc000 a def555.

Ma cosa succede se volevo (per motivi per ottenerne ottusità) escludere def333 dalla patch - come posso fare questo? Nota che non voglio ripristinare def333, è solo che non voglio che la patch incorpori questo commit.

Grazie

risposta

1

direi di creare un nuovo ramo, ciliegia scegliere i commit avete bisogno e poi fare il diff

7

realtà tuttigit diff s sono commit-coppia-saggio: quanto sopra confronta gli alberi/i file in abc000 contro quelli in def555. Ad esempio, se dir/file sostituisce dir/file con 10 tra abc000 e 6 (ad esempio, la modifica di def333 viene annullata da qualcosa lungo il percorso) è possibile che non ci sia il numero dir/file.

In generale, però, le modifiche apportate def333 avranno modificato dir/file in modo che si presenta quando si confrontano la versione abc000 contro quello in def555. Quindi vedrai il cambiamento probabilmente.

Il modo più semplice per ottenere un diff che indica "ciò che def555 potrebbe apparire come se def333 stati ritornato" è quello di fare proprio questo: creare un albero (su un ramo temporaneo) con il cambiamento ritornato. Per farlo con un ramo reale di nome, si potrebbe fare qualcosa di simile:

git checkout def555 # by ID, so that you get a "detached HEAD" 
git checkout -b temp-branch 
git revert --no-edit def333 
git diff [options] abc000 
git checkout somebranch; git branch -D temp-branch 

Che cosa succede se non si vuole un ramo temporaneo? Bene, è banale: basta non crearne uno. Ottieni un "HEAD distaccato" come sopra, effettua il ripristino come sopra, quindi git checkout somebranch. Non c'è un ramo temporaneo da eliminare, ad eccezione di quello senza nome che git ti avverte che ti stai lasciando alle spalle ... che è proprio quello che volevi.

+1

Si potrebbe anche usare 'revert --no-commit', quindi non sarebbe necessario un ramo (o una testa staccata) e non lasciare nulla dietro. – Bergi

+0

@Berg: true (anche se sarà necessario 'git reset --hard' per pulire l'albero di lavoro una volta che hai finito). – torek

3

Non è possibile git diff ed escludere uno o più commit. Devi fare un nuovo ramo, ripristinare i commit indesiderati, quindi diff e fare una patch:

git checkout -b <branch-name>-diff-branch // Create a throwaway branch. 
git revert <unwanted-sha> // Get rid of the unwanted commit. Do this as many times as necessary, you cannot revert multiple SHAs at once. 
git diff > new.patch // Create your new patch. 
git checkout - // Checkout previous branch, nice trick eh?! 
git branch --delete --force <branch-name>-diff-branch // Delete the throwaway branch. 

P.S. Non volevo macellare troppo la risposta di Torek così ne ho pubblicato uno nuovo che penso sia più conciso.

0

Si potrebbe provare a utilizzare git rebase -i e quindi rilasciare il commit non necessario. Un altro modo è scegliere i commit di cui hai bisogno su un ramo diverso.