Нет хорошего способа сделать это
Это не означает, что вы вообще не можете этого сделать, но все способы, которыми вы можете это сделать, в настоящее время довольно плохи. Основная проблема проста и состоит из трех или более частей, в зависимости от того, как вы считаете:
- Вы можете отправлять только коммиты.
- Разрешение конфликтов происходит в индексе Git.
- Новые коммиты создаются из индекса Git.
- Вы не можете сделать новую фиксацию, пока не разрешите все конфликты.
Пользователи могут использовать свои файлы рабочего дерева и/или дополнительные файлы, вставленные в свое рабочее дерево или где-либо еще, чтобы помочь с разрешением, но в основном конфликт существует, потому что Git изменил свой индекс таким образом, что некоторая запись помечена как конфликтующая. Чтобы снять отметку с записи, чтобы можно было сделать новую фиксацию, при условии, что это был последний конфликт, необходимо разрешить конфликт.
Следовательно, чтобы сделать фиксацию, которую вы можете отправить кому-то еще, чтобы они могли разрешить свою часть конфликта, вы должны сначала разрешить все части конфликта. Теперь вы можете зафиксировать и отправить фиксацию, а они могут... э-э-э-э... отменить ваше разрешение своих частей конфликта? За исключением того, что никакого конфликта не осталось.
Git мог бы сделать это, если бы только вы могли зафиксировать конфликт
К сожалению, вы не можете совершить конфликт. Но все инструменты существуют в экосистеме Git. Конфликты возникают из-за того, что в индексе Git есть записи индекса, отличные от нулевого этапа. В рабочем дереве пользователя также есть отслеженные и/или неотслеженные файлы, которые могут представлять собой частичное разрешение. Если бы мы могли просто взять каждый из них — ненулевые записи, отслеживаемые и неотслеживаемые файлы — и сделать из них фиксации, а затем использовать эти фиксации для повторной сборки конфликтующего индекса и содержимое рабочего дерева позже, у нас будут задатки именно того, что вы хотите.
Вывод git ls-files --stage
показывает все, что на самом деле находится в индексе Git. Нам просто нужно написать программу, которая берет эти выходные данные и создает несколько отдельных временных индексов (каждый из которых не конфликтует, но позволяет другой программе создать новый конфликтующий индекс позже) и фиксирует их вместе с еще одним или двумя коммитами для сохранения. состояние рабочего дерева. Эту массу коммитов — сколько бы ни потребовалось для сохранения записей этапов 0, 1, 2 и 31 плюс состояние рабочего дерева — лучше всего представить в виде фальшивого слияния, la git stash
, а затем индексируется через некоторую ссылку для временно разрешенных состояний, которые можно восстановить для возобновления слияния позже, a la refs/stash
для git stash
.
Сходства с git stash
достаточно очевидны, и реализация, скорее всего, в какой-то степени будет заимствована из старого сценария оболочки git stash
. Точный формат для этих коммитов, а также ссылка или ссылки для использования потребуют некоторых размышлений и экспериментов.
Сегодня этой команды нет.
1Теоретически, если, например, на этапе 1 в индексе есть конфликтующие записи, может существовать более одного файла с определенным именем, например path/to/file.ext
. Это будет представлять несколько баз слияния. На практике Git, кажется, не использует это, а если бы и использовал, то неясно, как можно было бы узнать, какая версия path/to/file.ext
пошла с какой базой слияния: должен ли каждый файл, имеющий запись этапа 1, иметь N такие записи, где N количество баз слияния? Какое хэш-значение будет помещено в слот индекса, если, скажем, в базе слияния №1 нет файла с именем path/to/file.ext
, а в базе слияния №2 есть?
Все это влияет на дизайн коммита слияния в процессе слияния, который мы сделали бы для обработки этого.
person
torek
schedule
27.01.2021