Mam jedno zamieszanie dotyczące określonego zachowania git:
Poniżej znajdują się kroki i sytuacja (lista poleceń jest również podana później):
- Mam dwie gałęzie: master i XBranch
- W obu występuje plik src / a.txt. Jego treść to "Stara treść"
- W XBranch zmieniam nazwę pliku src / a.txt na src / b.txt, używając:
mv
,git rm
,git add
. 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
igit commit
W master edytuję zawartość pliku b.txt na "
New Content
- W mistrzu mam
git add src/b.txt
igit commit
- 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 № 1Występuje konflikt, ale nie dotyczy plik zawartość. Chodzi o drzewo zawartość.
- W jednym drzewie,
case2
katalog (w master), istnieje Nowy plikb.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:
- Dodaję plik
a.txt
wmaster
z "Starą zawartością" i zatwierdź to.- Dodaję plik
a.txt
wXBranch
z "nową zawartością" i zatwierdz ją.- Łączę się
XBranch
wmaster
. 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 zmaster
?
Oznacza to, że:
- zamiast scalać
XBranch
(a.txt
zmieniono nazwę nab.txt
) domaster
popełnić z nowymb.txt
od kroku 6 (konflikt drzewa), - połączysz się
XBranch
(a.txt
zmieniono nazwę nab.txt
) z mistrzem z nowego krok 4 (a.txt
również zmieniono nazwę tak jakb.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 dirJeś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 jakomodify/delete
konflikt.