Due repository git in una directory?


89

È possibile avere 2 repository git in una directory? Pensavo di no, ma ho pensato di chiedere. Fondamentalmente, vorrei controllare i file di configurazione della mia directory home (ad es. .Emacs) che dovrebbero essere comuni a tutte le macchine su cui lavoro, ma ho un secondo repository per i file locali (ad es. .Emacs.local), che contiene configurazioni specifiche della macchina. L'unico modo in cui posso pensare di farlo è avere la configurazione locale in una sottodirectory e ignorare quella sottodirectory dal repository git principale. Altre idee?


git subtreeporterà a termine il lavoro.
Syd Pao

Se non hai a che fare con troppi file, potresti anche creare collegamenti simbolici / giunzioni.
thdoan

Risposte:


38

Se capisco cosa stai facendo, puoi gestirlo tutto in un repository, utilizzando rami separati per ogni macchina e un ramo contenente i tuoi file di configurazione della directory home comune.

Inizializza il repository e inviaci i file comuni, magari rinominando il ramo MASTER come Common. Quindi crea un ramo separato da lì per ogni macchina con cui lavori e salva i file specifici della macchina in quel ramo. Ogni volta che modifichi i tuoi file comuni, unisci il ramo comune in ciascuno dei rami della macchina e invialo alle altre macchine (scrivi uno script per quello se ce ne sono molti).

Quindi su ogni macchina, controlla il ramo di quella macchina, che includerà anche i file di configurazione comuni.


1
Sebbene funzionino anche i sottomoduli, penso che questo sia l'approccio migliore per me. I file locali seguiranno un modello e, poiché apporto modifiche al modello sul ramo MASTER, posso unirli nei rami locali della macchina, aggiornando in modo incrementale i file di configurazione locali. Grazie per l'aiuto!
Joe Casadonte

usa Mercurial e Git entrambi.
Linc

178

Questo articolo copre questo aspetto relativamente bene:

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

Fondamentalmente, se stai lavorando dalla riga di comando, è più semplice di quanto potresti immaginare. Supponiamo che tu voglia 2 repository git:

.gitone
.gittwo

Potresti impostarli in questo modo:

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

Puoi aggiungere un file e inviarlo a uno solo in questo modo:

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

Quindi vengono prima le opzioni per git, poi il comando, quindi le opzioni del comando git. Potresti facilmente alias un comando git come:

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

Quindi puoi impegnarti per l'uno o l'altro digitando un po 'meno, come gitone commit -m "blah".

Ciò che sembra essere più complicato viene ignorato. Poiché .gitignore normalmente si trova nella root del progetto, dovresti trovare un modo per cambiare anche questo senza cambiare l'intera root. Oppure, potresti usare .git / info / exclude, ma tutte le ignorazioni che esegui non verranno salvate o spinte, il che potrebbe rovinare altri utenti. Altri che utilizzano uno dei repository potrebbero inviare un file .gitignore, che potrebbe causare conflitti. Non mi è chiaro il modo migliore per risolvere questi problemi.

Se preferisci strumenti GUI come TortoiseGit avresti anche alcune sfide. Potresti scrivere un piccolo script che rinomina temporaneamente .gitone o .gittwo in .git in modo che i presupposti di questi strumenti siano soddisfatti.


1
L'impostazione come alias genera questo errore: $ git config --global alias.pub '--git-dir = ~ / Server / www / .gitpublic' $ git pub add. fatal: l'alias 'pub' cambia le variabili d'ambiente Puoi usare '! git' nell'alias per farlo. Dove imposteresti "! Git" in questo caso?
JaredBroad

1
@ JaredBroad Interessante - Ti stavo suggerendo di utilizzare un alias Bash, non un alias git. Mi piacealias gitone='git --git-dir=.gitone'
Chris Moschini

10
È possibile configurare i repository in modo da utilizzare i propri file di esclusione e tenere traccia di quelli, ad esempio gitone config core.excludesfile gitone.excludee gitone add gitone.exclude. Ho creato uno script che si espande su questa soluzione: github.com/capr/multigit

2
@JaredBroad l'ho fatto così git config --global alias.youralias '!git --git-dir="/d/MyProject/_git"'allora git youralias status:)
starikovs

1
Se si presume che i .gitignorefile siano generalmente impostati e dimenticati, è possibile creare copie diverse per ciascun repository, quindi copiare la versione pertinente nella directory come parte dell'alias. Questo vale per altri file nella radice che potrebbero entrare in conflitto, come README.mde .gitattributes.
giovedì

15

Dai un'occhiata al sottomodulo git .

I sottomoduli consentono di incorporare repository esterni in una sottodirectory dedicata dell'albero dei sorgenti, sempre puntata su un particolare commit.


8
Non va bene per i file che devono essere nella radice della tua directory. L'unica possibilità è riempire la radice dei collegamenti simbolici a questi.
WhyNotHugo

6

RichiH ha scritto uno strumento chiamato vcsh che è uno strumento per gestire i dotfile utilizzando i falsi repository di git per mettere più di una directory di lavoro in $ HOME. Niente a che vedere con csh AFAIK.

Tuttavia, se si dispone di più directory, un'alternativa ai sottomoduli git (che sono un problema nelle migliori circostanze e questo utilizzo di esempio non è il migliore delle circostanze) è gitslave che lascia i repository slave controllati sulla punta di un branch in ogni momento e non richiede il processo in tre fasi per apportare una modifica nel repository secondario (checkout sul ramo corretto, fare e eseguire il commit della modifica, quindi accedere al superprogetto ed eseguire il commit del nuovo sottomodulo commit).


6

È possibile usando la variabile GIT_DIRma ha molti avvertimenti se non sai cosa stai facendo.


4

Sì, i sottomoduli sono probabilmente quello che vuoi. Un'altra opzione potrebbe essere quella di avere la tua copia di lavoro in una sottodirectory e quindi puntare i collegamenti simbolici dalla tua home directory ai file di interesse.


3

il mio metodo preferito è utilizzare un repo in una sottodirectory e utilizzare collegamenti simbolici ricorsivi:

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

dove il file ' repo / build ' ha il seguente aspetto:

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

attenzione : non utilizzare "git add."


0

L'altra opzione è che si trovano in cartelle separate e creano collegamenti fisici simbolici da una cartella all'altra.

Ad esempio, se sono presenti i repository:

  1. Repo1 / FolderA
  2. Repo1 / FolderB

E:

  1. Repo2 / FolderC

Puoi collegare simbolicamente le cartelle FolderAe FolderBdal Repo1 al Repo2. Per Windows il comando da eseguire sul Repo1 sarebbe:

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

Per i file sui repository principali è necessario collegarli simbolicamente a ciascuno di essi, aggiungendoli anche al repository .gitignoreper evitare rumore, a meno che non lo si desideri.


0

Disclaimer: questa non è pubblicità. Sono lo sviluppatore della libreria fornita.

Ho creato un'estensione git per gestire i casi in cui desideri combinare più repository in una cartella. Il vantaggio della lib è tenere traccia dei repository e dei conflitti di file. lo puoi trovare su GitHub . Ci sono anche 2 repository di esempio per provarlo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.