Отслеживание стороннего кода с помощью Git - PullRequest
24 голосов
/ 24 марта 2009

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

Не могли бы вы, ребята, быть так любезны, чтобы пролить свет на это и помочь мне с мой конкретный вариант использования? Что было бы лучшим решением для следующая, конкретная проблема? (Я не буду пытаться обобщить мой проблема, так как я могу сделать неправильные предположения о вещах, особенно так как я такой новый со всем этим ...)

Я создаю веб-сайт в Django (веб-фреймворк на Python). Сейчас, Есть много сторонних плагинов, доступных для использования с Django (Django называет их «приложениями»), которые вы можете добавить в свой проект. Некоторые из эти приложения могут потребовать небольшой модификации, чтобы работать, как я хочу их. Но если вы начнете вносить изменения в сторонний код, вы представить проблему обновления этого кода, когда появляются новые версии И в то же время сохраняя ваши локальные модификации.

Итак, я бы сделал это в Subversion, используя ветки поставщиков. Мой макет хранилища будет выглядеть так:

/trunk
  ...
  /apps
    /blog-app
  ...
/tags
  ...
/branches
  ...
/vendor
  /django-apps
    /blog-app
      /1.2
      /1.3
      /current
    /other-app
      /3.2
      /current

В этом случае / trunk / apps / blog-app был бы svn copy'd одного из теги в / vendor / django-apps / blog-app. Скажи, что это был v1.2. А также что теперь я хочу обновить свою версию в trunk до v1.3. Как вы можете видите, я уже обновил / vendor / django-apps / blog-app / current (используя svn_load_dirs) и 'tagged' (svn copy) это как /vendor/django-apps/blog-app/1.3. Теперь я могу обновить / trunk / apps / blog-app с помощью svn merge'ing изменений между /vendor/django-apps/blog-app/1.2 и /vendor/django-apps/blog-app/1.3 в / trunk / apps / blog-app. Это будет сохранить мои локальные изменения. (для людей, неизвестных с этим процессом, это описано в Руководство по Subversion: http://svnbook.red -bean.com / ен / 1,5 / svn.advanced.vendorbr.html )

Теперь я хочу сделать весь этот процесс в Git. Как я могу это сделать?

Позвольте мне повторить требования:

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

Дополнительно (для бонусных баллов ;-)):

  • Предпочтительно, я хочу сделать это без чего-то вроде svn_load_dirs. я думаю, что должно быть возможно отслеживать приложения и их обновления прямо из своего хранилища (большинство сторонних приложений Django хранятся в Subversion). Дает мне дополнительное преимущество возможности просмотра отдельные сообщения коммита между выпусками. И исправление слияния конфликты легче, так как я могу справиться с множеством мелких коммитов вместо одного искусственного коммита, созданного svn_load_dirs. Я думаю, что можно было бы сделать это с svn: externals в Subversion, но у меня есть никогда не работал с этим раньше ...

Решение, в котором можно использовать комбинацию обоих методов, будет еще более предпочтительным, поскольку могут быть разработчики приложений, которые не используйте контроль версий или не делайте их репозитории общедоступными. (Имеется в виду как svn_load_dirs-подобное поведение и отслеживание прямо с Subversion reposity (или другой Git)

Я думаю, что мне нужно было бы использовать поддеревья, подмодули, ребаз, ветки или их комбинацию, но, если я знаю, какие из них или как с этим справляются, разбейте меня: S

Я с нетерпением жду ваших ответов! Пожалуйста, будьте максимально многословны отвечая, так как мне уже было трудно понять других примеры найдены в сети.

Заранее спасибо

Ответы [ 4 ]

27 голосов
/ 25 марта 2009

Здесь есть две отдельные проблемы:

  1. Как вы поддерживаете локальные ветки удаленных проектов, и
  2. Как сохранить копию удаленных проектов в своем собственном дереве?

Проблема 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 немного хитрыми. Вот некоторые вещи, которые нужно иметь в виду:

  1. Всегда передайте подмодуль перед передачей родителя.
  2. Всегда нажимайте на подмодуль, прежде чем нажать на родителя.
  3. Убедитесь, что заголовок подмодуля указывает на ветку, прежде чем совершать ее. (Если вы пользователь bash, я рекомендую использовать git-complete , чтобы вставить текущее имя ветки в ваше приглашение.)
  4. Всегда запускать 'обновление субмодуля git' после переключения веток или изменения изменений.

В определенной степени вы можете обойти (4), используя псевдоним, созданный одним из моих коллег:

git config --global alias.pull-recursive '!git pull && git submodule update --init'

... и затем работает:

git pull-recursive

Если подмодули git такие сложные, каковы преимущества?

  1. Вы можете проверить основной проект без проверки субмодулей. Это полезно, когда подмодули огромны, и вам не нужны они на определенных платформах.
  2. Если у вас есть опытные пользователи git, вы можете иметь несколько веток вашего подмодуля и связать их с разными вилками вашего основного проекта.
  3. Когда-нибудь кто-нибудь может починить подмодули 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

После этого вы сможете объединить изменения из апстрима, как и раньше.

3 голосов
/ 25 марта 2009

Я огляделся еще немного и наткнулся на Кос . Это инструмент, который автоматизирует ветки вендоров в Git. Он может использовать Git или SVN репозитории.

Просматривая источник, я обнаружил, что он использует стратегию поддерева. И, кажется, сделать это действительно просто! Плюс, похоже, что он отвечает всем моим требованиям!

Прежде чем я прыгну и использую его: кто-нибудь здесь имеет опыт работы с Braid? Хотелось бы узнать о возможных минусах, если они есть. Кроме того, если вы еще не использовали Braid, но имеете опыт работы с Git, что вы думаете об этом, на первый взгляд?

1 голос
/ 24 марта 2009

Я использую подмодули git для отслеживания многократно используемых приложений в моих проектах Django, но в долгосрочной перспективе это немного грязно.

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

Возможно, вам придется взглянуть на virtualenv и pip, потому что они имели некоторые недавние улучшения для работы с внешними репозиториями.

пункт: http://pip.openplans.org/ и работа с pip / virtualenv: http://www.b -list.org / weblog / 2008 / dec / 15 / pip /

0 голосов
/ 27 августа 2013

Я думаю, что мой ответ на другие вопросы дает точное решение для проблемы, описанной здесь, не вдаваясь в адские подмодули (которые я пробовал, но даже не приближается к svn: externals, которые я использовал в)

Тем не менее, посмотрите на этот ответ: Вы управляете версией отдельных приложений или всего проекта или обоих?

Прежде чем снова удалить мой ответ, я не знал, что не могу скопировать свой ответ на другой вопрос, даже если я убежден, что он полезен в качестве ответа. Извините, но попробуйте этот ответ, это действительно хорошее решение. Поэтому я надеюсь, что мне позволено обратиться к моему собственному ответу на другой вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...