一个目录中有两个git存储库?


86

一个目录中可以有2个git存储库吗?我认为不会,但我想问。基本上,我想检入我的主目录配置文件(例如.emacs),该文件在我使用的所有计算机上应该是公用的,但还有第二个本地文件存储库(例如.emacs.local),其中包含机器特定的配置。我能想到的唯一方法是将本地配置放在子目录中,并从主git存储库中忽略该子目录。还有其他想法吗?


git subtree将完成工作。
Syd Pao

如果您处理的文件不太多,则也可以创建符号链接/连接。
thdoan

Answers:


37

如果我了解您在做什么,则可以在一个存储库中全部处理,对每台计算机使用单独的分支,以及一个包含公用主目录配置文件的分支。

初始化存储库并将公共文件提交给它,也许将MASTER分支重命名为Common。然后从那里为您使用的每台计算机创建一个单独的分支,并将特定于计算机的文件提交到该分支。每次更改公用文件时,请将公用分支合并到每个计算机分支中,然后推送到其他计算机(如果有许多脚本,请编写脚本)。

然后在每台计算机上,检出该计算机的分支,其中还将包括公共配置文件。


虽然子模块也可以工作,但我认为这对我来说是最好的方法。本地文件将遵循一个模板,当我在MASTER分支上对该模板进行更改时,我可以将它们合并到计算机本地分支中,以增量方式更新本地配置文件。谢谢您的帮助!
乔·卡萨登特

同时使用Mercurial和Git。
林克

172

本文涵盖了相对较好的内容:

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

基本上,如果您使用命令行工作,这比您想像的要简单。假设您想要2个git repos:

.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之类的GUI工具,您还将面临一些挑战。您可以编写一个小脚本,将.gitone或.gittwo临时重命名为.git,以便满足这些工具的假设。


1
将其设置为别名会引发此错误:$ git config --global alias.pub'--git-dir =〜/ Server / www / .gitpublic'$ git pub add。致命:别名“ pub”更改环境变量您可以在别名中使用“!git”来执行此操作。在这种情况下,您将在哪里设置“!git”?
JaredBroad14年

1
@JaredBroad有趣-我建议您使用Bash别名,而不是git别名。喜欢alias gitone='git --git-dir=.gitone'
克里斯·莫斯基尼

10
您可以将存储库配置为使用其自己的排除文件,并且可以跟踪这些文件,即gitone config core.excludesfile gitone.excludegitone add gitone.exclude。我制作了一个扩展此解决方案的脚本:github.com/capr/multigit

2
@JaredBroadgit config --global alias.youralias '!git --git-dir="/d/MyProject/_git"'然后我是这样的git youralias status:)
starikovs 16/09/19

1
如果假设.gitignore文件通常是设置后遗忘的,则可以为每个存储库创建不同的副本,然后将相关版本作为别名的一部分复制到目录中。这适用于根目录中可能冲突的其他文件,例如README.md.gitattributes
thdoan

15

看看git子模块

子模块允许将外部存储库嵌入到源树的专用子目录中,该子目录始终指向特定的提交。


8
对于需要放在目录根目录中的文件没有好处。唯一的机会就是填补这些链接的根源。
WhyNotHugo 2010年

6

RichiH编写了一个名为vcsh的工具,该工具使用git的伪裸仓库来管理点文件,从而将多个工作目录放入$ HOME。与csh AFAIK无关。

但是,如果您确实有多个目录,则可以使用gitslave替代git-submodules(这在最佳情况下是很痛苦的,此示例用法不是最佳情况),这会使从站存储库被检出。始终保持分支状态,不需要三步过程即可在子仓库中进行更改(签出到正确的分支上,进行并提交更改,然后进入超级项目并提交新的子模块提交)。


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. 回购1 /文件夹A
  2. 回购1 /文件夹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个示例存储库可供试用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.