2012-04-17 8 views
5

Considerare il seguente caso:Come trovare il nuovo percorso di un file rinominato di cui è noto il nome originale?

Sto lavorando alla filiale locale mentre il refactoring è stato eseguito sul ramo principale. Ora alcuni file (classi) sono stati rinominati e/o spostati in nuove posizioni. Durante la fusione ottengo molti e molti errori di importazione dovuti alla mancanza di classi.

--A--B--C--D--E-- (master) 
    \   \ 
    F--G--H--I--J (topic) 

In A ci sono i vecchi nomi wich che ho usato in F--G--H--I.

In B--C--D--E i file vengono refactored con conseguente nuovi nomi di file in E. Questo include incatenato rinomina come

B: path/to/File.java    
-> C: path/to/BetterName.java 
-> D: better/package/BetterName.java 
-> E: final/package/FinalName.java 

Ora si fondono risultati in J con molti errori (di compilazione) a causa del refactoring mancanti sul mio ramo. (Perché ho ancora riferisco a path.to.File invece di final.package.FinalName

Per fissare la build rotto, ho bisogno di conoscere i nuovi nomi per le vecchie classi.

Esiste un comando git per ottenere tutti del cambiamento di nome che hanno stato applicato a un particolare file?

+0

funziona il vostro copione? se sì, non ricevo la tua domanda – CharlesB

+0

Sì, funziona, ma mi chiedevo se c'è una soluzione più semplice rispetto allo script di cui sopra. Come devo farlo per ogni file. – helt

+0

Devi dire a 'git log' per trovare i nomi con l'opzione' -M'. Quindi si desidera segnalare solo i nomi e ciò è fatto con l'opzione '--diff-filter'. Ho aggiunto più dettagli alla mia risposta. –

risposta

0

Git dovrebbe trovare i nomi dei file .Tuttavia, se il file ha cambiato il 50% o più righe in quel file, non sarà più considerato un rinominare. soglia se lo si desidera

Ecco il comando per farlo:

git log -M --diff-filter=R --stat 

Mostrerà solo i nomi. Se si desidera modificare la soglia a qualcos'altro diverso da quello predefinito del 50%, si può semplicemente aggiungere il numero all'opzione M:

git log -M90 --diff-filter=R --stat 

prenderà in considerazione solo un file come rinominato se i contenuti sono cambiati da non più del 10%

UPDATE:

Per saltare tutti i passaggi intermedi, utilizzare diff invece. Git seguirà i rinomati per voi:

git diff -M --diff-filter=R --name-status ..master | cut -f2- 

quando siete nel vostro ramo tematico.

È quindi possibile eseguire il piping di questo per creare una serie di istruzioni sed per regolare i riferimenti.

+0

il tuo comando è abbastanza utile ma devo ancora scriverlo per raggiungere il mio obiettivo – helt

+0

che cosa vuoi? È possibile formattare l'output a proprio piacimento. Dovresti essere in grado di collegarlo ad altri comandi se necessario. Non dovresti aver bisogno di seguire la tua storia. –

+0

'git log -M --diff-filter = R --name-status --reverse' fornisce un elenco di tutti i nomi nell'ordine necessario (prima i più vecchi). Ma ho il vecchio nome SOLO. Il problema non è trovare il rinominare diretto del vecchio nome ma trovare anche tutti i successivi nomi successivi. Speriamo che sia piuttosto comprensibile ora. – helt

-1

non riuscivo a trovare una risposta soddisfacente sul web, così ho scritto uno script (imbarazzante) di passare attraverso i registri uno per uno (rinominando rinominandolo)

Utilizzando lo script con sopra esempio fornisce l'uscita follwing:

$ git history path/to/File.java

final/package/FinalName.java

ho aggiunto lo script per il mio ~.bashrc e ha aggiunto un'opzione alias.history=!bash -ic 'git_file_history "[email protected]"' - alla mia globale git config

#! /bin/sh 
### Takes a filename as parameter ($1) 
### Echoes all filenames related to $1 
function git_file_history() { 
     loc_var=$1; 
     old="" 
     while [ "$loc_var" != "$old" ] && [ "$loc_var" != "" ] 
     do 
       old=$loc_var; 
       #echo $loc_var; 
       hashes=$(git log --format="%P %H" -1 --follow -- $loc_var); 
       status=$(git diff --name-status --find-renames $hashes | grep $loc_var); 
       awks=`echo $status | awk '{print $3}'` 
       loc_var=$awks; 
     done 
     echo "$loc_var"; 
}