git говорит: "Нет необходимости объединять файлы" сразу после конфликта слияния

Например

> git cherry-pick <hash>
...
error: could not apply <hash>...
Resolved '<file>' using previous resolution.
> git mergetool
No files need merging
> git status
...
Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified: <file>

"оба изменены" и "Нет необходимости объединять файлы"? лжец!

3 ответа

Я предполагаю, что проблема как-то git rerere получил плохое слияние. Я думаю, что это часто случается, когда Мэлд не совсем понимает, что я нажал Ctrl-S, и он записывает маркеры конфликта в разрешение. Почему git по-прежнему говорит "оба изменены" и не позволяет запускать mergetool, я не знаю. В любом случае, исправление заключается в следующем:

git rerere forget <file>
git checkout -m <file>
git mergetool

хотелось бы git checkout -m будет означать, git rerere forget или git статус был более явным. Сэкономил бы целую кучу времени.

Вы правы насчет git rerereи ключ к этой строке:

Resolved '<file>' using previous resolution.

Я не знал об этом раньше (отчасти потому, что я никогда не использую git mergetool), но:

Почему git по-прежнему говорит "оба изменены" и не позволяет запускать mergetool, я не знаю.

Это потому что git mergetool использования git rerere remaining выяснить, какие файлы объединить.

Я заново создал ваш конфликт слияния с помощью повторно используемого разрешения:

$ echo base version > file
$ git config rerere.enabled true
$ git add file && git commit -m 'create base'
[master 8e7a009] create base
 1 file changed, 1 insertion(+)
 create mode 100644 file
$ git checkout -b branch
Switched to a new branch 'branch'
$ echo 'branch conflict' >> file
$ git add file && git commit -m 'enter branch conflict'
[branch 6661ab7] enter branch conflict
 1 file changed, 1 insertion(+)
$ git checkout -b br2 master
Switched to a new branch 'br2'
$ echo 'different, hence conflict' >> file
$ git add file && git commit -m 'create br2 conflict'
[br2 9684589] create br2 conflict
 1 file changed, 1 insertion(+)
$ git merge branch
Auto-merging file
CONFLICT (content): Merge conflict in file
Recorded preimage for 'file'
Automatic merge failed; fix conflicts and then commit the result.

Обратите внимание на вторую строку, которая указывает на то, что, что бы я ни делал сейчас, чтобы разрешить конфликт, Git сохранит результат.

$ vim file

Здесь я разрешил конфликт (так, что это сложнее показать из-за полноэкранного редактирования).

$ git add file && git commit -m resolution
Recorded resolution for 'file'.
[br2 8b42a26] resolution

Фиксация записала резолюцию. Теперь я отменил слияние, а затем снова запустил:

$ git reset --hard HEAD^
HEAD is now at 9684589 create br2 conflict
$ git merge branch
Auto-merging file
CONFLICT (content): Merge conflict in file
Resolved 'file' using previous resolution.
Automatic merge failed; fix conflicts and then commit the result.

Обратите внимание на строку "используя предыдущее разрешение".

Сейчас статус таков, что есть необработанные пути:

$ git status
On branch br2
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both modified:   file

no changes added to commit (use "git add" and/or "git commit -a")

а также git ls-files --stage подтверждает, что существует три версии файла file:

$ git ls-files --stage
100644 eb2222a53126bfe165c615e816f5ba268f1e628f 0       README
100644 4b9049d6a70d93a7af91b4f6b741b88ba1f1838a 1       file
100644 5974ab850c831f806f950321b08391ccea97efcf 2       file
100644 7a77704a9d365c790f5a24fe87515b8df0b7e91b 3       file

Содержание использует мое сохраненное разрешение:

$ cat file
base version
resolved in br2

Бег git mergetool при включенной трассировке оболочки раскрывается секрет:

+ USAGE='[--tool=tool] [--tool-help] [-y|--no-prompt|--prompt] [-O<orderfile>] [file to merge] ...'
+ SUBDIRECTORY_OK=Yes
[mass snippage]
+ git rerere remaining
+ set --
+ test 0 -eq 0
+ print_noop_and_exit
+ echo 'No files need merging'
No files need merging
+ exit 0

Теперь я должен что-то сделать, например, трюк git rerere forget:

$ git rerere forget file
Updated preimage for 'file'
Forgot resolution for file
$ git checkout -m file
$ cat file
base version
<<<<<<< ours
different, hence conflict
||||||| base
=======
branch conflict
>>>>>>> theirs

Обратите внимание, что когда я снова разрешаю, добавляю и фиксирую, записывается новое разрешение:

$ git add file
$ git commit -m 're-resolved'
Recorded resolution for 'file'.
[br2 00c94b1] re-resolved

(Конечно, также возможно git config rerere.enabled false.)

У меня был тот же результат, что и у вас, после слияния, затемgit reset --hard {commit-prior-to-merge}затем повторите слияние: «оба изменены» и «Файлы не нуждаются в слиянии».

В моем случае меня устраивали разрешения, хранящиеся в rerere, поэтому все, что мне нужно было сделать, этоgit add .а затемgit commitслияние.

Видимо есть еще и переход наgit merge --rerere-autoupdateчтобы избежать этого дополнительного шага:

После того, как механизм rerere повторно использует записанное разрешение текущего конфликта для обновления файлов в рабочем дереве, разрешите ему также обновить индекс с результатом разрешения.

https://git-scm.com/docs/git-merge#Documentation/git-merge.txt --- rerere-autoupdate

Другие вопросы по тегам