web-dev-qa-db-fra.com

Gestion de nombreux référentiels git

Configurer un projet est facile dans git et je peux donc avoir un référentiel séparé même pour de petits scripts. Maintenant, le problème est de savoir comment les gérer.

Je travaille à plusieurs endroits avec ces dépôts. Une fois les modifications apportées à un référentiel, je souhaite pouvoir mettre à jour les référentiels ailleurs.

J'ai donc un répertoire avec de nombreux référentiels.

  1. Comment puis-je aller les chercher tous?
  2. Comment puis-je vérifier si certains d'entre eux ont des modifications non validées?
  3. Comment puis-je vérifier si certains d'entre eux ont des modifications à fusionner?

Et ce serait bien de pouvoir les faire avec une seule commande.

La sortie doit être suffisamment silencieuse pour que vous sachiez réellement quoi faire.

65
iny

Je recommande fortement l'outil de référentiels multiples mr . J'utilisais depuis longtemps un script Shell personnalisé, comme le recommandent d'autres personnes, mais l'utilisation de mr présente les avantages suivants:

  • C'est générique: une conjonction de divers systèmes de contrôle de version peut être utilisée, pas seulement git (par exemple, Mercurial, SVN, etc.).
  • C'est rapide: mr peut exécuter plusieurs tâches en parallèle. J'utilise plusieurs référentiels git/Mercurial et les synchronise plusieurs fois par jour. M. accélère énormément ce processus.
  • Il est facile et rapide de gérer la liste des extractions de référentiel. Utilisez simplement 'mr register' plutôt que de modifier la liste des projets dans votre script personnalisé.

Concernant votre question sur la sortie silencieuse: Le niveau de verbosité peut être modifié à l’aide du commutateur de ligne de commande -q. Je préfère la sortie par défaut qui semble unifier parfaitement la sortie dans un résumé court et clair.

J'utilise l'alias suivant pour la commande mr afin de m'assurer que mr choisit toujours la liste de projets par défaut stockée dans $ HOME et utilise 5 threads parallèles:

alias mr='mr -d ~/ -j 5 '
39
Sandro Giessl

Je dois dire que j'ai commencé avec la réponse actuellement acceptée (juste un tas de scripts helpers qui parcourent les référentiels), mais dans l'ensemble, c'était une expérience manquante pour moi.

Donc, après avoir essayé mr, repo et git-submodules, j’ai trouvé que chacun manquait d’une manière différente, j’ai donc fini par créer ma propre variante: http://fabioz.github.io/mu-repo qui est un outil mature à ce stade - il a des workflows qui vous permettent de:

  • cloner plusieurs repos
  • diff (et édite) les modifications en cours dans plusieurs dépôts
  • prévisualiser les modifications entrantes
  • exécuter des commandes dans plusieurs dépôts en parallèle
  • créer des groupes de repos
  • exécuter des commandes non liées à git sur plusieurs dépôts
  • etc (voir homepage pour plus d’informations).

Notez qu'il supporte tous les systèmes d'exploitation sur lesquels Python s'exécute;)

13
Fabio Zadrozny

gr (git-run) étend la fonctionnalité de mr (uniquement pour git). Je trouve plus facile d'organiser plusieurs dépôts avec git en utilisant son système de balises. Le code pour gr n'est pas bien maintenu cependant. Si vous utilisez bash, assurez-vous de l'utiliser avec le code -t tag au lieu du formulaire #tag.

10
Memming

Vous pouvez essayer d'utiliser repo avec un fichier manifest.xml personnalisé pour spécifier l'emplacement de vos référentiels. Il y a de la documentation sur la façon de le faire.

Vous pouvez également utiliser git-submodule(1) .

6
Spoike

gitslave est un outil qui peut exécuter la même commande sur plusieurs référentiels en créant une relation superprojet/sous-projet entre le super et le sous-projet. Ceci (par défaut) fournit un résumé de la sortie afin que vous puissiez vous concentrer sur les référentiels qui fournissent une sortie unique (utile pour le statut git, moins utile pour les fichiers git ls).

Cela est généralement utilisé pour les projets où vous devez assembler plusieurs référentiels et les conserver sur la même branche ou balise au même moment ou à un autre moment. Pour mon répertoire de référentiels (nus), j'ai juste un petit fichier makefile qui me permet d'exécuter des commandes git arbitraires que, comme vous voyez, j'utilise principalement pour fsck et 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
4
Seth Robertson

J'utilise ce script pour exécuter facilement des commandes git dans tous mes référentiels.

#!/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

Par défaut, le script recherchera les référentiels git dans ~/cm/src mais vous pouvez le remplacer en définissant la variable d'environnement GITREPO à votre convenance.

Ce script est basé sur ce script

3
Scotts

Vous pouvez utiliser le joyau git-status-all pour cela: 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

Il existe également une option d'extraction qui extraira Origin pour tous les référentiels avant d'afficher le statut:

git status-all --fetch

 git status all

3
Nathan

Je viens de créer un outil qui fait ce que vous voulez! 

  1. Comment puis-je aller les chercher tous? gmaster fetch
  2. Comment puis-je vérifier si certains d'entre eux ont des modifications non validées? gmaster status
  3. Comment puis-je vérifier si certains d'entre eux ont des modifications à fusionner? gmaster status

Il s'appelle gitmaster: https://github.com/francoiscabrol/gitmaster

1
francoiscabrol

J'ai écrit cette fonction bash simple dans mon .bash_profile pour pouvoir exécuter git, maven, gradle ou toute autre commande bash dans tous les référentiels git uniquement:

# 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
}

Cela peut être utilisé de cette façon

all git st
all git pull
all ./gradlew clean test
etc.
1
ChaudPain

Avertissement: je travaille sur cet outil à l'adresse www.repoflow.com

Comment puis-je aller les chercher tous?
Comment puis-je vérifier si certains d'entre eux ont des modifications à fusionner?

  • Vous pouvez récupérer tous les référentiels impliqués (ou les pousser/les extraire/les valider). Une fois que l'extraction aura été extraite, le nouvel état du référentiel sera mis à jour. Si le référentiel est divergé, vous pouvez voir le type de conflits et commencer à les fusionner.

enter image description here

Comment puis-je vérifier si certains d'entre eux ont des modifications non validées?

  • Sur l'interface utilisateur, vous pouvez voir l'état des fichiers pour chaque référentiel (vous pouvez les ajouter/les supprimer individuellement ou en bloc).

enter image description here

Je travaille là-dessus, mais ceci résout également les questions de l'OP et vous aide à gérer plusieurs référentiels en général. Vous pouvez utiliser l'interface utilisateur ou l'API GraphQL sous-jacente pour créer vos propres scripts. Veuillez le considérer comme une autre option.

0
Victor Jimenez

Il existe un outil pratique pour récupérer tous les référentiels. git-pull-all est un outil de ligne de commande à exécuter sur plusieurs référentiels git de manière asynchrone.

Installation

npm install -g git-pull-all

Usage

Supposons que vous avez ces fichiers et répertoires:

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

Lorsque vous exécutez la commande git-pull-all sur le répertoire ~/Projects, elle devrait trouver des référentiels git enfants (dans le cas ci-dessus cool-examples et super-express ) puis exécutez git pull sur chacun d’eux.

$ 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

Lien GitHub: https://github.com/tatsuyaoiw/git-pull-all

0
Alper Ebicoglu

J'ai écrit un outil appelé " RepoZ " qui détecte automatiquement les référentiels git dès que vous les clonez ou les modifiez, comme changer de branche, par exemple. 

Une fois trouvés, les référentiels sont "suivis". Cela les affichera simplement dans une liste de référentiels locaux comprenant une information de statut dense inspirée de posh-git . Il contient la branche actuelle et d'autres éléments tels que les modifications de fichiers et le nombre de validations entrantes ou sortantes.

 RepoZ UI

Cela aide à garder une trace de vos référentiels locaux et des travaux non terminés à valider ou Push. De plus, vous pouvez utiliser la liste de référentiels comme navigation pour basculer d'un référentiel à un autre. 

 RepoZ Navigation

"Comment puis-je aller les chercher tous?"

La version pour Windows propose un menu contextuel pour extraire ou extraire un référentiel. Avec la sélection multiple, vous pouvez exécuter des actions sur plusieurs référentiels à la fois.

Cependant, vous pourriez trouver une autre fonctionnalité très utile:

 RepoZ Auto-Fetch

Avec la récupération automatique, vous pouvez demander à RepoZ de récupérer périodiquement les télécommandes de tous vos référentiels git en arrière-plan. Bien entendu, ces recherches ne seront pas en conflit avec les commits locaux. Il n'y a pas de tentative de fusion locale comme avec git pull.

0
Waescher

J'ai créé un alias et une fonction pour exécuter toutes les commandes git sur tous les référentiels disponibles dans un répertoire (de manière récursive). Vous pouvez le trouver ici: https://github.com/jaguililla/dotfiles/git

C'est le code:

#!/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 "$@" \;
}

J'espère que ça aide :)

0
jamming

Vous devriez vérifier rgit sur le CPAN qui exécute de manière récursive les commandes git sur tous les référentiels d'une arborescence de répertoires.

De la docs:

Cet utilitaire effectue une recherche récursive dans un fichier répertoire racine (qui peut être le répertoire de travail current ou - s'il a été défini - le répertoire indiqué par la variable d'environnement GIT_DIR) pour tous les dépôts git, triez cette liste par le chemin du référentiel, chdir dans chacun d'eux, et exécute le commande git spécifiée.

0
Brian Phillips

J'ai écrit un outil en ligne de commande appelé gita pour gérer plusieurs dépôts. Il affiche l’état des pensions livrées côte à côte, par exemple

 enter image description here

Il peut également déléguer des commandes/alias git à partir de n'importe quel répertoire de travail. 

Maintenant, pour répondre à vos questions en utilisant cet outil:

Comment puis-je aller les chercher tous?

gita fetch

Comment puis-je vérifier si certains d'entre eux ont des modifications non validées?

La commande gita ls affiche 3 symboles possibles à côté du nom de la branche, ce qui indique

  • +: changements mis en scène
  • *: modifications non mises en scène
  • _: fichiers/dossiers non suivis

Comment puis-je vérifier si certains d'entre eux ont des modifications à fusionner?

Les noms de branche sont colorés de 5 manières

  • blanc: la branche locale n'a pas de branche distante
  • vert: la branche locale est identique à la branche distante
  • rouge: la branche locale a divergé de la branche distante
  • violet: la branche locale est en avance sur la branche distante (bon pour Push)
  • jaune: la branche locale est derrière la branche distante (bon pour la fusion)

Pour l'installer, lancez simplement 

pip3 install -U gita
0
nos

Si quelqu'un regarde encore ce fil, veuillez consulter mon script Shell appelé gitme

vous devrez saisir manuellement votre dépôt Git local, mais j'utilise cet outil tous les jours pour collaborer avec plusieurs projets Git sur plusieurs ordinateurs. 

vous pouvez exécuter git clone https://github.com/robbenz/gitme.git

aussi le script est affiché ci-dessous

#!/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

J'ai configuré un alias dans mon fichier ~/.bash_profile pour alias gitme='sh /path/to/gitme.sh'

0
RobBenz