2013-08-07 3 views
87

У меня есть ветка ветки git1 и branch2, и я хочу объединить файл.py в branch2 в file.py в branch1 и только этот файл.Как слить определенные файлы из ветвей Git

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

+0

Возможный дубликат [? Как объединить выборочные файлы с ГИТ-слияние] (http://stackoverflow.com/questions/449541/how-do-you-merge-selective-files-with- git-merge) –

+0

Возможный дубликат [Как объединить изменения в один файл, а не n слияния?] (https://stackoverflow.com/questions/10784523/how-do-i-merge-changes-to-a-single-file-rather-than-merging-commits) – fbmd

ответ

99

Принятый ответ уже упоминает с помощью git checkout. Теперь может быть содержание в 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 

Раскол команда особенно полезна.

+1

Это классная функция – rwolst

+0

Это прекрасно работает. Спасибо за включение текста подсказки командной строки. Без него было бы невозможно использовать. – James

+1

Как мы можем использовать патч и в то же время использовать инструмент слияния? вместо ключевого материала – Gabriel

12

Все изменения в 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 
80

Как указано в комментариях, это технически не является «слиянием», поэтому ссылка ниже использует кавычки. Однако мне редко нужно что-то сложное, как описывают другие плакаты, поэтому я думаю, что это полезно, если не правильное, решение вопроса OP.

Проверьте эту страницу: Git Tip: How to "Merge" Specific Files from Another Branch Это самый простой способ сделать это, ИМХО.

В основном, чтобы применить его к ситуации:

$ git checkout branch1 # i.e. make sure you're in branch1 
$ git checkout branch2 file.py 

Проще простого, file.py теперь в branch1.

+62

Легко, но это не так. фактически * слияние *. Он просто перезаписывает файл 'file.py' всем, что находится в ветке 2. –

+3

Крайне полезно, когда вы хотите получить всего пару файлов из функции в начале подготовки. Нам потребовались некоторые файлы из ветки функций, чтобы индексировать некоторые данные, прежде чем остальная часть функции попытается использовать индексированные данные. Благодаря! –

+0

Что делать, если вы объединили файл с ветки 1 в branch2? Вы получите конфликт! – Amir

2

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

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, выглядящей так, как если бы все в истории отрасли2 с этой точкой было объединено, что может и не быть тем, что вы хотите. Лучший вариант первой проверки выше, вероятно,

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

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

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

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

Для этого протокола я предполагаю, что вы хотите объединить файл '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 
2

Вы можете stash и stash pop этот файл :

git checkout branch1 
git checkout branch2 file.py 
git stash 
git checkout branch1 
git stash pop 
Смежные вопросы