Durante il refactoring del codice sorgente, a volte è necessario spostare grandi blocchi di testo all'interno di un file, o anche in un nuovo file. Si crea un ramo refactored
e si impegnano via:Dire a git di seguire il contenuto spostato (non semplicemente i file spostati)
$git checkout master
$git branch refactored
$git checkout refactored
<move code around>
$git commit -m "refactored code"
Tuttavia, le persone possono impegnarsi in cima al vecchio ramo pre-refactoring, modificando il codice che è stato spostato:
$git checkout master
<change code that was moved elsewhere on branch refactored>
$git commit -m "bugfix"
sul ramo refactored
, è poi desidera incorporare le modifiche apportate in master
:
$git checkout refactored
$git merge master
<giant merge conflict>
Questo porta ad un grande conflitto di unione. Se ci fosse un modo per dire a Git che il contenuto è stato semplicemente spostato, dovrebbe essere possibile unire automaticamente.
La cosa peggiore è che, anche dopo la risoluzione del conflitto e commettere è, git ancora non è possibile utilizzare la risoluzione per capire altre unioni:
<fix conflicts>
$git commit -m "merge master into refactored"
$git checkout master
<change more code>
$git commit -m "bugfix2"
$git checkout refactored
$git merge master
<another giant merge conflict>
E` evitabile a tutti? Ho provato git rerere
e non può risolvere i conflitti qui. C'è un modo in cui git può vedere lo spostamento di un blocco di testo come una mossa reale, invece di una cancellazione e inserimento? Se non è possibile, qual è l'approccio migliore per ridurre al minimo i conflitti di unione, se è necessario mantenere i due rami paralleli per un po '?
Mentre questo è abbastanza facile per moving the contents of a complete file, non riuscivo a trovare informazioni sullo spostamento solo parte di esso, o lo spostamento all'interno dello stesso file.
Inoltre, se esiste una soluzione per questo, quale sarebbe il comportamento di git blame
sul codice refactored ? Indicherebbe il commit del refactoring o lo ignorerebbe? C'è un modo per raggiungere il dopo?
Nel caso in cui qualcuno è interessato, ho messo un Base64 codificato tar.gz del repository (molto minima) che sto utilizzando per il test on pastebin
potenziali soluzioni
Una possibile soluzione potrebbe essere eseguendo il Unisci applicando una patch (automaticamente) modificata con le modifiche nel ramo pre-refactored. C'è un software sviluppato per fare questo? Utilizzando questo approccio, suppongo che, poiché questo è trasparente per git, git blame
farebbe riferimento al commit del refactoring.
Ho trovato the same question, applied to diff. Non c'è alcuna menzione di qualsiasi implementazione non proprietaria, ma c'è menzione ad un algoritmo che regola i movimenti del blocco
vi consiglio di fare più commettere. Quando si modificano molti dati, maggiore è il commit, meno problemi si verificano durante l'unione del codice. – sensorario
@sensorario è un buon suggerimento in generale. Non sono sicuro di come applicarlo al refactoring, tuttavia - spostare una sola funzione/piccoli blocchi alla volta non aiuterà il – goncalopp
Se cambi file, hai due contenuti diversi. Sì, anche se si sposta una funzione da un file a un altro. Se vuoi minimizzare i conflitti, fai sempre più commit. Per favore prova. – sensorario