Rinominare i nomi: svn vs. git vs. mercurial

In che modo ciascuno di questi VCS gestisce i nomi?

Ho trovato molte informazioni contraddittorie che affermano che git traccia LOC (linee di codice) invece di file, quindi i nomi dei nomi non avrebbero alcun significato.

  • Git non tiene traccia dei nomi, ma usa l’euristica per riscoprirli durante l’unione, ecc.
  • Rinomina delle tracce Mercurial (la versione di origine e il file di origine sono registrati) e utilizza tali informazioni durante le unioni. Quindi devi dire esplicitamente hg su come rinominare con hg mv , o usare hg addremove --similarity per l’auto-discovery. Si è parlato dell’aggiunta dell’euristica anche durante l’unione.
  • Svn rintraccia i nomi, ma non so quanto li tratti con loro durante le unioni (mai effettivamente testato).

Idiota

Git è diverso in quanto non rinominare il tracciamento , il che significa che non è necessario dirlo sui nomi dei nomi utilizzando i comandi SCM per rinominare (o eseguire lo script di autodeterminazione per contrassegnare i nomi prima del commit) e non salva tali informazioni nel repository, ma rinominano il rilevamento . Ciò significa che trova rinomina usando l’algoritmo euristico basato sulla similarità del nome file e del file, sia durante l’unione che per diff quando richiesto tramite l’opzione -M (o configurato usando l’opzione di configurazione diff.renames ).

I vantaggi di questo metodo sono i seguenti:

  • non è necessario che i nomi vengano contrassegnati (o rilevati) in modo esplicito: i nomi dei nomi possono provenire da una patch, oppure possono essere eseguiti vie filemanager o interfaccia grafica
  • l’algoritmo di rilevamento della somiglianza può essere migliorato e non viene congelato al momento del commit, come nel caso di rilevamento di rinomina per contrassegnarle prima del commit e salvataggio di queste informazioni nel repository; è anche più facile gestire gli errori di rilevamento della ridenominazione se non sono congelati nella storia
  • segue l’ophilosophy di Git che è il contenuto che conta; vedi come git blame (e i frontend grafici come “git gui blame”) possono seguire il movimento di blocchi di codice attraverso i limiti dei file, qualcosa che è più generico di quello dei nomi di file di wholesame.
  • lo stesso meccanismo è responsabile della gestione delle ridenominazioni durante le unioni; utilizzando il rilevamento del nome significa che può essere fatto per 3 commit che si fondono in ultima analisi, e non c’è bisogno di seguire attentamente la cronologia, annotando ogni rinominazione – o un concetto non distribuito di nome canonico di un file

Nota che il filtraggio di pathspec non funziona bene con il rilevamento della rinomina; se si desidera seguire la cronologia di un file con più git log --follow utilizzare ” git log --follow

In pratica:

Git rileva automaticamente i nomi. (Per inciso, ho sentito affermazioni che Git può rilevare quando si sposta una funzione da un file all’altro.I miei test iniziali sembrano indicare che non è questo il caso, comunque.)

Con Mercurial, devi dirlo esplicitamente sui nomi dei file, sia con hg mv , sia con l’opzione --similarity di hg addremove , o con l’opzione “guess rinomina” di TortoiseHg, o alcuni strumenti, ad esempio VisualHg, ti indicheranno i nomi. Se si desidera utilizzare l’approccio Git con Mercurial, ho scritto un’estensione per rilevare i nomi dei nomi al momento del commit , ma al momento è in una fase molto sperimentale.

Subversion non gestisce affatto i nomi . Registra un nuovo nome quando viene rimosso un file e viene aggiunto un altro file. Ciò significa, ad esempio, che se Alice cambia un file e Bob lo rinomina, si ottiene un conflitto ad albero. Questo succede se stai facendo branching e merging in piena regola o semplicemente svn update . Rinominare il tracciamento è pianificato per Subversion 1.8, che uscirà il prossimo anno.

Hai sentito bene, un po ‘.

Git funziona sui contenuti dei file, non sui file stessi, quindi i nomi dei nomi sono tecnicamente privi di significato. Per git, un rinominare sembra che il file A è scomparso e il file B è apparso con lo stesso contenuto di A. Ma git è in realtà abbastanza bravo a capire quando un file è stato effettivamente rinominato.

Provalo: rinominare un file, quindi eseguire ‘git rm oldname’ e ‘git add newname’ per dire a git di mettere in scena le modifiche, quindi eseguire ‘git status’ per vedere cosa git pensa che stia facendo – vedrai che dice il file è stato rinominato. Non sono sicuro che questo significhi qualcosa più tardi, però. Guarda un commit con ‘git show’ e non vedrai alcuna menzione di un rinominare, solo un gruppo di linee rimosse da un percorso e aggiunte ad un altro.

In alternativa, puoi anche usare il comando ‘git mv’ per rinominare un file. Non cambia il modo in cui git vede l’operazione, ma in modo efficace fa ‘mv oldname newname’, ‘git rm oldname’ e ‘git add newname’ in un solo passaggio.

Per una panoramica di Mercurial, vedi la risposta di tonfa .

SVN, d’altra parte, non può rilevare i nomi, ma deve essere informato su di essi con il comando ‘svn mv’. Quando viene detto, tuttavia, rintraccia i nomi come modifiche di “prima class”, quindi quando visualizzi il log delle modifiche più avanti vedrai che la modifica è stata rinominata.

Non suggerirei di scegliere un SVN su git o mercurial basato su questa funzione, però. Ci sono differenze molto più grandi e più importanti tra gli strumenti. Deciderei prima se si desidera un sistema di controllo della versione distribuito (git o mercurial) o un sistema di controllo della versione centralizzato (svn).

Un’altra cosa su git che non è stata ancora menzionata, oltre a usare l’euristica per determinare se un rinominato è successo:

Se un file o anche un intero albero di directory viene rinominato, copiato o spostato, e nulla al di sotto viene modificato in alcun modo, quindi il file o l’albero viene effettivamente memorizzato come lo stesso object all’interno del repository e non prende in più spazio.

Se lo modifichi, viene memorizzato come un nuovo object, come al solito.

Non sono sicuro di hg e svn, ma sospetto che le loro architetture orientate al changel significano che si comportano diversamente in questo scenario. Non ha alcun effetto sull’utilizzo, tranne che potrebbe darti ragione per evitare di spostare o copiare enormi alberi all’interno del tuo repository.

git tiene traccia dei contenuti, non dei file. non sono sicuro di mercurial, ma svn deve essere esplicitamente detto sui nomi