Два сховища git в одному каталозі?


86

Чи можна мати 2 сховища git в одному каталозі? Думаю, ні, але подумав, що запитаю. В основному, я хотів би перевірити конфігураційні файли домашнього каталогу (наприклад .emacs), які повинні бути загальними для всіх машин, на яких я працюю, але мати друге сховище для локальних файлів (наприклад .emacs.local), яке містить конфігурації, специфічні для машини. Єдиний спосіб, як я можу це придумати, - це мати локальний конфігуратор у підкаталозі та ігнорувати цей підкаталог із головного сховища git. Будь-які інші ідеї?


git subtreeвиконає роботу.
Syd Pao,

Якщо ви не маєте справу з занадто великою кількістю файлів, ви також можете створити символьні посилання / переходи.
thdoan

Відповіді:


37

Якщо я розумію, що ви робите, ви можете обробити все це в одному сховищі, використовуючи окремі гілки для кожної машини та гілку, що містить ваші загальні файли конфігурації домашнього каталогу.

Ініціалізуйте репо та зафіксуйте для нього загальні файли, можливо, перейменувавши гілку MASTER як Загальну. Потім створіть окрему гілку звідти для кожної машини, з якою ви працюєте, і вкладіть у цю гілку файли, що відповідають машині. Кожного разу, коли ви змінюєте загальні файли, об’єднуйте загальну гілку в кожну з гілок машин і переходьте на інші машини (напишіть сценарій для цього, якщо їх багато).

Потім на кожній машині перевірте гілку цієї машини, яка також включатиме загальні конфігураційні файли.


Хоча підмодулі також будуть працювати, я думаю, що це найкращий підхід для мене. Локальні файли будуть слідувати за шаблоном, і, коли я вношу зміни в шаблон у гілці MASTER, я можу об'єднати їх у локальні гілки машини, поступово оновлюючи локальні файли конфігурації. Дякую за допомогу!
Джо Касадонте

використовуйте Mercurial та Git.
Лінк

171

Ця стаття висвітлює це відносно добре:

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

В основному, якщо ви працюєте з командного рядка, це простіше, ніж можна здогадатися. Припустимо, ви хочете 2 репозиторії git:

.gitone
.gittwo

Ви можете налаштувати їх так:

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

Ви можете додати файл і зафіксувати його лише для одного:

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

Отже, параметри git стоять спочатку, потім команда, потім параметри команди git. Ви можете легко отримати псевдонім команди git, наприклад:

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

Тож ви можете взяти на себе зобов’язання перед тим чи іншим, дещо менше набираючи текст, наприклад gitone commit -m "blah".

Те, що видається складнішим, це ігнорування. Оскільки .gitignore зазвичай знаходиться в корені проекту, вам потрібно буде знайти спосіб переключити це, не перемикаючи весь кореневий каталог. Або ви можете використовувати .git / info / exclude, але всі проігноровані вами ігнорування не будуть зафіксовані або виштовхнуті - що може зіпсувати інших користувачів. Інші користувачі будь-якого репо можуть натиснути .gitignore, що може спричинити конфлікти. Мені незрозуміло, як найкраще вирішити ці проблеми.

Якщо ви віддаєте перевагу інструментам графічного інтерфейсу, таким як TortoiseGit, у вас також виникнуть певні проблеми. Ви можете написати невеликий скрипт, який тимчасово перейменовує .gitone або .gittwo на .git, щоб виконувались припущення цих інструментів.


1
Встановивши його як псевдонім, виникає така помилка: $ git config --global alias.pub '--git-dir = ~ / Server / www / .gitpublic' $ git pub add. fatal: псевдонім 'pub' змінює змінні середовища. Для цього ви можете використовувати '! git' в псевдонімі. Де б ви встановили "! Git" у цьому випадку?
JaredBroad

1
@JaredBroad Цікаво - я пропонував використовувати псевдонім Bash, а не псевдонім git. Подобаєтьсяalias gitone='git --git-dir=.gitone'
Кріс Москіні

10
Ви можете налаштувати репозиторії на використання власних файлів виключення, і ви можете відстежувати їх, тобто gitone config core.excludesfile gitone.excludeі gitone add gitone.exclude. Я створив сценарій, який розширює це рішення: github.com/capr/multigit

2
@JaredBroad Я зробив це git config --global alias.youralias '!git --git-dir="/d/MyProject/_git"'тоді так git youralias status:)
starikovs

1
Якщо ви припускаєте, що .gitignoreфайли зазвичай встановлюються і забуваються, тоді ви можете зробити різні копії для кожного репозиторію, а потім скопіювати відповідну версію в каталог як частину псевдоніма. Це стосується інших кореневих файлів, які можуть конфліктувати, таких як README.mdі .gitattributes.
thdoan

15

Погляньте на підмодуль git .

Підмодулі дозволяють вбудовувати іноземні сховища у виділений підкаталог дерева джерела, завжди вказуючи на певний коміт.


8
Не годиться для файлів, які повинні бути в кореневій директорії вашого каталогу. Єдиний шанс - це заповнити корінь символьних посилань до них.
WhyNotHugo

6

RichiH написав інструмент під назвою vcsh, який є інструментом для управління файлами точок за допомогою підроблених оголених репозиторіїв git для розміщення більш ніж одного робочого каталогу в $ HOME. Нічого спільного з csh AFAIK.

Однак, якщо у вас було кілька каталогів, альтернативою git-підмодулям (які є болем в найкращих обставинах, а використання цього прикладу не найкраще) є gitslave, який залишає підпорядковані репозиторії на кінчику філія в будь-який час і не вимагає триступеневого процесу, щоб вносити зміни в допоміжний репо (перевірка на правильну гілку, внесення та фіксація змін, а потім перехід до суперпроекту та комітування нового підмодуля коміту).


6

Це можливо за допомогою змінної, GIT_DIRале має багато застережень, якщо ви не знаєте, що робите.


4

Так, підмодулі - це, мабуть, те, що ви хочете. Іншим варіантом було б розміщення робочої копії у підкаталозі, а потім вказувати символічні посилання з домашнього каталогу на цікаві файли.


3

моїм кращим методом є використання репо в піддиректорії та використання рекурсивних символічних посилань:

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

де файл-репо / побудова виглядає так:

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

застереження : не використовуйте "git add."


0

Інший варіант - розмістити їх в окремих папках і створити символічні жорсткі посилання з однієї папки в іншу.

Наприклад, якщо є сховища:

  1. Repo1 / ПапкаA
  2. Repo1 / ПапкаB

І:

  1. Repo2 / ПапкаC

Ви можете символічно зв’язати папки FolderAта FolderBз Repo1 на Repo2. Для Windows команда для запуску на Repo1 буде такою:

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

Для файлів у основних сховищах вам знадобиться символічно зв’язати кожен із них, а також додати їх до сховища, .gitignoreщоб уникнути шуму, якщо ви цього не хочете.


0

Застереження: Це не реклама. Я розробник наданої бібліотеки.

Я створив розширення git для обробки випадків, коли ви хочете змішати кілька сховищ в одну папку. Перевагою lib є відстеження сховищ та конфліктів файлів. Ви можете знайти його на github . Існує також 2 приклади сховищ, щоб спробувати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.