Два репозитория git в одном каталоге?

86

Возможно ли иметь 2 репозитория git в одном каталоге? Я бы не подумал, но подумал, что спрошу. По сути, я хотел бы проверить файлы конфигурации моего домашнего каталога (например, .emacs), которые должны быть общими для всех машин, на которых я работаю, но иметь второй репозиторий для локальных файлов (например, .emacs.local), который содержит машинно-зависимые конфигурации. Единственный способ, который я могу придумать для этого, - иметь локальную конфигурацию в подкаталоге и игнорировать этот подкаталог из основного репозитория git. Есть другие идеи?

Джо Касадонте
источник
git subtreeвыполнит свою работу.
Сид Пао
Если вы не имеете дело с слишком большим количеством файлов, вы также можете создать символические ссылки / переходы.
thdoan

Ответы:

37

Если я понимаю, что вы делаете, вы можете обрабатывать все это в одном репозитории, используя отдельные ветки для каждой машины и ветку, содержащую ваши общие файлы конфигурации домашнего каталога.

Инициализируйте репо и зафиксируйте в нем общие файлы, возможно, переименовав ветвь MASTER в Common. Затем создайте отдельную ветку оттуда для каждой машины, с которой вы работаете, и зафиксируйте машинно-зависимые файлы в этой ветке. Каждый раз, когда вы меняете свои общие файлы, объединяйте общую ветвь с каждой из ветвей машины и отправляйте ее на другие машины (напишите для этого сценарий, если их много).

Затем на каждой машине проверьте ветку этой машины, которая также будет включать общие файлы конфигурации.

Павел
источник
Хотя подмодули также будут работать, я думаю, что это лучший подход для меня. Локальные файлы будут следовать шаблону, и по мере того, как я вношу изменения в шаблон в ветви MASTER, я могу объединять их в локальные ветви компьютера, постепенно обновляя локальные файлы конфигурации. Спасибо за помощь!
Джо Касадонте,
используйте и Mercurial, и Git.
Linc
172

Эта статья освещает это относительно хорошо:

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. фатальный: псевдоним pub изменяет переменные среды. Для этого в псевдониме можно использовать "! git". Где бы вы установили "! Git" в этом случае?
JaredBroad
1
@JaredBroad Интересно - я предлагал вам использовать псевдоним Bash, а не псевдоним git. Likealias 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
получилось
1
Если вы сделаете предположение, что .gitignoreфайлы обычно устанавливаются и забываются, вы можете сделать разные копии для каждого репо, а затем скопировать соответствующую версию в каталог как часть псевдонима. Это относится к другим файлам в корне, которые могут конфликтовать, например, README.mdи .gitattributes.
thdoan
15

Взгляните на подмодуль git .

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

Ненавидит_
источник
8
Не годится для файлов, которые должны находиться в корне вашего каталога. Единственный шанс там, это заполнить корень символическими ссылками на них.
WhyNotHugo
6

RichiH написал инструмент под названием vcsh - инструмент для управления точечными файлами с использованием поддельных голых репозиториев git для помещения более одного рабочего каталога в $ HOME. Ничего общего с csh AFAIK.

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

Сет Робертсон
источник
6

Это возможно с использованием переменной, GIT_DIRно есть много предостережений, если вы не знаете, что делаете.

церво
источник
4

Да, возможно, вам нужны подмодули. Другой вариант - разместить вашу рабочую копию в подкаталоге, а затем указать символические ссылки из вашего домашнего каталога на интересующие файлы.

Пэт Нотц
источник
3

мой предпочтительный метод - использовать репо в подкаталоге и использовать рекурсивные символические ссылки:

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

где файл ' repo / 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 / FolderA
  2. Repo1 / FolderB

А также:

  1. Repo2 / FolderC

Вы можете сделать символическую ссылку на папки 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 для обработки случаев, когда вы хотите объединить несколько репозиториев в одну папку. Преимущество библиотеки в том, что она позволяет отслеживать репозитории и конфликты файлов. вы можете найти его на гитхабе . Есть также 2 репозитория примеров, чтобы опробовать его.

user1810087
источник