Как организовать несколько репозиториев git, чтобы все они были скопированы вместе?

С SVN у меня было одно большое хранилище, которое я держал на сервере, и проверил несколько машин. Это была довольно хорошая система резервного копирования и позволила мне легко работать на любой из машин. Я мог бы проверить конкретный проект, зафиксировать и обновить проект "master", или я мог бы проверить все.

Теперь у меня есть куча репозиториев git для разных проектов, некоторые из которых находятся на github. У меня также есть репозиторий SVN, который я упомянул, импортированный с помощью команды git -svn.

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

Проблема заключается в том, что это частный репозиторий и git не позволяет проверять конкретную папку (что я мог бы нажать на github как отдельный проект, но изменения будут отображаться как в master-repo, и суб-РЕПО)

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

В настоящее время у меня есть папка git -repos (например, ~/code_projects/proj1/.git/~/code_projects/proj2/.git/), а после внесения изменений в proj1 я делаю git push github, то я копирую файлы в ~/Documents/code/python/projects/proj1/и делаю одно коммитирование (а не многочисленные в отдельных репозиториях). Затем выполните git push backupdrive1, git push mymemorystick и т.д.

Итак, вопрос: как ваш персональный код и проекты с репозиториями git, и сохраните их в синхронизации и резервном копировании?

Ответ 1

Я бы настоятельно советовал не помещать несвязанные данные в данный Git репозиторий. Накладные расходы на создание новых репозиториев вполне низкий, и это функция, которая позволяет сохранить разные линии полностью разделены.

Борьба с этой идеей означает, что она заканчивается излишне запутанной историей, что затрудняет администрацию и - более важно - инструменты "археологии" менее полезны из-за разведение. Кроме того, как вы упомянули, Git предполагает, что "единица клонирование "является хранилищем, и это практически необходимо из-за его распределенный характер.

Одним из решений является сохранение каждого проекта/пакета/и т.д. как его собственный голый репозиторий (т.е. без рабочего дерева) под благословенной иерархией, как:

/repos/a.git
/repos/b.git
/repos/c.git

Как только несколько конвенций были установлены, становится тривиальным применять административные операции (резервное копирование, упаковка, веб-публикация) до полная иерархия, которая выполняет роль, не совсем отличающуюся от "монолитные" хранилища SVN. Работа с этими репозиториями также становится несколько похожим на рабочие процессы SVN, с добавлением того, что один могут использовать локальные коммиты и ветки:

svn checkout   --> git clone
svn update     --> git pull
svn commit     --> git push

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

$ cd ~/dev
$ git clone /repos/foo.git       # or the one from github, ...
$ cd foo
$ git remote add github ...
$ git remote add memorystick ...

Затем вы можете извлекать/извлекать из каждого из "источников", работать и фиксировать локально, а затем нажмите ( "резервное копирование" ) на каждый из этих пультов, когда вы готовы с чем-то вроде (обратите внимание, как это толкает те же самые коммиты и истории для каждого из пультов!):

$ for remote in origin github memorystick; do git push $remote; done

Самый простой способ превратить существующий рабочий репозиторий ~/dev/foo в такой пустой хранилище, вероятно:

$ cd ~/dev
$ git clone --bare foo /repos/foo.git
$ mv foo foo.old
$ git clone /repos/foo.git

который в основном эквивалентен svn import, но не бросает существующей, "местной" истории.

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

Ответ 2

Я хочу добавить в ответ Damien, где он рекомендует:

$ for remote in origin github memorystick; do git push $remote; done

Вы можете настроить специальный пульт для нажатия на все отдельные реальные пульты с 1 командой; Я нашел его в http://marc.info/?l=git&m=116231242118202&w=2:

Итак, для "git push" (где это делает смысл выдвигать те же ветки несколько раз), вы действительно можете сделать что я делаю:

  • .git/config содержит:

    [remote "all"]
    url = master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
    url = login.osdl.org:linux-2.6.git
    
  • и теперь git push all master будет толкать ветвь "master" как на
    этих удаленных репозиториев.

Вы также можете сэкономить на вводе URL-адресов дважды, используя конструкцию:

[url "<actual url base>"]
    insteadOf = <other url base>

Ответ 3

я еще не пробовал вложенные репозитории git, потому что я не сталкивался с ситуацией, в которой мне нужно. Как я читал на # git channel git, кажется, путают, вставляя репозитории, то есть вы пытаетесь git -init внутри репозитория git. Единственный способ управлять вложенной структурой git - либо использовать git-submodule, либо Android repo.

Что касается этой ответственности за резервную копию, которую вы описываете, я говорю делегировать это... Для меня я обычно помещаю "исходный" репозиторий для каждого проекта на сетевом диске на работе, которая выполняется на регулярной основе по ИТ-технологиям по их стратегии резервного копирования по выбору. Это просто, и мне не о чем беспокоиться.;)

Ответ 4

Мне также любопытно предлагать способы справиться с этим и описать текущую настройку, которую я использую (с SVN). Я в основном создал репозиторий, который содержит иерархию мини файловой системы, включая свои собственные bin и lib dirs. В корне этого дерева есть script, который настроит вашу среду, чтобы добавить эти bin, lib и т.д. Другие источники в соответствующие переменные среды. Поэтому корневой каталог выглядит следующим образом:

./bin/            # prepended to $PATH
./lib/            # prepended to $LD_LIBRARY_PATH
./lib/python/     # prepended to $PYTHONPATH
./setup_env.bash  # sets up the environment

Теперь внутри /bin и/lib есть несколько проектов и их соответствующие библиотеки. Я знаю, что это не стандартный проект, но кому-то еще в моей группе очень легко проверить репо, запустить "setup_env.bash" script и иметь самые последние версии всех проектов локально в их оформлении. Им не нужно беспокоиться об установке/обновлении/usr/bin или /usr/lib, и это упрощает проведение нескольких проверок и очень локализованной среды для каждой проверки. Кто-то может также просто запустить весь репозиторий и не беспокоиться о деинсталляции каких-либо программ.

Это отлично работает для нас, и я не уверен, изменим ли мы его. Проблема в том, что в этом большом хранилище много проектов. Существует ли стандартный способ git/hg/bzr для создания такой среды и выработки проектов в свои собственные репозитории?

Ответ 5

Как использовать mr для управления несколькими репозиториями Git:

Команда mr (1) может проверять, обновлять или выполнять другие действия на набор репозиториев, как если бы они были одним объединенным репозиторием. Это поддерживает любую комбинацию подрывной деятельности, git, cvs, mercurial, bzr, darcs, cvs, vcsh, хранилища ископаемых и правдивости и поддержка для другие системы контроля версий могут быть легко добавлены. [...]

Он чрезвычайно настраивается с помощью простых сценариев оболочки. Некоторые примеры вещей, которые он может сделать, включают:

[...]

  • При обновлении репозитория Git вытащите из двух разных потоков вверх и объедините их вместе.
  • Выполнять несколько обновлений репозитория параллельно, значительно ускоряя процесс обновления.
  • Помните о действиях, которые не удалось из-за того, что ноутбук не подключен к сети, поэтому их можно повторить, когда он возвращается в сеть.

Ответ 6

Существует другой метод для вложенных репозиций git, но он не решает проблему, с которой вы столкнулись. Тем не менее, для тех, кто ищет решение, я был:

В верхнем уровне git репо просто спрячьте папку в .gitignore, содержащую вложенный репозиторий git. Это упрощает создание двух отдельных (но вложенных!) git репозиций.