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

У меня есть 2 git ветки branch1 и branch2, и я хочу объединить файл .py в branch2 в file.py в ветке1 и только этот файл.

В сущности, я просто хочу работать с file.py в ветке1, но хочу использовать команду слияния. Каков наилучший способ сделать это?

Ответ 1

Когда содержимое находится в file.py из branch2, которое больше не относится к branch1, оно требует выбора некоторых изменений и оставления других. Для полного контроля выполните интерактивное слияние с помощью переключателя --patch:

$ git checkout --patch branch2 file.py

В разделе интерактивного режима на странице руководства для git-add(1) объясняются ключи, которые следует использовать:

y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk nor any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk nor any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

Команда split особенно полезна.

Ответ 2

Хотя само по себе это не слияние, иногда требуется все содержимое другого файла в другой ветки. Блог Джейсона Рудольфа blog post предоставляет простой способ копирования файлов из одной ветки в другую. Примените технику следующим образом:

$ git checkout branch1 # ensure in branch1 is checked out and active
$ git checkout branch2 file.py

Сейчас file.py сейчас в branch1.

Ответ 3

Являются ли все изменения file.py в branch2 в своих собственных записях, отдельно от изменений в других файлах? Если это так, вы можете просто cherry-pick внести изменения:

git checkout branch1
git cherry-pick <commit-with-changes-to-file.py>

В противном случае merge не работает по отдельным путям... вы можете просто создать патч git diff изменений file.py от branch2 и git apply до branch1:

git checkout branch2
git diff <base-commit-before-changes-to-file.py> -- file.py > my.patch
git checkout branch1
git apply my.patch

Ответ 4

Ни один из других текущих ответов на самом деле не "объединит" файлы, как если бы вы использовали команду слияния. (В лучшем случае они потребуют от вас выбора различий вручную.) Если вы действительно хотите воспользоваться объединением с использованием информации от общего предка, вы можете выполнить процедуру, основанную на процедуре, описанной в разделе "Расширенное объединение". Справочного руководства по git.

Для этого протокола я предполагаю, что вы хотите объединить файл 'path/to/file.txt' из origin/master в HEAD - при необходимости измените. (Вам не обязательно находиться в верхнем каталоге вашего хранилища, но это помогает.)

# Find the merge base SHA1 (the common ancestor) for the two commits:
git merge-base HEAD origin/master

# Get the contents of the files at each stage
git show <merge-base SHA1>:path/to/file.txt > ./file.common.txt
git show HEAD:path/to/file.txt > ./file.ours.txt
git show origin/master:path/to/file.txt > ./file.theirs.txt

# You can pre-edit any of the files (e.g. run a formatter on it), if you want.

# Merge the files
git merge-file -p ./file.ours.txt ./file.common.txt ./file.theirs.txt > ./file.merged.txt

# Resolve merge conflicts in ./file.merged.txt
# Copy the merged version to the destination
# Clean up the intermediate files

git merge-file должен использовать все настройки по умолчанию для слияния для форматирования и т.п.

Также обратите внимание, что если ваша "наша" версия рабочей копии, и вы не хотите быть слишком осторожными, вы можете работать непосредственно с файлом:

git merge-base HEAD origin/master
git show <merge-base SHA1>:path/to/file.txt > ./file.common.txt
git show origin/master:path/to/file.txt > ./file.theirs.txt
git merge-file path/to/file.txt ./file.common.txt ./file.theirs.txt

Ответ 5

Вы можете stash и stash pop создать файл:

git checkout branch1
git checkout branch2 file.py
git stash
git checkout branch1
git stash pop

Ответ 6

Чтобы слить только изменения из ветки2 file.py, измените остальные изменения.

git checkout -B wip branch2
git read-tree branch1
git checkout branch2 file.py
git commit -m'merging only file.py history from branch2 into branch1'
git checkout branch1
git merge wip

Слияние никогда не будет смотреть на какой-либо другой файл. Возможно, вам понадобится "-f" выписки, если деревья будут достаточно разными.

Обратите внимание, что это оставит ветвь1, выглядящую так, как если бы все в истории branch2 к этой точке было объединено, что может быть не таким, каким вы хотите. Лучшая версия первой проверки выше, вероятно,

git checkout -B wip `git merge-base branch1 branch2`

в этом случае сообщение фиксации должно быть также

git commit -m"merging only $(git rev-parse branch2):file.py into branch1"

Ответ 7

Я нахожусь в той же ситуации, я хочу объединить файл из ветки, в которой много коммитов на 2 ветке. я пробовал много способов выше и других, которые я нашел в интернете, и все они провалились (потому что история коммитов сложна), поэтому я решил сделать свой путь (безумный способ).

git merge <other-branch>
cp file-to-merge file-to-merge.example
git reset --hard HEAD (or HEAD^1 if no conflicts happen)
cp file-to-merge.example file-to-merge