Здесь есть две отдельные проблемы:
- Как вы поддерживаете локальные ветки удаленных проектов, и
- Как сохранить копию удаленных проектов в своем собственном дереве?
Проблема 1 довольно проста сама по себе. Просто сделайте что-то вроде:
git clone git://example.com/foo.git
cd foo
git remote add upstream git://example.com/foo.git
git remote rm origin
git remote add origin ssh://.../my-forked-foo.git
git push origin
После этого вы можете нормально работать с разветвленным репозиторием. Если вы хотите объединить вышестоящие изменения, запустите:
git pull upstream master
Что касается проблемы 2, один из вариантов - использовать субмодули. Для этого перейдите в ваш основной проект и запустите:
git submodule add ssh://.../my-forked-foo.git local/path/for/foo
Если я использую подмодули git, что мне нужно знать?
Иногда вы можете найти подмодули git немного хитрыми. Вот некоторые вещи, которые нужно иметь в виду:
- Всегда передайте подмодуль перед передачей родителя.
- Всегда нажимайте на подмодуль, прежде чем нажать на родителя.
- Убедитесь, что заголовок подмодуля указывает на ветку, прежде чем совершать ее. (Если вы пользователь bash, я рекомендую использовать git-complete , чтобы вставить текущее имя ветки в ваше приглашение.)
- Всегда запускать 'обновление субмодуля git' после переключения веток или изменения изменений.
В определенной степени вы можете обойти (4), используя псевдоним, созданный одним из моих коллег:
git config --global alias.pull-recursive '!git pull && git submodule update --init'
... и затем работает:
git pull-recursive
Если подмодули git такие сложные, каковы преимущества?
- Вы можете проверить основной проект без проверки субмодулей. Это полезно, когда подмодули огромны, и вам не нужны они на определенных платформах.
- Если у вас есть опытные пользователи git, вы можете иметь несколько веток вашего подмодуля и связать их с разными вилками вашего основного проекта.
- Когда-нибудь кто-нибудь может починить подмодули git для более изящной работы. Самые глубокие части реализации субмодуля на самом деле довольно хороши; сломаны только инструменты верхнего уровня.
Подмодули git не для меня. Что дальше?
Если вы не хотите использовать подмодули git, вы можете изучить стратегию поддерева git merge . Это сохраняет все в одном хранилище.
Что если репозиторий обратного потока использует Subversion?
Это довольно легко, если вы знаете, как использовать git svn:
git svn clone -s https://example.com/foo
cd foo
git remote add origin ssh://.../my-forked-foo.git
git push origin
Затем настройте локальную ветку отслеживания в git.
git push origin master:local-fork
git checkout -b local-fork origin/local-fork
Затем, чтобы объединиться с апстримом, запустите:
git svn fetch
git merge trunk
(Я не тестировал этот код, но более или менее мы поддерживаем один подмодуль с вышестоящим хранилищем SVN.)
Не используйте git svn rebase, потому что это очень затруднит использование подмодуля git в родительском проекте без потери данных. Просто обрабатывайте ветви Subversion как доступные только для чтения зеркала восходящего потока и явно объединяйте их.
Если вам нужен доступ к репозиторию Subversion восходящего потока на другом компьютере, попробуйте:
git svn init -s https://example.com/foo
git svn fetch
После этого вы сможете объединить изменения из апстрима, как и раньше.