Le chaos des dépôts Git
Au fil des années, j’ai vu mon répertoire personnel se transformer en un véritable dédale de projets Git clonés pas toujours avec une organisation optimale et la perte de temps que ca engendrait.
Frustré par cette situation et par l’absence d’outils adaptés à ma façon de travailler, j’ai écrit un script bash qui clone de manière plus pratique.
Il organise intelligemment les projets par fournisseur, crée des liens symboliques à la demande et s’intègre avec zoxide pour une navigation ultra-rapide. Une solution simple mais efficace qui a amélioré ma façon de gérer mes projets.
Fonctionnalités clés du script
- Organisation automatique par fournisseur : Le script détecte le fournisseur Git et structure vos dépôts dans des répertoires dédiés.
- Intégration avec zoxide : Chaque répertoire cloné est ajouté à zoxide pour une navigation simplifiée entre projets.
- Gestion des liens symboliques : Créez optionnellement un lien dans votre répertoire courant pour accéder rapidement au projet.
- Support des tokens : L’option
--token
permet de cloner facilement des dépôts privés sans compromettre vos identifiants. - Multi-fournisseurs : Compatible avec GitHub, GitLab, Bitbucket et d’autres plateformes de gestion de code source.
Installation et prérequis
Dépendances
Avant d’installer le script “clone”, assurez-vous d’avoir les outils suivants :
- git : Évidemment nécessaire pour cloner les dépôts
- fzf : Utilisé pour les confirmations interactives
- zoxide (optionnel) : Améliore la navigation entre les projets
Installation
# Téléchargez le script
curl -o ~/.local/bin/clone https://chemin-vers-votre-script/clone
# Rendez-le exécutable
chmod +x ~/.local/bin/clone
# Assurez-vous que ~/.local/bin est dans votre PATH
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Configuration
Le script utilise par défaut ~/repos
comme répertoire de base pour tous vos dépôts. Vous pouvez modifier cette valeur en éditant la variable BASE_DIR
au début du script si vous préférez une autre structure.
Exemples d’utilisation
Cloner un dépôt GitHub public
$ clone https://github.com/username/project.git
Repository cloned into /home/user/repos/github/project
Directory added to zoxide
Le script détecte automatiquement qu’il s’agit d’un dépôt GitHub, le place dans ~/repos/github/project
et l’ajoute à zoxide pour une navigation rapide.
Travailler avec des dépôts privés
$ clone https://gitlab.com/username/private-project.git --token
Enter your token: [votre token masqué]
Repository cloned into /home/user/repos/gitlab/private-project
Directory added to zoxide
L’option --token
vous permet d’entrer un token d’accès de manière sécurisée, sans l’exposer dans votre historique de commandes ou vos logs.
Créer un lien symbolique
Quand vous clonez un projet, le script vous propose de créer un lien symbolique dans votre répertoire courant :
Add symlink in current dir ?
> Yes
No
Symlink created in current directory
Cette option est pratique pour accéder rapidement au projet depuis votre emplacement actuel.
Gérer les dépôts existants
Si vous tentez de cloner un dépôt déjà présent dans votre structure :
⚠️ github/project already exists, overwrite it ?
> Yes
No
Vous pouvez choisir de conserver votre version locale ou de l’écraser avec la nouvelle.
Navigation avec zoxide
Une fois vos projets clonés, naviguez facilement entre eux grâce à l’intégration zoxide :
$ z project
# Vous amène directement à ~/repos/github/project
Le code 🤖
Voici le script en question :
#!/bin/bash
################################################################################
# Script Name: clone.sh
# Description: This script clones a Git repository from a given URL and organizes
# it into a directory structure based on the provider. It also adds
# the cloned directory to zoxide if zoxide is installed.
#
# Usage: clone <repository-url>
#
# Providers Supported:
# - GitHub (github.com)
# - GitLab (gitlab.com)
# - Bitbucket (bitbucket.org)
# - Azure DevOps (dev.azure.com)
# - AWS CodeCommit (git-codecommit.<region>.amazonaws.com)
# - Gitea (custom domains)
# - GitBucket (custom domains)
# - Custom providers with subdomains (e.g., <provider>.<company>.com)
#
# Requirements:
# - git (for cloning repositories)
# - zoxide (optional, for adding directories)
#
# License: MIT
# Copyright (c) 2025 🦊 Flobsx
#
################################################################################
# Base directory for cloned repositories (configurable)
BASE_DIR="${HOME}/repos"
# Function to clone a repository and add it to zoxide if installed
clone() {
local url="$1"
local provider=""
local projectpath=""
# Extract the domain from the URL
local domain=$(echo "$url" | sed -n 's|.*://\([^/]*\).*|\1|p')
if [ -z "$domain" ]; then
local domain=$(echo "$url" | sed -n 's/.*@\([^:/]*\).*/\1/p' || echo "$url" | sed -n 's|.*://\([^/]*\).*|\1|p')
fi
if [ -z "$domain" ]; then
echo "❌ Invalid URL"
return 1
fi
# Remove user:password@ or token@ if present
if [[ "$domain" =~ .*@(.*) ]]; then
domain="${BASH_REMATCH[1]}"
fi
# Determine the provider based on the domain
case "$domain" in
gitlab.com)
provider="gitlab"
;;
github.com)
provider="github"
;;
bitbucket.org)
provider="bitbucket"
;;
dev.azure.com)
provider="azure"
;;
git-codecommit.*.amazonaws.com)
provider="aws"
;;
*.gitea.*)
provider=$(echo "$domain" | sed -n 's/.*\.\(.*\)\.gitea.*/\1/p')
;;
*.gitbucket.*)
provider=$(echo "$domain" | sed -n 's/.*\.\(.*\)\.gitbucket.*/\1/p')
;;
*)
if [[ "$domain" =~ (.*)\.(.*).com ]]; then
provider="${BASH_REMATCH[2]}"
else
echo "Provider not recognized for domain: $domain"
return 1
fi
;;
esac
# Add token to the URL if provided
if [ -n "$TOKEN" ]; then
url=$(echo "$url" | sed "s|://$domain|://$TOKEN@$domain|")
fi
# Extract the project path from the URL
projectpath=$(echo "$url" | sed -n 's|.*/\([^.]*\)|\1|p' | sed 's/\.git$//')
# Define the target directory
local target_dir="$BASE_DIR/$provider/$projectpath"
# Create the provider directory if it doesn't exist
mkdir -p "$BASE_DIR/$provider"
# Check if the target directory already exists
if [ -d "$target_dir" ]; then
ADD_SYMLINK=$(fzf --header="⚠️ $provider/$projectpath already exists, overwrite it ?" --tac <<<$'Yes\nNo')
if [[ $ADD_SYMLINK == Yes ]]; then
echo "Overwriting the existing directory..."
rm -rf "$target_dir"
else
echo "Clone aborted"
return
fi
fi
# Clone the repository into the target directory
git clone "$url" "$target_dir"
echo "Repository cloned into $target_dir"
ADD_SYMLINK=$(fzf --header="Add symlink in current dir ?" --tac <<<$'Yes\nNo')
if [[ $ADD_SYMLINK == Yes ]]; then
ln -s "${target_dir}" .
echo "Symlink created in current directory"
fi
# Check if zoxide is installed and add the directory to zoxide
if command -v zoxide &> /dev/null; then
zoxide add "$target_dir"
echo "Directory added to zoxide"
# else
# echo "zoxide is not installed. Directory not added to zoxide."
fi
}
# Function to display help
display_help() {
echo "Usage: clone <repository-url> [--token] [--help]"
echo
echo "Description:"
echo "This script clones a Git repository from a given URL and organizes"
echo "it into a directory structure based on the provider. It also adds"
echo "the cloned directory to zoxide if zoxide is installed."
echo
echo "Options:"
echo " --token Prompt for a token to include in the repository URL."
echo " --help Display this help message."
echo
echo "Providers Supported:"
echo " - GitHub (github.com)"
echo " - GitLab (gitlab.com)"
echo " - Bitbucket (bitbucket.org)"
echo " - Azure DevOps (dev.azure.com)"
echo " - AWS CodeCommit (git-codecommit.<region>.amazonaws.com)"
echo " - Gitea (custom domains)"
echo " - GitBucket (custom domains)"
echo " - Custom providers with subdomains (e.g., <provider>.<company>.com)"
}
# Check if an argument is provided
if [ -z "$1" ] || [[ "$@" == *"--help"* ]]; then
display_help
exit 0
fi
# Check if --token flag is provided
TOKEN=""
if [[ "$@" == *"--token"* ]]; then
read -sp "Enter your token: " TOKEN
echo
fi
# Call the clone function with the provided URL
clone "$1"
Comment ça fonctionne
Détection du fournisseur
Le script commence par extraire le domaine de l’URL fournie en utilisant des expressions régulières :
local domain=$(echo "$url" | sed -n 's|.*://\([^/]*\).*|\1|p')
Une fois le domaine isolé, une structure case permet d’identifier le fournisseur :
case "$domain" in
gitlab.com)
provider="gitlab"
;;
github.com)
provider="github"
;;
# Autres fournisseurs...
esac
Pour les domaines personnalisés, le script utilise des expressions régulières plus complexes pour extraire la partie pertinente du nom de domaine.
Extraction du chemin du projet
Le script isole intelligemment le nom du projet depuis l’URL :
projectpath=$(echo "$url" | sed -n 's|.*/\([^.]*\)|\1|p' | sed 's/\.git$//')
Cette expression régulière extrait la dernière partie de l’URL (après le dernier slash) et supprime l’extension .git
si elle est présente.
Organisation des répertoires
Une structure cohérente est créée pour chaque projet :
local target_dir="$BASE_DIR/$provider/$projectpath"
mkdir -p "$BASE_DIR/$provider"
Cette approche organise tous les projets selon ~/repos/fournisseur/
projet, ce qui facilite énormément la navigation et la gestion.
Gestion des liens symboliques
Le script propose de créer un lien symbolique dans le répertoire courant via une interface interactive utilisant fzf :
ADD_SYMLINK=$(fzf --header="Add symlink in current dir ?" --tac <<<$'Yes\nNo')
if [[ $ADD_SYMLINK == Yes ]]; then
ln -s "${target_dir}" .
echo "Symlink created in current directory"
fi
Intégration avec zoxide
Pour faciliter la navigation ultérieure, le script ajoute automatiquement le répertoire cloné à zoxide :
if command -v zoxide &> /dev/null; then
zoxide add "$target_dir"
echo "Directory added to zoxide"
fi
Cette fonctionnalité permet ensuite d’accéder au projet depuis n’importe où en utilisant simplement z nom-du-projet
.
Comment ce script a transformé mon workflow
Ce script a été un véritable game-changer dans ma gestion quotidienne de projets. Fini les minutes perdues à rechercher mes repos !
À vous de jouer
Ce script reste volontairement simple et modulaire. N’hésitez pas à l’adapter à vos besoins ou à le faire évoluer.
Le script est disponible sur mon dépôt de dotfiles, et les contributions sont les bienvenues. Qu’il s’agisse de corriger un bug, d’ajouter une fonctionnalité ou simplement de suggérer une amélioration, votre retour m’intéresse.
Et vous ?
Et vous, comment organisez-vous vos dépôts Git en local ?
Partagez vos astuces et expériences dans les commentaires !