2010-06-24 2 views
2

У меня проблема: У нас есть большой продукт, который находится в главной ветке. Кроме того, у нас есть другие ветви, в которых есть только несколько файлов, только файлы, характерные только для этой ветви. Каждая из этих ветвей представляет собой плагин для основного продукта. Например, когда вы получаете основной продукт, вы получаете много файлов, устанавливаете их и т. Д., А позже, когда вы решите получить плагин, вы получаете пакет, содержащий только несколько файлов, и загружая этот файл (и заменяя исходные файлы) вы установили плагин.Git: как слить только измененные файлы

Давайте будем иметь payment.php в главной ветке (как и многие другие файлы). И у меня есть филиал PayPal, у которого есть только один файл, который является payment.php. Теперь я исправлю ошибку в master.php мастера и хочу объединить это исправление в ветке paypal. Однако, когда я запускаю слияние, абсолютно все файлы добавляются в эту ветку. Таким образом, в конце PayPal-ветвь имеет все файлы из главной ветки. Вы случайно знаете, как это можно исправить? Я хочу, чтобы GIT объединил файлы, которые существуют только в этой ветви, поэтому в приведенном выше примере ветка PayPal должна иметь только один файл (payment.php) с объединенным исправлением ошибок.

+0

Как говорят другие, вы, вероятно, не хотите иметь ветку, в которой отсутствуют все файлы. Если вы действительно хотите отслеживать плагин отдельно, это должен быть отдельный репозиторий, возможно, включенный в качестве подмодуля в основной проект. Если вы не хотите, чтобы он был отдельным, то, конечно, он мог иметь свою собственную ветку развития, но в качестве ветки репозитория проекта эта ветвь должна содержать весь проект, а не только один плагин. – Cascabel

ответ

4

Вот почему важно хорошо управляйте своими филиалами, в частности, чтобы использовать ветви темы и сливаться вверх.

Вы должны сделать это исправить на тему ветви, раздвоенный от общего предка всех отраслей, которые нуждаются в затруднительном, а затем объединить их в мастере и PayPal:

x - x - x - x ------------- X (master) 
|\       | 
| x - x - x ---- X (paypal) | 
\   /  /
    x (bugfix) --------------- 

Если вы уже сделали ваш багфикс, и вы по ошибке сделали его мастером, а не из соответствующего объединения базы, и история на мастер не был опубликован, вы должны вишневого выбрать или перебазировать его в нужном месте:

# If the bugfix commit is not at the tip of master, you can rebase to get it there: 
git rebase -i <commit before the bugfix> master 
# rearrange the list of commits to put the bugfix at the tip, save and quit 

# Now either cherry-pick or rebase the commit to the right place 
# (rebase is easier if the bugfix is actually several commits) 

# Cherry-pick 
# make a branch and cherry-pick 
git checkout -b bugfix <SHA1 of merge base> 
git cherry-pick <SHA1 of bugfix> 
# remove the commit from master, assuming it's still on the tip 
git checkout master 
git reset --hard master^ 

# or rebase 
# make the bugfix branch (assuming it's still on the tip) 
git branch bugfix master 
# and remove the commit from master (assuming it's still on the tip) 
git checkout master 
git reset --hard master^ # or if the bugfix is composed of n commits, master~n 
# rebase the bugfix branch to the right place 
git rebase --onto <SHA1 of merge base> master bugfix 

Если История содержит был опубликован, все, что вы можете сделать, это вишневое выбрать на устранение ошибку PAYPAL ветви, и не забудьте сделать это правильно в следующий раз:

git checkout paypal 
git cherry-pick <SHA1 of bugfix> 
+0

Привет, я подумывал о том, чтобы время от времени приходилось иметь филиал Paypal и объединять его. Поэтому, когда мне нужны новые функции, исправленные или исправленные ошибки, я буду делать это в файлах мастера, а затем до релиза я буду объединять изменения в ветке paypal (так что у PayPal могут быть новые исправления и функции). Я совершенно новичок в этом, поэтому, пожалуйста, поправьте меня, если я не вижу в этом каких-то скрытых проблем. Раньше я делал эту работу вручную. Поэтому я реализовал новую функцию в master, а затем вручную скопировал фрагменты кода в paypal branch. – Eugene

+0

В приведенном выше примере две ветви кажутся очень разными (все эти коммиты после точки ветвления), в то время как мои ветви обычно имеют только одну разницу (например, функция paypal). Все остальное - то же самое, и основная работа заключается в том, чтобы сохранить новые модификации кода, которые всегда идут в обе ветви. Конечно, иногда у меня есть исправление, характерное только для paypal branch, но это довольно редко, потому что этот код хорошо протестирован к этому времени. – Eugene

+0

@Eugene: Я действительно не уверен, что вы пытаетесь спросить в этих комментариях. Независимо от того, вы всегда можете внести изменения из правой точки ветвления, а затем объединить их во все ветви, которые в них нуждаются. Неважно, насколько различны эти ветви, до тех пор, пока ваш патч по-прежнему применяется ... – Cascabel

1

Почему ваши другие ветви содержат все файлы, которые являются частью ведущей ветки? Вы просто усложняете себя, переживая проблему удаления всех других файлов. Особенно если позже вам нужно изменить другой файл, который вы уже удалили.

0

Вы можете сделать что-то похожее на это: http://nvie.com/git-model

(я надеюсь, что это работает)

master будет по-прежнему ваш главный филиал. Вы создаете вторую ветку с выводом bugfix. Вы создаете третью ветку с исправлением, называемым plugin-foo.

В плагине-foo вы удаляете все файлы, которые не нужны. Теперь, всякий раз, когда вы вносите изменения в файлы, которые не находятся в ветке плагина, вы делаете их на главной ветке. Все исправления попадают в ветку bugfix. Вы периодически объединяете ветку bugfix как в основной, так и в ветви плагина. Это приводит к исправлениям ошибок в обеих ветвях.

1

Вы делаете это неправильно. У вас должны быть все файлы в ветке.

Это работа Git, чтобы отслеживать, какие файлы отличаются между ветвями, а не вашими. Это своего рода одна из точек использования VCS.

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

+1

Привет, спасибо за ваш ответ. Я тестирую это решение в настоящий момент и, скорее всего, его использую. – Eugene

0

Изоляция ваших плагинов в собственном git-репо позволяет создавать эволюции на них независимо от родительского проекта.

Если, однако, вы должны их непосредственно включены в проект, последние релизы Git (git1.7.11, июнь 2012), включает в себя git subtree script (ранее developed on GitHub по apenwarr, теперь объединены в магистральный мерзавца)

Таким образом, , вы можете объединить одно репо (и его историю) в другое, сохранив возможность позже извлечь свою историю (в отличие от слияния поддерева).
Это можно рассматривать как альтернативу подмодулям git.

Другим вариантом является git slave, чтобы сохранить родительский репо и подмодули плотно синхронно.

Смежные вопросы