2014-05-18 3 views
5

Ich traf vor kurzem ein Problem, bei dem eine leere Datei in zwei Zweigen anders umbenannt wurde, aber ohne einen Konflikt zusammengeführt zusammengeführt.Git umbenennen Erkennung von leeren Datei

Schritte zum Wiederherstellen sind wie folgt.

  1. Erstellen Sie eine leere Datei.

    git init 
    touch empty 
    git add empty 
    git commit -m "add empty file" 
    
  2. Benennen Sie es in der Branche um.

    git checkout -b branch 
    git mv empty empty-in-branch 
    git commit -m "empty -> empty-in-branch" 
    
  3. Im Master umbenennen.

    git checkout master 
    git mv empty empty-in-master 
    git commit -m "empty -> empty-in-master" 
    
  4. Zweig in Master zusammenführen.

    git merge --no-commit branch 
    

Dies gibt die Nachricht Automatic merge went well; stopped before committing as requested.

git status zeigt nur die neue Datei empty-in-branch. Aber es gibt keine Löschung von empty-in-master, also wenn wir zu diesem Zeitpunkt committen, werden wir beide Dateien bekommen.

Ich würde erwarten, dass dies als Merge-Konflikt gekennzeichnet wird, der manuelle Auflösung benötigt (d. H. Entscheidung, welche leere Datei zu behalten). Das passiert, wenn die Originaldatei nicht leer ist.

Gibt es etwas Besonderes an leeren Dateien, das sich auf die Erkennung von Umbenennungen auswirkt? Gibt es irgendwelche Parameter, die ich der git merge hinzufügen könnte, um den Konflikt zu erkennen (z. B. Feinabstimmung der Merge-Strategie)?

+0

Interessantes Verhalten für sicher. Nicht sicher die Ursache, aber ... Git speichert Dateien nach ihrem Inhalt. Zwei leere Dateien würden also technisch als gleich betrachtet werden. Wegen des Potenzials für eine große Anzahl von Überschneidungen wäre es sinnvoll, hier eine spezielle Logik zu haben. – Barett

+0

Es sieht sicherlich so aus, als könnte es eine spezielle Handhabung für leere Dateien geben. Aber Git speichert bereits nur eine Kopie jedes Objekts basierend auf seinem Hash, so dass es keinen wirklichen Unterschied zwischen vielen duplizierten leeren Dateien und vielen duplizierten nicht leeren Dateien gibt (d. H. Keine offensichtliche Notwendigkeit einer speziellen Behandlung von leeren Dateien). –

Antwort

2

Leere Dateien werden nicht mehr berücksichtigt für Umbenennungen auf einer rekursiven merge als dieser begehen: https://github.com/git/git/commit/4f7cb99ada26be5d86402a6e060f3ee16a672f16

Ältere Versionen von Git als Konflikt berichten, es immer noch.

$ 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 nicht implizit Umbenennungen verfolgen, also ohne die Umbenennungs Erkennung was Git am Ende passiert ist sieht nur, dass sowohl die empty Datei gelöscht Commits, und dass jeder commit eine neue Datei hinzugefügt.

Es gibt eine Option, dieses Verhalten für Git-diff (https://github.com/git/git/commit/90d43b07687fdc51d1f2fc14948df538dc45584b) zu ändern, aber derzeit ist es in einer Option zu git merge nicht verfügbar.

Die anderen Merge-Strategien scheinen auch nicht das gewünschte Verhalten zu geben.

+0

Danke - nützliche Info.Der erste Link sagt "Dies wird einen Konflikt bei der Zusammenführung verursachen, der den Benutzer selbst aussortiert", was leider nicht geschieht. –

+0

Das ist nur, wenn die leere Datei Inhalt hinzugefügt bekommt. Sie können sich den Test des Commits ansehen und dieses Verhalten sehen. – onionjake