мерзавец переименовать / удалить путаницу - PullRequest
7 голосов
/ 23 июня 2010

У меня одна путаница в отношении определенного поведения git:

Ниже приведены шаги и ситуация (список команд также приведен позже):

  1. У меня есть две ветви:master и XBranch
  2. В обоих файлах есть файл src / a.txt.Это содержимое «Старый контент»
  3. В XBranch я переименовываю src / a.txt в src / b.txt, используя: mv, git rm, git add.
  4. В мастере переименуйте файл в a.txt.Во время коммита я сделал git rm src/a.txt, но забыл сделать git add src/b.txt В мастере я делаю: git rm src/a.txt и git commit

  5. В мастере я редактирую содержимое файла b.txt to "New Content

  6. В мастере я делаю git add src/b.txt и git commit
  7. В мастере я делаю: git merge XBranch

Файл src / b.txt конфликтует, что вполне понятно. Но содержимое "Old Content". Почему?

Почему не это что-то вроде:

<<<<<<< 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

1 Ответ

6 голосов
/ 23 июня 2010

Конфликт, но не в содержании файла . Речь идет о дерево содержание.

  • В одном дереве, каталоге case2 (в мастере), есть новый файл b.txt
  • в том же каталоге (в XBranch) есть переименованный файл a.txt => b.txt

Когда вы разрешаете конфликт, вы фактически выбираете один файл или другое (не одна строка в файле). Отсюда «старое содержание» в результате файл.


ОП добавляет в комментариях:

Но тогда насколько логически это отличается от следующей ситуации:

  1. Я добавляю файл a.txt в master со «Старым контентом» и фиксирую его.
  2. Я добавляю файл a.txt в XBranch с «Новым контентом» и фиксирую его.
  3. Я объединяю XBranch в master. На этот раз он показывает оба содержимого в этом файле!

На этот раз оба дерева (каталог case2 в ветвях master и XBranch) ссылка на новый файл a.txt: его содержимое сливается с конфликтом разрешающая способность. Раньше был конфликт между a.txt ( переименован в b.txt) и new b.txt : оба файла не могут существовать в та же ветка, выбор (файла, а не содержимого файла) должен быть сделан.

На шаге 4 моего вопроса, если я сделаю "git rm" и "git add" в одном коммит, все работает как я ожидаю! Я не понимаю этого сейчас. Как я могу предсказать, когда файл будет иметь оба содержимого? Когда он будет иметь содержимое XBranch и когда он будет иметь только содержание master?

Это означает, что:

  • вместо слияния XBranch (a.txt переименован в b.txt) в master commit с новым b.txt из шага 6 (конфликт деревьев),
  • вы бы слились XBranch (a.txt переименован в b.txt) с мастером из нового шаг 4 (a.txt также переименован в b.txt): то же самое древо, но другое содержимое BLOB-объекта : конфликт строк.

При этом ОП все еще думает, что должна быть ошибка:


Примечание: Git 2.18 (Q2 2018) изменяет отчет об обнаружении конфликта с помощью рекурсивного слияния.
См. коммит 6e7e027 (19 апреля 2018 г.) Элайджа Ньюрен (newren) .

merge-recursive: избежать ложного конфликта переименования / переименования из переименования dir

Если файл на одной стороне истории был переименован и просто изменен на с другой стороны, затем применение переименования каталогов к измененной стороне дает нам rename/rename(1to2) конфликт.
Мы должны применять переименования каталогов только к парам, представляющим либо добавления, либо переименования.

Внесение этого изменения означает, что каталог переименовал контрольный пример, который был , ранее сообщавшийся как rename/delete конфликт, теперь будет сообщаться как modify/delete конфликт .

...