Управление многими репозиториями git
настройка проекта легко в git и поэтому я могу иметь отдельный репозиторий даже для небольшого скрипта. Теперь проблема в том, как ими управлять.
Я работаю в нескольких местах с этими репозиториями. Когда я внес изменения в некоторые репозитории, я хочу иметь возможность обновлять репозитории в других местах.
Так что у меня есть каталог со многими репозиториями в нем.
- как я могу получить все из них?
- как я могу проверить, является ли любой из них есть незафиксированные изменения?
- как я могу проверить, есть ли какие-либо из них изменения для слияния?
и было бы неплохо сделать это с помощью одной команды.
выход должен быть достаточно тихим, чтобы на самом деле заметить, что нужно делать.
14 ответов:
Я настоятельно рекомендую инструмент несколько репозиториев г. Раньше я использовал пользовательский скрипт оболочки, как рекомендовали другие в течение некоторого времени, но использование mr имеет следующие преимущества для меня:
- это общий: можно использовать сочетание различных систем управления версиями, а не только git (например, Mercurial, SVN и т. д.).
- это быстро: mr может выполнять несколько заданий параллельно. Я использую несколько репозиториев git/mercurial и синхронизирую их несколько раз в день. Г-н чрезвычайно ускоряет этот процесс.
- легко и быстро управлять список касс. Просто используйте "Mr register" вместо изменения списка проектов в вашем пользовательском скрипте.
Что касается вашего вопроса о бесшумном выводе: уровень детализации может быть изменен с помощью переключателя командной строки-q. я предпочитаю вывод по умолчанию, который, как представляется, хорошо объединяет вывод в коротком и ясном резюме.
Я использую следующий псевдоним для команды mr, чтобы убедиться, что mr всегда берет мой список проектов по умолчанию, хранящийся в $HOME, и использует 5 параллельных потоков:
alias mr='mr -d ~/ -j 5 '
Я должен сказать, что начал с принятого в настоящее время ответа (просто куча сценариев помощников, которые повторяют репозитории), но в целом мне не хватало опыта.
Итак, попробовав mr, repo и Git-подмодули, я обнаружил, что каждый из них не хватает по-разному, поэтому я закончил делать свой собственный вариант:http://fabioz.github.io/mu-repo который является зрелым инструментом на данный момент-он имеет рабочие процессы, которые позволяют:
- клонировать несколько РЕПО
- diff (и редактировать) текущие изменения в нескольких репозиториях
- предварительный просмотр входящих изменений
- запуск команд в нескольких репозиториях параллельно
- создание групп РЕПО
- запуск команд, не связанных с git, через несколько репозиториев
- etc (см. Домашняя страница для получения дополнительной информации).
обратите внимание, что он поддерживает любую ОС, где работает Python;)
Вы можете попробовать использовать РЕПО с пользовательским
manifest.xmlфайл, чтобы указать, где находятся ваши репозитории. Есть документация о том, как это сделать.в качестве альтернативы вы можете использовать
git-submodule(1).
gitslave - это инструмент, который может выполнять одну и ту же команду над многими репозиториями, создавая отношения суперпроекта/подпроекта между супер и подпроектами. Это (по умолчанию) обеспечивает суммирование вывода, поэтому вы можете сосредоточиться на репозиториях, которые обеспечивают уникальный вывод (полезно для состояния git, не так полезно для ls-файлов git).
это обычно используется для проектов, где вам нужно собрать несколько репозиториев вместе и сохранить их на одном и том же ветка или тег в то же время или что-то еще. Для моего каталога (голых) репозиториев у меня просто есть небольшой makefile, который позволяет мне запускать произвольные команды 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
Я использую этот скрипт, чтобы легко выполнять команды git во всех моих репозиториях.
#!/bin/sh if [ ! "" = "" ] ; 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 " cd $GITREPO/$dir ; git $@ echo fi done else echo "Git repositories not found." fi fiпо умолчанию скрипт будет искать репозитории git в ~/cm / src, но вы можете переопределить это, установив переменную среды GITREPO по своему вкусу.
этот скрипт основан на этот скрипт.
можно использовать
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
Я только что создал инструмент, который делает то, что вы хотите!
- как я могу получить все из них?
gmaster fetch- как я могу проверить, есть ли у них незафиксированные изменения?
gmaster status- как я могу проверить, есть ли какие-либо из них изменения для слияния?
gmaster statusЭто называется gitmaster:https://github.com/francoiscabrol/gitmaster
Я написал эту простую функцию 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.
вы должны проверить rgit на CPAN, который рекурсивно выполняет команды git на всех репозиториях в дереве каталогов.
документы:
эта утилита рекурсивно ищет в a корневой каталог (который может быть текущий рабочий каталог или-если это был установлен-каталог, заданный переменная среды использование переменной git_dir) для все репозитории git, отсортируйте этот список по пути к репозиторию, chdir в каждый из них, и выполняет указанный команду git.
Если кто-то все еще смотрит на эту тему, пожалуйста, проверьте мой сценарий оболочки под названием gitme
вам нужно будет вручную ввести свои локальные репозитории git, но я использую этот инструмент каждый день для совместной работы нескольких проектов git на нескольких компьютерах.
вы можете запустить
git clone https://github.com/robbenz/gitme.gitтакже скрипт размещен ниже
#!/bin/bash -e REPOS=( /Users/you/gitrepo1 /Users/you/gitrepo2 /Users/you/gitrepo3 /Users/you/gitrepo4 ) MOVE="Moving to next REPO... \n" tput setaf 2;echo "What ya wanna do? You can say push, pull, commit, ftp push, or status"; tput sgr0 read input if [ $input = "commit" ] then tput setaf 2;echo "Do you want a unique commit message? [y/n]";tput sgr0 read ans if [ $ans = "y" ] then for i in "${REPOS[@]}" do cd "$i" tput setaf 6;pwd;tput sgr0 git add . -A read -p "Commit description: " desc git commit -m "$desc" tput setaf 2;echo $MOVE;tput sgr0 sleep 1 done else for i in "${REPOS[@]}" do cd "$i" tput setaf 6;pwd;tput sgr0 git add . -A git commit -m "autocommit backup point" tput setaf 2;echo $MOVE;tput sgr0 sleep 1 done fi elif [ $input = "push" ] || [ $input = "pull" ] || [ $input = "ftp push" ] || [ $input = "status" ] then for i in "${REPOS[@]}" do cd "$i" tput setaf 6;pwd;tput sgr0 git $input tput setaf 2;echo $MOVE;tput sgr0 sleep 1 done else tput setaf 1;echo "You have zero friends";tput sgr0 fiсоздать псевдоним в моем ~/.файл так
alias gitme='sh /path/to/gitme.sh'
Я сделал псевдоним и функцию для запуска любой команды 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 "$@" \; }надеюсь, что это помогает :)
https://github.com/wwjamieson3/envisionTools имеет скрипт bash под названием gitstat, который делает это и многое другое. Это GNU и Mac совместимы. Он может выполнять выборки из пультов дистанционного управления, если его спросят. Он показывает неотслеженные, измененные, добавленные, удаленные и поэтапные файлы. Он отличается от пультов дистанционного управления, показывая несвязанные коммиты на пультах дистанционного управления и не очищенные локальные коммиты. Он также может отображать результаты с цветовой кодировкой в сводном или подробном режиме и даже HTML. Он использует locate вместо find потому что это бесконечно быстрее и даже предложит обновить базу данных locate, если она становится слишком старой.
похоже, написать сценарий, чтобы сделать это довольно легко. По сути, он должен перебирать репозитории, а затем использовать команды, такие как git ls-files, git diff и git log.

Comments