2014-05-18 16 views
5

Recentemente ho riscontrato un problema in cui un file vuoto è stato rinominato in modo diverso in due rami ma è stato unito senza che si verificasse un conflitto.Rilevamento di rinominazione Git del file vuoto

I passaggi per ricreare sono i seguenti.

  1. Creare un file vuoto.

    git init 
    touch empty 
    git add empty 
    git commit -m "add empty file" 
    
  2. Rinominarlo nel ramo.

    git checkout -b branch 
    git mv empty empty-in-branch 
    git commit -m "empty -> empty-in-branch" 
    
  3. Rinominarlo in modo diverso nel master.

    git checkout master 
    git mv empty empty-in-master 
    git commit -m "empty -> empty-in-master" 
    
  4. Unire il ramo al master.

    git merge --no-commit branch 
    

Questo dà il messaggio Automatic merge went well; stopped before committing as requested.

git status mostra solo il nuovo file empty-in-branch. Ma non c'è la cancellazione di empty-in-master quindi se ci impegniamo in questa fase otterremo entrambi i file.

Mi aspetto che questo sia contrassegnato come un conflitto di merge che necessitava di una risoluzione manuale (ovvero decidere quale file vuoto conservare). Questo è ciò che accade se il file originale non è vuoto.

C'è qualcosa di speciale sui file vuoti che influisce sul rilevamento della ridenominazione? Ci sono dei parametri che potrei aggiungere allo git merge che lo otterrà per rilevare il conflitto (ad esempio modificando la strategia di fusione)?

+0

Comportamento interessante di sicuro. Non sei sicuro della causa, ma ... Git memorizza i file in base al loro contenuto. Quindi due file vuoti sarebbero tecnicamente considerati uguali. A causa del potenziale per un numero enorme di sovrapposizioni, avrebbe senso avere una logica speciale qui. – Barett

+0

Sembra che ci possa essere una gestione speciale per i file vuoti. Ma Git memorizza già solo una copia di ciascun oggetto in base al suo hash, quindi non c'è alcuna differenza tra un sacco di file vuoti duplicati e un sacco di file duplicati non vuoti (cioè non è necessario un trattamento speciale dei file vuoti). –

risposta

2

file vuoti non sono più considerati per rinomina su una fusione ricorsivo a partire da questa commettono: https://github.com/git/git/commit/4f7cb99ada26be5d86402a6e060f3ee16a672f16

più vecchio versioni di Git ancora segnalarlo come un conflitto.

$ git --version 
git version 1.7.9.5 
# ... follow OP instructions to reproduce 
$ git merge --no-commit branch 
CONFLICT (rename/rename): Rename "empty"->"empty-in-master" in branch "HEAD" rename "empty"->"empty-in-branch" in "branch" 
Automatic merge failed; fix conflicts and then commit the result. 
$ git status 
# On branch master 
# Unmerged paths: 
# (use "git add/rm <file>..." as appropriate to mark resolution) 
# 
# both deleted:  empty 
# added by them:  empty-in-branch 
# added by us:  empty-in-master 
# 
no changes added to commit (use "git add" and/or "git commit -a") 

Git non implicitamente traccia rinomina, quindi senza la rilevazione di rinomina ciò che finisce accadendo è Git vede solo che sia impegna cancellato il file empty, e che ogni commit aggiunto un nuovo file.

C'è un'opzione per modificare questo comportamento per git-diff (https://github.com/git/git/commit/90d43b07687fdc51d1f2fc14948df538dc45584b), ma attualmente non è esposto in un'opzione a git merge.

Anche le altre strategie di unione non sembrano dare il comportamento desiderato.

+0

Grazie - informazioni utili.Il primo link dice "Ciò causerà un conflitto di modifica/eliminazione sull'unione, che consentirà all'utente di risolverlo da solo", che sfortunatamente non sta accadendo. –

+0

Questo è solo se il file vuoto viene aggiunto contenuto. Puoi guardare il test sul commit e vedere quel comportamento. – onionjake