Как я могу объединить определенный файл из одной ветки в другую ветвь в Git

У меня есть 2 ответвления в репозитории git, позволяет называть их, dev и test. У меня есть изменения в одном файле, somecode.js. Обе ветки имеют изменения в somecode.js. 2 ветки значительно расходятся (но управляемы), поэтому прямого "слияния" недостаточно.

Я пробовал http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/, но не сливает содержимое обоих файлов. В основном вы просто пишете файл вместо фактического слияния содержимого файла.

Я также пробовал:

git checkout -b newbranch
git checkout test somecode.js
git commit -m "somecode changes from newbranch"
git checkout dev
git merge newbranch

и

git checkout -m test somecode.js

(Я действительно надеялся на -m для слияния, но, похоже, он не работал у меня...)

Я думал, что я близок к тому, что мне нужно, но потом понял, что он просто переадресовал значение фиксации, которое он не слил, он написал поверх исходного файла в тесте.

Итак, чтобы повторить, как я могу объединить определенный файл из одной ветки в другую ветвь, не просто записывая файл в ветке, я сливаюсь с использованием git.

Ответ 1

Я думаю, вам нравится использовать

git checkout -p

В вашем случае

git checkout dev
git checkout -p test somecode.js

И вы можете интерактивно применять diff.

Ответ 2

git checkout dev
git show test:somecode.js > somecode.js.theirs
git show $(git merge-base dev test):somecode.js > somecode.js.base
git merge-file somecode.js somecode.js.base somecode.js.theirs 

Таким образом вы вручную сделаете трехстороннее слияние из somecode.js на тестовой ветке в somecode.js на ветке dev.

Или.. Вы можете создать временную ветку с необходимыми изменениями и сделать из нее сквош-слияние. Это 'git путь' достаточно?:)

git checkout -b test/filtered $(git merge-base dev test)
git diff ..test -- somecode.js | git apply
git add -- somecode.js
git commit -m "Updated somecode.js"
git checkout dev
git merge --squash test/filtered
git branch -D test/filtered

Ответ 3

Я думаю, что git merge-file - это то, что вы ищете. На странице man:

git merge-file incorporates all changes that lead from the <base-file> to
<other-file> into <current-file>. The result ordinarily goes into <current-file>.
git merge-file is useful for combining separate changes to an original. Suppose
<base-file> is the original, and both <current-file> and <other-file> are
modifications of <base-file>, then git merge-file combines both changes.