Domanda

Ho un repository git (che copre più o meno la storia del progetto) e separati fonti (solo un tarball con alcuni file), che hanno biforcuta qualche tempo fa (in realtà da qualche parte nel 2004 o 2005).

Le fonti da tarball hanno subito un sacco di cambiamenti da cui mi piacerebbe incorporare alcune. Ora la domanda è -. Come scoprire che cosa era in realtà il punto di diramazione per le sorgenti modificate per ottenere diff minima di quello che è successo lì

Quindi quello che fondamentalmente voglio è quello di trovare un posto nella storia git, in cui il codice è più simile al tarball di fonti che ho. E io non voglio farlo manualmente.

E 'anche opportuno ricordare che le sorgenti modificate comprendono sottoinsieme solo di file e si sono divisi alcuni file in più. Tuttavia il codice che è in là sembrano avere solo piccole modifiche e una serie di aggiunte.

Se si vuole giocare con te stesso che, il tarball con le fonti è qui e Git è ospitato presso Gitorious : git://gitorious.org/gammu/mainline.git

È stato utile?

Soluzione

Nel caso generale, si sarebbe in realtà hanno esaminare ogni singolo commit, perché non hai modo di sapere se si potrebbe avere un enorme diff in un unico, piccolo diff il prossimo, poi un altro diff enorme, quindi un mezzo di diff ...

La cosa migliore è destinata probabilmente ad essere quello di limitarsi a file specifici. Se si considera solo un singolo file, non dovrebbe prendere tempo per scorrere tutte le versioni di quel file (uso git rev-list <path> per ottenere una lista, in modo da non mettere alla prova ogni commit). Per ogni commit che ha modificato il file, è possibile controllare le dimensioni del diff, e abbastanza rapidamente trovare un minimo. Fare questo per una manciata di file, speriamo che sarete d'accordo!

Il modo migliore per impostare voi stessi per il diffing è quello di fare una temporanea commit semplicemente copiando nel tarball, in modo da poter avere un ramo chiamato tarball da confrontare. In questo modo, si potrebbe fare questo:

git rev-list path/to/file | while read hash; do echo -n "$hash "; git diff --numstat tarball $hash path/to/file; done

per avere una bella lista di tutti i commit con le loro dimensioni diff (le prime tre colonne saranno SHA1, il numero di linee aggiunte, e il numero di linee rimosso). Poi si può solo tubo su in awk '{print $1,$2+$3}' | sort -n -k 2, e si avrebbe una lista ordinata di commit e le loro dimensioni diff!

Se non ti può limitarsi a una piccola manciata di file in prova, potrei essere tentato di mano implementare qualcosa di simile a git-bisect - basta provare per restringere la tua strada verso il basso per un piccolo diff, facendo l'ipotesi che in tutti probabilità, commit vicino al vostro migliore dei casi avrà anche diff più piccoli, e si impegna lontano da esso avrà diff più grandi. (Da qualche parte tra il metodo di Newton e un pieno su ricerca binaria / griglia, probabilmente?)

Edit: Un'altra possibilità, suggerita in risposta Douglas' , se si pensa che alcuni file potrebbero essere identica a quelli in qualche commit, è quello di hash utilizzando git-hash-object , e poi vedere che cosa impegna nella vostra storia ha quel blob. C'è una domanda con alcune risposte eccellenti su come farlo. Se si esegue questa operazione con una manciata di file - preferibilmente quelli che hanno cambiato di frequente -. Si potrebbe essere in grado di restringere il target impegnarsi abbastanza rapidamente

Altri suggerimenti

Non è una grande soluzione, ma per ottenere una supposizione di cui revisioni potrebbe essere: Si supponga che alcuni dei file nella palla di catrame non sono state modificate da quando sono stati diramati. Eseguire git hash oggetto gli uni contro gli file nella palla di catrame, quindi cercare i file nel repository utilizzando git spettacolo . Poi cercare di trovare i commit in cui sono stati inclusi i file, possibilmente utilizzando git WhatChanged . La risposta alla tua domanda potrebbe quindi essere il commit con i file più comuni, ma sarà ancora un po 'incostante.

in base a quello che ha detto araqnid mi è venuta 9c6c864426bf88429e77c7e22b5aa78e9295b97a (appena chiesto per le cose tra 0.61.0 e HEAD) questo non è il migliore è probabilmente) si potrebbe fare meglio con qualcosa di simile

git rev-list --no-merges --all | while read rev; do patchsize=$(git diff $rev | wc -c); echo $patchsize $rev; done | sort -n | less

supponendo di aver importato il tarball in git e che hanno la revisione estratto (Ho fatto questo untaring e quindi

git init
git add .
git commit -m "import tarball"
git remote add origin git://gitorious.org/gammu/mainline.git

Quindi, dopo aver fatto questo e la corsa di cui sopra dovrebbe uscita la dimensione di tutte le diff in ordine di patchsize ascendente (il primo sarà 0 poiché accorgerete l'attuale capo) ci vorrà molto tempo ... ma dovrebbe trovare il più piccolo diff ...

come è stata effettuata la forchetta? era un clone che qualcun altro ha fatto e poi ha fatto il proprio lavoro? se è così, allora questo è davvero facile. tutto quello che dovete fare è creare una filiale locale che tira nel codice dalla forcella. git vedrà l'ascendenza della punta ramo biforcuto ad uno dei commit dal repository originale e "unire i puntini" per così dire ... sarà ricollegare la storia dal repository originale alla forcella.

si dovrebbe essere in grado di fare questo:

git remote add thefork git://wherever.it.lives/thefork.git

git fetch thefork

git branch -f thefork-branch thefork/branchname

git checkout thefork-branch

A questo punto, è possibile eseguire gitk e vedere la storia completa del ramo a forcella e il vostro repository locale, e vedere se si collegano o meno.

Importa che i file nel tarball in una revisione git, su un ramo separato o uno completamente nuovo:. La posizione nel grafico di revisione non è importante, vogliamo solo disponibile come un albero

Ora, per ogni revisione in master, solo diff contro quell'albero / revisione ( 'importati') e appena uscita quanto grande sia il diff è. Qualcosa di simile:

git rev-list master | while read rev; do patchsize=$(git diff $rev imported | wc -c); echo $rev $patchsize; done

Quindi, la revisione con la dimensione delle patch più piccolo sarà il "più vicino", da una regola molto approssimativa. (Una revisione identico produrrà una dimensione appezzamento di 0, e qualsiasi altra cosa sarà certamente diverso da zero, e l'altro che è cambiata, il più grande).

Se avete una vaga idea di dove si è verificata la forcella, considerare l'utilizzo di Will Manley git meld . (Vedi anche: Guarda le differenze di rami con fusione ?).

Per fare questo, aggiungere il contenuto tarball al repository (che vi ritroverete a fare in ogni caso). Dopo aver installato Meld e git-meld, eseguire

git meld branch_from_tarball commit_to_check &

su diversi commit fino a trovare quello con meno differenze. Questo comando aprirà meld e visualizzare le modifiche nella struttura di directory tra i commit specificati, con i file identici nascosti. screenshots Esempio:

Meld mostrando due commit molto diverse:
Molto diverso

Mostra due commit simili: Simile

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top