Я собираюсь сосредоточиться на подмножестве этой проблемы, которая меня интересовала: У меня две ветки, и я хочу псевдо-слить один файл из одного в другой. сильный>
(Я говорю «псевдо-слияние», потому что мне не нужна и не нужна фиксация слияния; я просто хочу объединить вклады обеих версий файла так, как я считаю нужным.)
Мой подход основан на подходе, принятом в https://stackoverflow.com/a/39916536/341994. К сожалению, этот вопрос закрыт как дубликат (ошибочно, на мой взгляд: это не дубликат этого вопроса, и неправильно отвечать и закрывать как дубликат, что и сделал там ответчик). Но в этом ответе есть некоторые ошибки, поэтому я модернизировал и очистил подход. Вместо checkout
и reset
я использую restore
, и я не беспокоюсь о том, чтобы зафиксировать то, что мне не нужно.
Хорошо, представьте, что у меня есть три файла:
$ ls
a b f
Но я хочу псевдо-объединить только одно из них, a
, из otherbranch
. Давайте посмотрим на них, чтобы увидеть, как будет выглядеть ситуация. Вот моя версия:
$ cat a
line one
line two
line three
line four
line five
Вот версия другого филиала:
$ git show otherbranch:a
line one
line two edited
line three
line four
line five
line six
Уловка здесь в том, что мы собираемся использовать индекс как блокнот (в конце концов, для чего он нужен). Итак, мы начинаем (ШАГ 1), убедившись, что наша версия скопирована в индекс:
$ git add a
Теперь (ШАГ 2) мы можем использовать restore
, чтобы получить версию из otherbranch
(в настоящее время restore
лучше, чем checkout
, поскольку это позволяет нам говорить более ясно):
$ git restore --source otherbranch a
На первый взгляд это выглядит плохо. Теперь мы полностью перезаписали наш a версией из otherbranch
, как вы можете видеть:
$ cat a
line one
line two edited
line three
line four
line five
line six
Но не волнуйтесь! Предыдущая версия a все еще находится в индексе, как вы можете видеть:
$ git diff a
diff --git a/a b/a
index abf51fa..333614b 100644
--- a/a
+++ b/a
@@ -1,6 +1,7 @@
line one
-line two
+line two edited
line three
line four
line five
+line six
Хорошо, теперь мы готовы к ключевому ходу (ШАГ 3). Мы выполняем интерактивное исправление add
нашего файла из рабочего дерева в индекс.
Мы могли бы сказать git add -p a
, чтобы запустить интерактивный процесс исправления, и в этом случае мы будем получать блоки по одному. Но в этом случае есть только один кусок, и я все равно хочу его отредактировать, поэтому я говорю:
$ git add --e a
В результате мы открываем патч-файл различий в нашем редакторе! Это выглядит так:
line one
-line two
+line two edited
line three
line four
line five
+line six
Путем тщательного редактирования мы можем теперь решить, какие части мы хотим принять, а какие нет. Допустим, что строка шестая, но не вторая, отредактирована. Итак, мы редактируем, чтобы выглядеть так:
line one
line two
line three
line four
line five
+line six
Мы закрываем редактор, и патч применяется к индексной версии файла. Но мы еще не закончили! otherbranch
версия a все еще находится в рабочем дереве:
$ cat a
line one
line two edited
line three
line four
line five
line six
Версия, которая нам нравится, есть в указателе, помните? Чтобы получить его (ШАГ 4), мы просто вызываем git restore
простой и простой (опять же, это современный способ; restore
лучше, чем reset
, и может применяться к одному файлу):
$ git restore a
Теперь наш a правильный, и мы все закончили:
$ cat a
line one
line two
line three
line four
line five
line six
На этом этапе мы могли бы выполнить фиксацию, но это не обязательно; мы выполнили то, что намеревались достичь.
person
matt
schedule
02.05.2021
git merge -s ours --no-commit
, за которой следуют некоторыеgit read-tree
, не будет хорошим решением для этого? См. stackoverflow.com/questions/1214906/ - person VonC   schedule 04.03.2011