Deux référentiels git dans un répertoire?


86

Est-il possible d'avoir 2 référentiels git dans un répertoire? Je ne pense pas, mais j'ai pensé que je demanderais. Fondamentalement, j'aimerais archiver les fichiers de configuration de mon répertoire personnel (par exemple .emacs) qui devraient être communs à toutes les machines sur lesquelles je travaille, mais avoir un deuxième référentiel pour les fichiers locaux (par exemple .emacs.local), qui contient configurations spécifiques à la machine. La seule façon dont je peux penser pour faire cela est d'avoir la configuration locale dans un sous-répertoire et d'ignorer ce sous-répertoire du référentiel git principal. D'autres idées?


git subtreefera le travail.
Syd Pao

Si vous ne traitez pas trop de fichiers, vous pouvez également créer des liens symboliques / jonctions.
thdoan

Réponses:


37

Si je comprends ce que vous faites, vous pouvez tout gérer dans un seul référentiel, en utilisant des branches séparées pour chaque machine, et une branche contenant vos fichiers de configuration de répertoire de base communs.

Initialisez le référentiel et livrez-y les fichiers communs, en renommant peut-être la branche MASTER en Common. Créez ensuite une branche distincte à partir de là pour chaque machine avec laquelle vous travaillez et validez les fichiers spécifiques à la machine dans cette branche. Chaque fois que vous modifiez vos fichiers communs, fusionnez la branche commune dans chacune des branches de la machine et poussez vers vos autres machines (écrivez un script pour cela s'il y en a beaucoup).

Ensuite, sur chaque machine, vérifiez la branche de cette machine, qui comprendra également les fichiers de configuration courants.


Bien que les sous-modules fonctionnent également, je pense que c'est la meilleure approche pour moi. Les fichiers locaux suivront un modèle, et au fur et à mesure que j'apporte des modifications au modèle sur la branche MASTER, je peux les fusionner dans les branches locales de la machine, en mettant à jour de manière incrémentielle les fichiers de configuration locaux. Merci pour l'aide!
Joe Casadonte le

utilisez Mercurial et Git à la fois.
Linc

171

Cet article couvre cela relativement bien:

https://github.com/rrrene/gitscm-next/blob/master/app/views/blog/progit/2010-04-11-environment.markdown

Fondamentalement, si vous travaillez à partir de la ligne de commande, c'est plus simple que vous ne le pensez. Supposons que vous vouliez 2 dépôts git:

.gitone
.gittwo

Vous pouvez les configurer comme ceci:

git init .
mv .git .gitone
git init .
mv .git .gittwo

Vous pouvez ajouter un fichier et le valider dans un seul comme ceci:

git --git-dir=.gitone add test.txt
git --git-dir=.gitone commit -m "Test"

Ainsi, les options pour git viennent en premier, puis la commande, puis les options de la commande git. Vous pouvez facilement aliaser une commande git comme:

#!/bin/sh
alias gitone='git --git-dir=.gitone'
alias gittwo='git --git-dir=.gittwo'

Vous pouvez donc vous engager dans l'un ou l'autre avec un peu moins de frappe, comme gitone commit -m "blah".

Ce qui semble devenir plus délicat est ignoré. Étant donné que .gitignore se trouve normalement à la racine du projet, vous devez également trouver un moyen de changer cela sans changer la racine entière. Ou, vous pouvez utiliser .git / info / exclude, mais tous les ignorés que vous effectuez alors ne seront pas validés ou poussés - ce qui pourrait gâcher d'autres utilisateurs. D'autres utilisant l'un ou l'autre des référentiels peuvent pousser un .gitignore, ce qui peut provoquer des conflits. La meilleure façon de résoudre ces problèmes n'est pas claire pour moi.

Si vous préférez les outils GUI comme TortoiseGit, vous aurez également des défis. Vous pouvez écrire un petit script qui renomme temporairement .gitone ou .gittwo en .git afin que les hypothèses de ces outils soient satisfaites.


1
Le définir comme alias génère cette erreur: $ git config --global alias.pub '--git-dir = ~ / Server / www / .gitpublic' $ git pub add. fatal: l'alias 'pub' change les variables d'environnement Vous pouvez utiliser '! git' dans l'alias pour ce faire. Où définiriez-vous le "! Git" dans ce cas?
JaredBroad

1
@JaredBroad Intéressant - Je vous suggérais d'utiliser un alias Bash, pas un alias git. J'aimealias gitone='git --git-dir=.gitone'
Chris Moschini

10
Vous pouvez configurer les dépôts pour utiliser leurs propres fichiers d'exclusion et vous pouvez les suivre, c'est gitone config core.excludesfile gitone.exclude-à- dire et gitone add gitone.exclude. J'ai fait un script qui développe cette solution: github.com/capr/multigit

2
@JaredBroad je l'ai fait comme ça git config --global alias.youralias '!git --git-dir="/d/MyProject/_git"'alors git youralias status:)
starikovs

1
Si vous supposez que les .gitignorefichiers sont généralement définis et oubliés, vous pouvez faire des copies différentes pour chaque dépôt, puis copier la version appropriée dans le répertoire dans le cadre de l'alias. Cela s'applique à d'autres fichiers à la racine qui pourraient entrer en conflit, tels que README.mdet .gitattributes.
thdoan

15

Jetez un œil au sous-module git .

Les sous-modules permettent aux référentiels étrangers d'être intégrés dans un sous-répertoire dédié de l'arborescence source, toujours pointé vers un commit particulier.


8
Pas bon pour les fichiers qui doivent être à la racine de votre répertoire. La seule chance là-bas, est de remplir la racine des liens symboliques vers ceux-ci.
WhyNotHugo

6

RichiH a écrit un outil appelé vcsh qui est un outil pour gérer les fichiers dotfiles en utilisant les faux dépôts nus de git pour mettre plus d'un répertoire de travail dans $ HOME. Rien à voir avec csh AFAIK.

Cependant, si vous aviez plusieurs répertoires, une alternative aux git-submodules (qui sont pénibles dans le meilleur des cas et cet exemple d'utilisation n'est pas la meilleure des circonstances) est gitslave qui laisse les dépôts esclaves vérifiés sur la pointe d'un branchez à tout moment et ne nécessite pas le processus en trois étapes pour effectuer une modification dans le dépôt subsidiaire (extraire la bonne branche, effectuer et valider la modification, puis aller dans le superprojet et valider le nouveau commit de sous-module).


6

C'est possible en utilisant la variable GIT_DIRmais comporte de nombreuses mises en garde si vous ne savez pas ce que vous faites.


4

Ouais, les sous-modules sont probablement ce que vous voulez. Une autre option serait d'avoir votre copie de travail dans un sous-répertoire, puis de pointer des liens symboliques de votre répertoire personnel vers les fichiers d'intérêt.


3

ma méthode préférée utilise un dépôt dans un sous-répertoire et utilise des liens symboliques récursifs:

git clone repo1
cd somerepo
git clone repo2
cd repo2
./build

où le fichier ' repo / build ' ressemble à:

#!/bin/bash 
SELF_PATH="$(dirname "$(readlink -f "$0")" )"  # get current dir 
cd .. && git stash && git clean -f -d ''       # remove previous symlinks
cp -sR "$SELF_PATH"/* ../.                     # create recursive symlinks in root

attention : n'utilisez pas 'git add.'


0

L'autre option consiste à les placer sur des dossiers séparés et à créer des liens symboliques durs d'un dossier à l'autre.

Par exemple, s'il y a les référentiels:

  1. Repo1 / DossierA
  2. Repo1 / DossierB

Et:

  1. Repo2 / DossierC

Vous pouvez créer un lien symbolique entre les dossiers FolderAet FolderBle Repo1 dans le Repo2. Pour Windows, la commande à exécuter sur le Repo1 serait:

User@Repo1$ mklink /J FullPath/Repo2/FolderA FullPath/Repo1/FolderA
User@Repo1$ mklink /J FullPath/Repo2/FolderB FullPath/Repo1/FolderB
User@Repo1$ printf "/FolderA/*\n/FolderB/*\n" >> .gitignore

Pour les fichiers sur les référentiels principaux, vous devez créer un lien symbolique pour chacun d'eux, en les ajoutant également au référentiel .gitignorepour éviter le bruit, sauf si vous le souhaitez.


0

Avertissement: ce n'est pas de la publicité. Je suis le développeur de la bibliothèque fournie.

J'ai créé une extension git pour gérer les cas où vous souhaitez mélanger plusieurs référentiels dans un seul dossier. L'avantage de la lib est de garder une trace des référentiels et des conflits de fichiers. vous pouvez le trouver sur github . Il existe également 2 exemples de référentiels pour l'essayer.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.