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.
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.
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:
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 '
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:
Notez qu'il supporte tous les systèmes d'exploitation sur lesquels Python s'exécute;)
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
.
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
) .
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
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 .
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
Je viens de créer un outil qui fait ce que vous voulez!
gmaster fetch
gmaster status
gmaster status
Il s'appelle gitmaster: https://github.com/francoiscabrol/gitmaster
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.
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?
Comment puis-je vérifier si certains d'entre eux ont des modifications non validées?
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.
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.
npm install -g git-pull-all
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
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.
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.
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:
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
.
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 :)
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.
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
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 suivisComment puis-je vérifier si certains d'entre eux ont des modifications à fusionner?
Les noms de branche sont colorés de 5 manières
Pour l'installer, lancez simplement
pip3 install -U gita
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'