Керування багатьма сховищами git


85

Налаштування проекту легко у git, тому я можу мати окреме сховище навіть для невеликого сценарію. Тепер проблема полягає в тому, як ними керувати.

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

Отже, у мене є каталог із багатьма сховищами.

  1. Як я можу отримати їх усіх?
  2. Як я можу перевірити, чи є в кожному з них незмінені зміни?
  3. Як я можу перевірити, чи є в будь-якому з них зміни для об’єднання?

І було б непогано мати можливість робити це за допомогою однієї команди.

Вихід повинен бути досить тихим, щоб насправді помітити те, що потрібно зробити.


Те ж питання відповів на hg mercurial.
Serge Stroobandt

Відповіді:


44

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

  • Це загальне: може використовуватися поєднання різних систем контролю версій, а не лише git (наприклад, Mercurial, SVN тощо).
  • Це швидко: пан може виконувати кілька завдань паралельно. Я використовую кілька сховищ git / mercurial і синхронізую їх кілька разів на день. Пан надзвичайно пришвидшує цей процес.
  • Управляти списком оформлення сховищ легко і швидко. Просто використовуйте "mr register", а не змінюйте список проектів у своєму користувацькому сценарії.

Щодо вашого запитання про тихий вихід: Рівень деталізації можна змінити за допомогою перемикача командного рядка -q. Я віддаю перевагу виводу за замовчуванням, який, здається, добре уніфікує результат у короткому та зрозумілому підсумку.

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

alias mr='mr -d ~/ -j 5 '

5
Чи підтримує він Windows?
Фіцчак Іцчакі,

це чудово, але не підтримує тегування git (станом на 2016-08)
Уго Сарагоса

@CADbloke він не згадує про вікна на сторінці встановлення, але як скрипт Perl він може / повинен / міг би працювати на вікнах.
Scipilot

2
@HugoZaragoza, ти завжди можеш визначити цю команду самостійно [ЗАВДАННЯ] tag = git tag "$ @"
AlexS

2
alias pa='find . -name .git -print -execdir git pull \;'тоді paдосить
DawnSong

19

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

Отож, спробувавши mr, repo та git-підмодулі, я виявив, що кожному бракує по-різному, отже, в підсумку я зробив свій власний варіант: http://fabioz.github.io/mu-repo, який є зрілим інструментом у цей момент - він має робочі процеси, які дозволяють вам:

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

Зверніть увагу, що він підтримує будь-яку ОС, де працює Python;)


Ваша відповідь свідчить про те, що му-репо краще, ніж те, що робить пан. Але mu-repo не підтримує не git-репо.
Шаунак Сонтакке

1
Колесо, його мета - насправді підтримувати лише репозиторії git (саме це і задається питанням) - хоча ви можете mu sh <some command>виконати якусь довільну команду і в декількох репозиторіях, уся остаточна справа стосується git, а не інших систем контролю версій .. Якщо вам це потрібно, тоді так, будь ласка, використовуйте інший інструмент.
Фабіо Задрозний

14

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



8

Ви можете спробувати використовувати repo із користувацьким manifest.xmlфайлом, щоб вказати, де знаходяться ваші сховища. Існує деяка документація про те, як це зробити.

Ви також можете використовувати git-submodule(1) .


2
git-submodule було б добре, якби я хотів зберегти сховища в точно такому ж стані, але це не так. Набір сховищ неоднаковий у кожному місці. Можуть бути незмінені зміни. Можуть бути зміни, які я поки не хочу об’єднувати.
iny

Я не знав про git-підмодуль. Дякуємо, що згадали.
sykora

Документація для репо є досить мінімальною і, схоже, вона призначена для різних типів робочих процесів, які я хочу використовувати.
iny

6

Я написав інструмент під назвою " RepoZ ", який автоматично виявляє сховища git, як тільки ви їх клонуєте або щось змінюєте, наприклад, перемикання гілки.

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

Інтерфейс користувача RepoZ

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

Навігація RepoZ

"Як я можу забрати їх усіх?"

Версія для Windows пропонує контекстне меню для отримання або витягування сховища. За допомогою мультивибору ви можете виконувати дії одночасно з кількома сховищами.

Однак, можливо, вам знадобиться ще одна функція:

RepoZ Auto-Fetch

За допомогою функції автоматичного отримання ви можете сказати RepoZ періодично отримувати пульти всіх ваших сховищ git у фоновому режимі. Звичайно, ці завантаження не зіткнуться з вашими локальними комітами. Немає спроб локального об’єднання, як у git pull.


Так, дуже погано і не заслужено. Відкритий для PR в будь-який час. Пінг мене.
Waescher

5

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

5

Я створив псевдонім та функцію для запуску будь-якої команди 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
струнка і корисна!
Кевін Чоу

Фантастично! Простий один лайнер покласти в .bash_aliases: alias rgit='function _rgit(){ find . -type d -name .git -printf "\n%p\n" -execdir git "$@" \;; }; _rgit'. Джерело, потім, наприклад, дзвінок rgit status.
ford04

4

Для цього ви можете використовувати 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 статус все


1
Дуже хороший підхід. На відміну від більшості інструментів, за якими голосували більше, немає необхідності спочатку реєструвати сховища, натомість він просто перевіряє всі підкаталоги.
луатор

find . -name .git -print -execdir git status \;це нормально
DawnSong

3

Я використовую цей скрипт для легкого виконання команд 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 на свій смак.

Цей сценарій заснований на цьому сценарії .


find . -name .git -print -execdir git pull \;робить те, що ти думаєш.
DawnSong

3

Я написав інструмент командного рядка під назвою gita для управління кількома репозиторіями. Наприклад, він відображає статус зареєстрованих РЕПО

введіть тут опис зображення

Він також може делегувати команди / псевдоніми git з будь-якого робочого каталогу.

Тепер, щоб відповісти на ваші запитання за допомогою цього інструменту:

Як я можу отримати їх усіх?

gita fetch

Як я можу перевірити, чи є в кожному з них незмінені зміни?

У gita lsкоманда показує 3 можливих символів поряд з ім'ям гілки, що вказує на

  • +: поетапні зміни
  • *: нестадійні зміни
  • _: файли / папки без відстеження

Як я можу перевірити, чи є в будь-якому з них зміни для об’єднання?

Назви гілок забарвлені у 5 способів

  • білий: локальне відділення не має віддаленого відділення
  • зелений: локальна гілка - те саме, що віддалена гілка
  • червоний: локальна гілка відхилилася від віддаленої гілки
  • фіолетовий: локальна гілка випереджає віддалену гілку (добре для push)
  • жовтий: локальна гілка знаходиться за віддаленою гілкою (добре для злиття)

Щоб встановити його, просто запустіть

pip3 install -U gita

2

Якщо хтось все ще переглядає цю тему, перевірте мій сценарій оболонки під назвою 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

Я встановив псевдонім у своєму ~ / .bash_profile так alias gitme='sh /path/to/gitme.sh'


1

Вам слід перевірити rgit на CPAN, який рекурсивно виконує команди git у всіх сховищах у дереві каталогів.

З документів:

Ця утиліта здійснює рекурсивний пошук у кореневому каталозі (який може бути поточним робочим каталогом або - якщо він встановлений - каталогом, заданим змінною середовища GIT_DIR) для всіх сховищ git, відсортуйте цей список за шляхом до сховища, chdir у кожному з їх і виконує вказану команду git.


1

Я щойно створив інструмент, який робить те, що ти хочеш!

  1. Як я можу отримати їх усіх? gmaster fetch
  2. Як я можу перевірити, чи є в кожному з них незмінені зміни? gmaster status
  3. Як я можу перевірити, чи є в будь-якому з них зміни для об’єднання? gmaster status

Він називається gitmaster: https://github.com/francoiscabrol/gitmaster


1

Я записав цю просту функцію 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.

їх також можна було б запустити паралельно, використовуючи: all './gradlew clean test &'
ChaudPain

0

Застереження: я працюю над цим інструментом на веб-сайті www.repoflow.com

Як я можу отримати їх усіх?
Як я можу перевірити, чи є в будь-якому з них зміни для об’єднання?

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

введіть тут опис зображення

Як я можу перевірити, чи є в кожному з них незмінені зміни?

  • В інтерфейсі ви можете бачити стан файлів для кожного сховища (Ви можете додавати / видаляти їх окремо або масово).

введіть тут опис зображення

Я працюю над цим, але це також вирішує питання OP та допомагає керувати кількома сховищами загалом. Ви можете використовувати інтерфейс користувача або базовий API GraphQL для створення власних сценаріїв, будь ласка, розгляньте це як інший варіант.


0

Існує зручний інструмент для отримання всіх безлічі сховищ. git-pull-all- це інструмент командного рядка для асинхронного виконання на декількох сховищах git.

Встановлення

npm install -g git-pull-all

Використання

Припустимо, у вас є ці файли та каталоги:

~/Projects/
  cool-examples/
    .git/
  funny-movies/
  my-todos.txt
  super-express/
    .git/

Коли ви запускаєте git-pull-allкоманду в ~/Projectsкаталозі, вона повинна знайти дочірні сховища git (у наведеному вище випадку cool-examples та super-express ), а потім виконати git pullна кожному з них.

$ cd ~/Projects
$ git-pull-all
funny-movies/
Not a git repository
cool-examples/
Already up-to-date.
super-express/
Already up-to-date.
Done!
git-pull-all ~/Projects

Посилання на GitHub: https://github.com/tatsuyaoiw/git-pull-all


0

Я використовую код Visual Studio. У нашій базі коду є близько 20 бібліотек, які є окремими репозиторіями Git, і вкладка керування джерелом у Visual Studio Code цілком непогана для того, щоб побачити "на перший погляд" уявлення про те, наскільки відстають або випереджають місцеві репо. Є також налаштування для періодичного отримання, щоб оновлювати цю інформацію, а також кнопка оновлення.

Це не так зручно, як сценарій, але коли справа доходить до контролю джерел для мене, мені подобається бути тим, хто вносить зміни. Потрібен дуже добре написаний сценарій, щоб бути обережним, щоб не перезаписати зміни тощо. Завдяки підходу VS Code ви швидко отримуєте велику кількість інформації, на яку ви можете вплинути самі.

Ось знімок екрану, як це виглядає:

Вікно керування джерелом у VS Code


0

Я знайшов чудове рішення для витягування з поточної гілки з усіх підкаталогів, у яких є папка .git, навіть якщо кожне репо має іншу гілку. Команда є однолінійною, досить гнучкою для модифікації для різних команд git і може бути псевдонімом.

Просто скопіюйте та вставте наступне:

find . -type d -maxdepth 2 -name .git -exec sh -c 'cd $0 && cd .. && git pull origin $(git rev-parse --abbrev-ref HEAD)' {} \;

Розбивши його:

find . -type d -maxdepth 2 -name .git 

Знайдіть усі каталоги (-тип d) у поточному каталозі (find.), Які мають ім’я ".git" (-name .git), шукаючи максимум два каталоги вглиб (2, а не 1, оскільки ми шукаємо git у папці git repo).

-exec sh -c 

Запустіть наступну команду оболонки (exec sh -c)

'cd $0 && cd .. && git pull origin $(git rev-parse --abbrev-ref HEAD)'

Змініть каталог на перший аргумент (cd $ 0), потім змініть каталог на один рівень вище, щоб залишити папку .git (cd ..), потім виконайте git pull origin, вказавши гілку, запустивши git rev-parse ... для поточної гілки Фіксація HEAD.

{} \;

"{}" - це відносний шлях до результату, який ми отримуємо від початкової команди пошуку . The; використовується для завершення команди.

Перевірено на MacOS 10.14.6 на zsh. Як є, працює лише тоді, коли віддалені та місцеві відділення називаються однаково, AFAIK.

Ви можете змінити це, щоб отримати статус. Я сподіваюся, ви можете додати аргументи, щоб зробити це більш гнучким, але я ще не пробував.


-1

https://github.com/wwjamieson3/envisionTools має скрипт bash під назвою gitstat, який робить це та багато іншого. Він сумісний з GNU та mac. За запитом він може виконувати вилучення з пультів. Він показує відстежувані, модифіковані, додані, видалені та поетапні файли. Він відрізняється від пультів дистанційного керування, показуючи нез’єднані коміти на віддалених та невідправлених локальних комітах. Він також може відображати кольорові кодовані результати в зведеному або детальному режимі і навіть HTML. Він використовує локацію замість пошуку, оскільки це нескінченно швидше, і навіть запитує оновити базу даних локації, якщо вона стає занадто старою.


2
Дякуємо за розміщення Вашої відповіді! Будь ласка, уважно прочитайте поширені запитання щодо самореклами . Також зверніть увагу, що потрібно публікувати відмову від відповідальності кожного разу, коли ви переходите на свій сайт / продукт.
Ендрю Барбер,

3
На жаль, посилання github wwjamieson3 / envisionTools не працює.
Бренда Дж. Батлер

@williamJamieson - це envisionTools - це приватне сховище GitHub?
eebbesen

-5

Схоже, написати сценарій, щоб зробити це досить просто. По суті, йому потрібно переглядати сховища, а потім використовувати такі команди, як git ls-files, git diff та git log.


Я знаю, що пізно, але чи можете ви опублікувати сценарій?
l0b0

Немає "сценарію". Я використовую сценарій, який я написав для власних потреб, але він не є загальним.
iny

"git diff" насправді хитро, якщо ви хочете отримати один файл diff, який можна повернути та повторно застосувати за допомогою однієї команди патча.
proski

4
Буквально будь-яка з відповідей повинна бути прийнятою відповіддю, але це.
Кеннет Селесте,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.