Управление множеством репозиториев git - PullRequest
66 голосов
/ 03 мая 2009

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

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

Итак, у меня есть каталог со множеством репозиториев.

  1. Как я могу получить их все?
  2. Как я могу проверить, есть ли у кого-нибудь незафиксированные изменения?
  3. Как я могу проверить, есть ли изменения в слиянии?

И было бы неплохо сделать это с помощью одной команды.

Вывод должен быть достаточно тихим, чтобы на самом деле замечать, что нужно делать.

Ответы [ 17 ]

40 голосов
/ 28 февраля 2011

Я настоятельно рекомендую инструмент для нескольких репозиториев mr . Раньше я использовал собственный сценарий оболочки, как это было рекомендовано другими в течение некоторого времени, но использование mr дает мне следующие преимущества:

  • Это универсально: может использоваться сочетание различных систем контроля версий, а не только git (например, Mercurial, SVN и т. Д.).
  • Это быстро: г-н может выполнять несколько заданий параллельно. Я использую несколько git / mercurial репозиториев и синхронизирую их несколько раз в день. Мистер чрезвычайно ускоряет этот процесс.
  • Легко и быстро управлять списком проверок хранилища. Просто используйте 'mr register', а не изменяйте список проектов в вашем собственном скрипте.

Относительно вашего вопроса о выводе без вывода сообщений: уровень детализации можно изменить с помощью ключа командной строки -q. Я предпочитаю вывод по умолчанию, который, по-видимому, приятно объединяет вывод в краткую и понятную сводку.

Я использую следующий псевдоним для команды mr, чтобы гарантировать, что mr всегда выбирает мой список проектов по умолчанию, хранящийся в $ HOME, и использует 5 параллельных потоков:

alias mr='mr -d ~/ -j 5 '
14 голосов
/ 03 июля 2012

Должен сказать, что я начал с принятого в настоящее время ответа (просто набор сценариев помощников, которые перебирают репозитории), но в целом мне не хватало опыта.

Итак, попробовав mr, repo и git-submodules, я обнаружил, что у каждого из них по-своему не хватает, и в итоге я сделал свой собственный вариант: http://fabioz.github.io/mu-repo, который на данный момент является зрелым инструментом он имеет рабочие процессы, которые позволяют вам:

  • клонировать несколько репо
  • diff (и редактировать) текущие изменения в нескольких репо
  • предварительный просмотр входящих изменений
  • запуск команд в нескольких репозиториях параллельно
  • создание групп репо
  • запускать команды, не относящиеся к git, через несколько репозиториев
  • и т. Д. (См. домашнюю страницу для получения дополнительной информации).

Обратите внимание, что он поддерживает любую ОС, в которой работает Python;)

11 голосов
/ 19 октября 2014

гр (git-run) расширяет функциональность mr (только для git). Мне проще организовать несколько репозиториев git, используя систему тегов. Код для gr не очень хорошо поддерживается. Если вы используете bash, убедитесь, что вы используете его с формой -t tag вместо #tag.

7 голосов
/ 03 мая 2009

Вы можете попробовать использовать repo с пользовательским файлом manifest.xml, чтобы указать, где находятся ваши репозитории. некоторая документация о том, как это сделать.

В качестве альтернативы вы можете использовать git-submodule(1) .

4 голосов
/ 15 марта 2012

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

Это обычно используется для проектов, где вам нужно собрать несколько репозиториев вместе и хранить их в одной ветке или теге в одно и то же время или в любом другом месте. Для моего каталога (пустых) репозиториев у меня просто есть небольшой make-файл, который позволяет мне запускать произвольные команды git, которые, как вы видите, я в основном использую для fsck и gc:

full: fsck-full gc-aggressive
        @:

fsck-full:
        for f in */.; do (cd $$f; echo $$f; git fsck --full || echo $$f FAILED); done

gc-aggressive:
        for f in */.; do (cd $$f; echo $$f; git gc --aggressive || echo $$f FAILED); done

%:
        for f in */.; do (cd $$f; git $@ || echo $$f FAILED); done
3 голосов
/ 07 января 2019

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

После обнаружения хранилища «отслеживаются». Это просто покажет их в списке локальных репозиториев, включая плотную информацию о статусе, вдохновленную posh-git . Он содержит текущую ветку и другие вещи, такие как изменения файла и количество входящих или исходящих коммитов.

RepoZ UI

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

RepoZ Navigation

«Как я могу получить их все?»

Версия для Windows предлагает контекстное меню для извлечения или извлечения хранилища. С помощью функции multi-select вы можете одновременно выполнять действия в нескольких хранилищах.

Однако, вы можете найти еще одну очень полезную функцию:

RepoZ Auto-Fetch

С помощью функции автоматической выборки вы можете указать RepoZ, чтобы он периодически выбирал удаленные объекты всех ваших репозиториев git в фоновом режиме. Конечно, эти извлечения не будут конфликтовать с вашими локальными коммитами. Нет локальных попыток слияния, как с git pull.

3 голосов
/ 22 декабря 2016

Для этого вы можете использовать камень git-status-all: https://github.com/reednj/git-status-all

# install the gem    
gem install git-status-all

# use the status-all subcommand to scan the directory
git status-all

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

git status-all --fetch

git status all

3 голосов
/ 07 мая 2009

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

#!/bin/sh
if [ ! "$1" = "" ] ; then

   if [ "$GITREPO" = "" -a -d "$HOME/cm/src" ] ; then
      GITREPO="$HOME/cm/src"
   fi

   if [ "$GITREPO" != "" ] ; then

      echo "Git repositories found in $GITREPO"
      echo "-=-=-=-=-=-=-=-=-=-=-=-=-=-"

      DIRS="`/bin/ls -1 $GITREPO`"

      for dir in $DIRS ; do

         if [ -d $GITREPO/$dir/.git ] ; then
            echo "$dir -> git $1"
            cd $GITREPO/$dir ; git $@
            echo
         fi

      done
   else

      echo "Git repositories not found."

   fi
fi

По умолчанию скрипт ищет git-репозитории в ~ / cm / src, но вы можете переопределить это, установив переменную окружения GITREPO по своему вкусу.

Этот скрипт основан на этом скрипте .

1 голос
/ 25 августа 2018

Я создал псевдоним и функцию для запуска любой команды git во всех репозиториях, доступных в каталоге (рекурсивно). Вы можете найти его здесь: https://github.com/jaguililla/dotfiles/git

Это код:

#!/bin/sh
# To use it: source git_aliases

# Example: rgita remote \;
alias rgita='find . -type d -name .git -execdir git'

# Example: rgit remote -vv
rgit() {
  rgita "$@" \;
}

Надеюсь, это поможет:)

1 голос
/ 25 апреля 2018

Я написал эту простую функцию bash в свой .bash_profile, чтобы можно было запускать git, maven, gradle или любую другую команду bash только во всех репозиториях git:

# usefull function to work with multiple git repositories
all() {
    failed=0
    printf '>>> START RUNNING: "%s" >>>' "$*"
    for d in */; do
        pushd "$d" > /dev/null
        if [ -d ".git" ]
        then
            printf '\n--------------------------------------------\n\n'
            pwd
            eval $@
            if [ $? -ne 0 ]
            then
                failed=1
                break;
            fi
        fi
        popd > /dev/null
    done
    if [ $failed -eq 0 ]
    then
        printf '\n--------------------------------------------\n'
        printf '<<< RAN "%s" WITH SUCCESS!!! <<<' "$*"
    else
        printf '\n<<< FAILED!!! <<<'
    fi
}

Это можно использовать таким образом

all git st
all git pull
all ./gradlew clean test
etc.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...