Управление многими репозиториями git
настройка проекта легко в git, и поэтому я могу иметь отдельный репозиторий даже для небольшого скрипта. Теперь проблема в том, как ими управлять.
Я работаю в нескольких местах с этими репозиториями. Когда я внес изменения в какой-то репозиторий, я хочу иметь возможность обновлять репозитории в других местах.
поэтому у меня есть каталог со многими репозиториями в нем.
- как я могу получить все из них?
- как я могу проверить, есть ли какой-либо из них есть незафиксированные изменения?
- как я могу проверить, есть ли какие-либо из них изменения для слияния?
и было бы неплохо сделать это с помощью одной команды.
выход должен быть достаточно тихим, чтобы действительно заметить, что нужно делать.
14 ответов
Я настоятельно рекомендую инструмент нескольких репозиториев г. Я использовал пользовательский сценарий оболочки, как рекомендовали другие в течение некоторого времени, но использование mr имеет следующие преимущества для меня:
- это общий: можно использовать сочетание различных систем управления версиями, а не только git (например, Mercurial, SVN и т. д.).
- это быстро: mr может выполнять несколько заданий параллельно. Я использую несколько репозиториев git/mercurial и синхронизирую их несколько раз в день. Mr чрезвычайно ускоряет этот процесс.
- легко и быстро управлять список касс. Просто используйте "mr register" вместо изменения списка проектов в вашем пользовательском скрипте.
Что касается вашего вопроса о silent output: уровень детализации можно изменить с помощью переключателя командной строки-q. Я предпочитаю вывод по умолчанию, который, кажется, хорошо объединяет вывод в коротком и ясном резюме.
Я использую следующий псевдоним для команды mr, чтобы убедиться, что mr всегда берет мой список проектов по умолчанию, хранящийся в $HOME, и использует 5 параллельных потоков:
alias mr='mr -d ~/ -j 5 '
должен сказать, что я начал с принятого в настоящее время ответа (просто куча сценариев помощников, которые повторяют репозитории), но в целом, мне не хватало опыта.
Итак, попробовав mr, repo и Git-подмодули, я обнаружил, что каждому не хватает по-разному, поэтому я закончил свой собственный вариант:http://fabioz.github.io/mu-repo который является зрелым инструментом на данный момент-он имеет рабочие процессы, которые позволяют:
- клонировать несколько repos
- diff (и редактировать) текущие изменения в нескольких репозиториях
- предварительный просмотр входящих изменений
- запуск команд в нескольких репозиториях параллельно
- создать группы РЕПО
- выполнить команды, не связанные с git, через несколько репозиториев
- и т. д. (см. Домашняя страница для получения дополнительной информации).
обратите внимание, что он поддерживает любую ОС, где работает Python;)
Вы можете попробовать использовать РЕПО с пользовательским manifest.xml
файл, чтобы указать, где находятся ваши репозитории. Есть документация о том, как это сделать.
в качестве альтернативы вы можете использовать git-submodule(1
).
gitslave - это инструмент, который может запускать одну и ту же команду над многими репозиториями, создавая связь superproject/subproject между super и subs. Это (по умолчанию) обеспечивает суммирование вывода, поэтому вы можете сосредоточиться на репозиториях, которые предоставляют уникальный вывод (полезно для состояния 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
существует также опция fetch, которая будет получать из origin для всех репозиториев перед отображением статуса:
git status-all --fetch
Я только что создал инструмент, который делает то, что вы хотите!
- как я могу принести все из них?
gmaster fetch
- как я могу проверить, есть ли какие-либо из них незафиксированные изменения?
gmaster status
- как я могу проверить, есть ли какие-либо из них изменения для слияния?
gmaster status
он называется gitmaster:https://github.com/francoiscabrol/gitmaster
Я написал эту простую функцию bash в my .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 на всех репозиториях в дереве каталогов.
документы:
эта утилита рекурсивно ищет в корневой каталог (который может быть текущий рабочий каталог или-если это был установлен-каталог, заданный переменная среды 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. Он может выполнять выборки из пультов дистанционного управления, если его спросят. Он показывает неотслеженные, измененные, добавленные, удаленные и поэтапные файлы. Его разногласия с пультов показывая неслиянно совершает на пульты и unpushed локальные коммиты. Он также может отображать цветовые результаты в сводном или подробном режиме и даже HTML. Он использует locate вместо find потому что это бесконечно быстрее и даже предложит обновить базу данных locate, если она становится слишком старой.
похоже, написать сценарий, чтобы сделать это довольно легко. По сути, он должен перебирать репозитории, а затем использовать команды, такие как Git ls-files, git diff и git log.