2016-02-01 19 views
5

Scenario: un repository con parti della storia totalmente disconnesse. Per esempio. da diversi telecomandi che non hanno una cronologia git comune. (Questo si verifica in genere in scenari con sottostruttura git.)git cherry-pick un diff tra commit senza storia comune?

E 'possibile selezionare il differenziale tra questi due commit, anche se non hanno una storia comune? (E si impegnano l'attivo non ha una storia comune con uno di questi due)

ho provato questo (in una sottodirectory con -X subtree=sub/dir opzionale):

git cherry-pick -X subtree=vendor/package aaa/aaa..bbb/bbb 

Senza sottostruttura, questo sarebbe stato più semplice:

git cherry-pick aaa/aaa..bbb/bbb 

Dove aaa/aaa e bbb/bbb sono due commit con cronologia disconnessa.

Sfortunatamente, questo non funziona: l'aaa/aaa..bbb/bbb non viene letto come diff, ma qualcos'altro.

Lo stesso può essere visualizzato con git show aaa/aaa..bbb/bbb, che è abbastanza diverso da git diff aaa/aaa bbb/bbb. Per esempio. se entrambi hanno file identici, allora git diff sarà vuoto, ma git show a..b mostrerà solo b, ma non a.


Nota: il mio caso di utilizzo personale è con uno sfondo sottosale. Ne parlo per evitare un caso d'uso artificiale, in cui le persone in genere iniziano a discutere sulla validità del caso d'uso anziché sulla domanda vera e propria.

Una risposta ideale in primo luogo affronterà il caso generale e quindi affronterà il caso del sottoalbero.

risposta

2

Dal cherry-picking applica diff, sarebbe più semplice per create a patch an apply it:

git checkout aaa/aaa 
git cherry-pick -n bbb/bbb 
git diff --cached > my.patch 

Poi checkout vostra filiale regolare e git apply my.patch

Questo richiede commettere 'bbb/bbb', paragona al suo immediato antenato, quindi applica tale differenza sopra 'aaa/aaa': i conflitti possono essere previsti.
Test se -X subtree=vendor/package è utile in caso di sottostruttura.

+0

git apply è una buona idea! Ma non sono sicuro che i tuoi comandi facciano ciò che è promesso. – donquixote

+0

Il problema che vedo con il cherry-pick è che selezionerà solo l'ultimo commit, non l'intero range di commit che porta da aaa/aaa a bbb/bbb (che in realtà non esiste - questo è il punto). – donquixote

2

@VonC punti in una buona direzione. Credito e +1 per questa idea.

sarebbe più semplice per creare una patch di applicarla:

Tuttavia, questo può essere fatto con un semplice one-liner (Ho provato questo, e funziona per me):

git diff aaa/aaa bbb/bbb | git apply --directory=vendor/package 

O in uno scenario di non sottostruttura:

git diff aaa/aaa bbb/bbb | git apply 

non c'è bisogno di git checkout, git cherr y-pick o creazione di un file locale.
Hai quindi ancora bisogno di impegnare questa roba, ovviamente ..

Ed ecco come farlo senza aggiungere e/o scaricare alcun telecomando secondario. Invece, è possibile clonare i repository dei pacchetti in directory separate al di fuori del il repository principale del progetto.

git --git-dir="/path/to/package/repo/.git" diff aaa bbb | git apply --directory=vendor/package 

Il modo in cui ho capito, tutto questo è ancora in gran parte equivalente al solito flusso git subtree lavoro. Voglio dire, la storia del git del progetto principale sarà la stessa. Correggimi se sbaglio.

+0

Certo, un git diff è probabilmente più semplice (ho esitato tra diff e cherry-pick). +1 – VonC