/ / git zmień nazwę / usuń zamieszanie - git, git-merge

git zmień nazwę / usuń zamieszanie - git, git-merge

Mam jedno zamieszanie dotyczące określonego zachowania git:

Poniżej znajdują się kroki i sytuacja (lista poleceń jest również podana później):

  1. Mam dwie gałęzie: master i XBranch
  2. W obu występuje plik src / a.txt. Jego treść to "Stara treść"
  3. W XBranch zmieniam nazwę pliku src / a.txt na src / b.txt, używając: mv, git rm, git add.
  4. W master zmień nazwę pliku a.txt. Podczas zatwierdzania zrobiłem git rm src/a.txt ale zapomniałem zrobić git add src/b.txt W mistrzu: git rm src/a.txt i git commit

  5. W master edytuję zawartość pliku b.txt na "New Content

  6. W mistrzu mam git add src/b.txt i git commit
  7. W mistrzu: git merge XBranch

Konflikt src / b.txt pliku, który jest całkowicie zrozumiały. Ale treść jest "Old Content". Czemu?

Czemu nie czy jest coś takiego:

<<<<<<< HEAD
New Content
=======
Old content
>>>>>>> XBranch
sabya@SABYA-PC d:/merge_temp/test/case2
$ mkdir source

sabya@SABYA-PC d:/merge_temp/test/case2
$ git init
Initialized empty Git repository in d:/merge_temp/test/case2/.git/

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ mkdir src

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ vi src/a.txt

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ cat src/a.txt
Old Content

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git add src/

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git commit
[master (root-commit) 148500e] added src/a.txt
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 src/a.txt

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git branch XBranch

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git checkout XBranch
Switched to branch "XBranch"

sabya@SABYA-PC d:/merge_temp/test/case2 (XBranch)
$ mv src/a.txt src/b.txt

sabya@SABYA-PC d:/merge_temp/test/case2 (XBranch)
$ git rm src/a.txt
rm "src/a.txt"

sabya@SABYA-PC d:/merge_temp/test/case2 (XBranch)
$ git add src/b.txt

sabya@SABYA-PC d:/merge_temp/test/case2 (XBranch)
$ git commit
[XBranch b3ff8fa] changed a.txt to b.txt in XBranch
1 files changed, 0 insertions(+), 0 deletions(-)
rename src/{a.txt => b.txt} (100%)

sabya@SABYA-PC d:/merge_temp/test/case2 (XBranch)
$ git checkout master
Switched to branch "master"

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ mv src/a.txt src/b.txt

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git rm src/a.txt
rm "src/a.txt"

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git commit
[master bfeaecb] removed src/a.txt
1 files changed, 0 insertions(+), 1 deletions(-)
delete mode 100644 src/a.txt

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ vi src/b.txt

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ cat src/b.txt
New Content

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git add src/b.txt

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git commit
[master 2361d5e] changed content of b.txt
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 src/b.txt

sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git merge XBranch
CONFLICT (rename/delete): Rename src/a.txt->src/b.txt in XBranch and deleted in HEAD
Automatic merge failed; fix conflicts and then commit the result.

sabya@SABYA-PC d:/merge_temp/test/case2 (master|MERGING)
$ cat src/b.txt
Old Content

Odpowiedzi:

7 dla odpowiedzi № 1

Występuje konflikt, ale nie dotyczy plik zawartość. Chodzi o drzewo zawartość.

  • W jednym drzewie, case2 katalog (w master), istnieje Nowy plik b.txt
  • w tym samym katalogu (w XBranch) istnieje zmieniono nazwę plik a.txt => b.txt

Podczas rozwiązywania konfliktu obowiązuje wybór jednego pliku lub pliku inne (nie jedna linia w pliku). Stąd "Stara zawartość" w wynikowym plik.


PO dodaje w uwagach:

Ale jak logicznie różni się ona od następującej sytuacji:

  1. Dodaję plik a.txt w master z "Starą zawartością" i zatwierdź to.
  2. Dodaję plik a.txt w XBranch z "nową zawartością" i zatwierdz ją.
  3. Łączę się XBranch w master. Tym razem pokazuje zarówno zawartość tego pliku!

Tym razem oba drzewa (katalog case2 w gałęziach master i XBranch) odniesienie a Nowy plik a.txt: jego treść zostaje połączona z konfliktem rozkład. Wcześniej wystąpił konflikt między a.txt (zmieniono nazwę tak jak b.txt) i Nowy b.txt: oba pliki nie mogą istnieć w ta sama gałąź, wybór (pliku, nie treści pliku) musiał być dokonany.

W punkcie 4 mojego pytania, jeśli mam zrobić "git rm" i "git add"w jednym commit, działa tak jak oczekuję! Nie rozumiem tego teraz. Jak mogę przewidzieć, kiedy plik będzie zawierał obie treści? Kiedy będzie po prostu mieć zawartość XBranch i kiedy będzie miał tylko zadowolony z master?

Oznacza to, że:

  • zamiast scalać XBranch (a.txt zmieniono nazwę na b.txt) do master popełnić z nowym b.txt od kroku 6 (konflikt drzewa),
  • połączysz się XBranch (a.txt zmieniono nazwę na b.txt) z mistrzem z nowego krok 4 (a.txt również zmieniono nazwę tak jak b.txt): ta sama zawartość drzewa, ale inna treść blob: konflikt linii.

W związku z tym OP nadal uważa, że ​​musi istnieć błąd:


Uwaga: Git 2.18 (Q2 2018) zmienia raport wykrycia konfliktu o rekurencję korespondencji seryjnej.
Widzieć zatwierdź 6e7e027 (19 kwietnia 2018) przez Elijah Newren (newren).

merge-recursive: unikaj fałszywego zmieniania nazwy / zmiany nazwy z nazw plików dir

Jeśli plik z jednej strony historii został zmieniony i zmodyfikowany tylko na z drugiej strony, a następnie zastosowanie nazwy katalogu do zmodyfikowanej strony daje nam za rename/rename(1to2) konflikt.
Powinniśmy stosować tylko nazwy katalogów do par reprezentujących albo rozszerzenia, albo nazwy.

Dokonanie tej zmiany oznacza, że ​​zmieniono nazwę testcase katalogu, który był wcześniej zgłoszone jako rename/delete konflikt zostanie teraz zgłoszony jako modify/delete konflikt.