2012-10-08 14 views
12

Domande su come rinominare i file in Git havebeenasked prima, ma non riesco a trovare una soluzione al mio problema specifico.Ottenere Git per seguire file rinominati e modificati

Ho spostato e modificato più file (non ho usato git mv - sfortunatamente è troppo tardi per quello). Ora lo voglio così quando il mio collega tira fuori dal mio repository, avendo apportato le sue stesse modifiche a quegli stessi file (senza spostarli), riesce a unire le mie modifiche con il suo nella nuova posizione del file. Per unire con successo, Git ha chiaramente bisogno di sapere che questi sono gli stessi file.

Git è abbastanza intelligente per funzionare da solo? Sembra difficile da credere. E se è così, come posso essere sicuro che un particolare movimento del file verrà raccolto da Git - anche se il contenuto è cambiato?

+1

Questo è lo scopo di 'git mv'. – ezod

+0

Ok, ma come faccio a dire a Git che un file * ha * spostato? Ho spostato i file in Visual Studio, ora voglio assicurarmi che Git lo sappia. Ho provato 'git mv --cached' ma questo non esiste. Quando provo 'git mv' ottengo' fatal: bad source, source = ... ' –

+0

Se non hai ancora eseguito il commit, puoi semplicemente spostare i file nei loro percorsi originali, e quindi' git mv' li per i nuovi percorsi. – ezod

risposta

16

Git in realtà non tiene traccia dei nomi nel repository, utilizza un'euristica diff per determinare se il file è stato rinominato in un altro. Vale a dire, se si copia un file git mv e si sostituisce completamente il contenuto, è non considerato un rinominare, e si fa non necessario per utilizzare git mv affinché rilevi i nomi.

Ad esempio:

% mv d.txt e.txt 
% git rm d.txt 
rm 'd.txt' 
% git add e.txt 
% git commit -m"rename without git mv" 
[master f70ae76] rename without git mv 
1 file changed, 0 insertions(+), 0 deletions(-) 
rename d.txt => e.txt (100%) 
% git diff --summary --find-renames HEAD~1 HEAD 
rename d.txt => e.txt (100%) 

Allo stesso modo, git mv non significa che il file verrà rinominato, sarà ancora utilizzare l'algoritmo diff:

% git mv e.txt f.txt 
% echo "Completely replacing f.txt" > f.txt 
% git add f.txt 
% git commit -m"git mv doesn't help here" 
[master 068d19c] git mv doesn't help here 
2 files changed, 1 insertion(+), 14 deletions(-) 
delete mode 100644 e.txt 
create mode 100644 f.txt 
% git diff --summary --find-renames HEAD~1 HEAD 
delete mode 100644 e.txt 
create mode 100644 f.txt 
7

Per impostazione predefinita, git controlla la presenza di nomi quando un file viene rimosso tra commit - non è necessario specificarlo manualmente. Se si sposta effettivamente un file (con git mv, invece di rimuoverlo manualmente e aggiungerlo di nuovo) ignora il suggerimento. Per motivi di prestazioni, l'euristica non viene eseguita continuamente: se sposti un file e ne aggiungi uno nuovo con il nome originale, la mossa potrebbe non essere rilevata.

Si noti che logicamente, git memorizza solo l'albero come esisteva in ogni revisione: non è archivio qualsiasi informazione di tracciamento sulle modifiche apportate tra le revisioni.

Se si desidera vedere cosa viene rilevato, è possibile utilizzare lo switch -M (--find-renames) su git diff per visualizzare i nomi. Questo interruttore attiva anche l'euristica, che è utile se hai un commit che non li attiva.

Questo approccio euristico è una buona ragione (se ne serviva un altro) per mantenere i commit piccoli e autonomi, in quanto ciò rende più facile il lavoro di git.

1

git diff non stava prendendo che ho 'd i file rinominati e hanno alterato il loro contenuto. Il mio scenario era che avevo i file A, B, C e inserito un nuovo B, quindi il vecchio B adesso era C, e il vecchio C adesso D. git diff mi stava dicendo che B e C ora erano completamente diversi!

La soluzione che ho usato era noiosa e manuale, ma ho fatto il lavoro.

  1. Ha rinominato i file, come meglio potevo. Cioè B to Bnew, da C a B, da D a C.
  2. Il diff, per controllare nessun errore.
  3. Impegnato.
  4. Utilizzato git mv per rinominare i file ai loro nuovi nomi. Da B a C, da C a D.
  5. Impegnato.
  6. Gli altri nomi si sono rinominati e li hanno commessi come nuovi file. Cioè Da Bnew a B.
Problemi correlati