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

Joe*_*nte 78 git git-submodules git-subrepo

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

Chr*_*ini 147

本文相对较好地介绍了这一点:

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

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

.gitone
.gittwo
Run Code Online (Sandbox Code Playgroud)

你可以像这样设置它们:

git init .
mv .git .gitone
git init .
mv .git .gittwo
Run Code Online (Sandbox Code Playgroud)

您可以添加一个文件并将其提交给只有这样的文件:

git --git-dir=.gitone add test.txt
git --git-dir=.gitone commit -m "Test"
Run Code Online (Sandbox Code Playgroud)

所以git的选项首先是命令,然后是命令,然后是git命令的选项.您可以轻松地为git命令添加别名,例如:

#!/bin/sh
alias gitone='git --git-dir=.gitone'
alias gittwo='git --git-dir=.gittwo'
Run Code Online (Sandbox Code Playgroud)

因此,您可以通过少量输入来提交一个或另一个,例如gitone commit -m "blah".

看起来更棘手的是忽略.由于.gitignore通常位于项目根目录中,因此您需要找到一种方法来切换它,而无需切换整个根目录.或者,您可以使用.git/info/exclude,但是您执行的所有忽略都不会被提交或推送 - 这可能会搞砸其他用户.使用任何一个repo的其他人可能会推送.gitignore,这可能会导致冲突.我不清楚解决这些问题的最佳方法.

如果您更喜欢TortoiseGit等GUI工具,那么您也会遇到一些挑战.您可以编写一个小脚本,暂时将.gitone或.gittwo重命名为.git,以便满足这些工具的假设.

  • 你可以配置repos使用他们自己的排除文件,你可以跟踪它们,即`gitone config core.excludesfile gitone.exclude`和`gitone add gitone.exclude`.我制作了一个扩展此解决方案的脚本:https://github.com/capr/multigit (8认同)
  • @JaredBroad 有趣 - 我建议你使用 Bash 别名,而不是 git 别名。就像 `alias gitone='git --git-dir=.gitone'` (2认同)
  • @JaredBroad我这样做了`git config --global alias.youralias'!git --git-dir ="/ d/MyProject/_git"'```git youralias status` :) (2认同)

Pau*_*aul 33

如果我了解您正在做什么,您可以在一个存储库中处理所有内容,为每台计算机使用单独的分支,以及包含公共主目录配置文件的分支.

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

然后在每台机器上,检查该机器的分支,它还包括公共配置文件.

  • 虽然子模块也可以工作,但我认为这对我来说是最好的方法。本地文件将遵循模板,当我对 MASTER 分支上的模板进行更改时,我可以将它们合并到计算机本地分支中,从而增量更新本地配置文件。谢谢您的帮助! (2认同)
  • 同时使用 Mercurial 和 Git。 (2认同)

Hat*_*es_ 14

看看git子模块.

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

  • 对于需要位于目录根目录的文件没有用处.只有这样的机会,是将符号链接的根填充到这些. (7认同)

小智 5

通过使用变量是可能的,GIT_DIR但是如果您不知道自己在做什么,则有很多警告。


Set*_*son 5

RichiH编写了一个名为vcsh的工具,它是一个使用git的虚假存储库管理dotfiles的工具,可以将多个工作目录放入$ HOME.与csh AFAIK无关.

但是,如果你确实有多个目录,那么git-submodules的替代方案(在最好的情况下这是一种痛苦,而这个例子的使用并不是最好的情况)是gitslave,它会让奴隶回购在在任何时候都是分支,并且不需要三步过程来对子公司仓库进行更改(签出到正确的分支,进行并提交更改,然后进入超级项目并提交新的子模块提交).


cod*_*ion 5

我的首选方法是在子目录中使用存储库,并使用递归符号链接:

git clone repo1
cd somerepo
git clone repo2
cd repo2
./build
Run Code Online (Sandbox Code Playgroud)

其中“ 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
Run Code Online (Sandbox Code Playgroud)

注意:不要使用“git add”。


Sau*_*abh 5

是的,一个目录中可以有两个 git 存储库。

我假设一个远程存储库位于 GitHub 中,另一个位于 GitLab 中。我还使用两个不同的 SSH 密钥来连接到这些远程存储库。

您可以在 GitHub / GitLab 之一中拥有两个远程存储库(并使用单个 SSH 密钥) - 不会有太大变化。

先决条件

  • 公共 SSH 密钥(id_ecdsa.pub/ id_rsa.pub/id_ed25519.pub等)存在于您的 GitHub 和 GitLab 配置文件中

  • SSH 私钥(id_ecdsa/ id_rsa/id_ed25519等)被添加并保留在操作系统的钥匙串中

  • SSH 配置文件具有为 GitHub 和 GitLab 指定的密钥:

    Host github.com
      Hostname github.com
      AddKeysToAgent yes
      UseKeychain yes
      IdentityFile ~/.ssh/id_ecdsa
    
    Host gitlab.com
      Hostname gitlab.com
      AddKeysToAgent yes
      UseKeychain yes
      IdentityFile ~/.ssh/id_rsa
    
    Run Code Online (Sandbox Code Playgroud)

以下是克里斯模拟工作流程的答案的细分

  • 在目录中初始化 git:

    git init

  • 将 git 连接到一个远程存储库(位于 GitHub)

    git remote add origin git@github.com:your-username/your-repo.git

  • 重命名.git为类似的名称.github

    mv .git .github

  • 再次初始化git

    git init

  • 将 git 连接到另一个远程存储库(位于 GitLab)

    git remote add origin git@gitlab.com:your-username/your-repo.git

  • 重命名.git为类似的名称.gitlab

    mv .git .gitlab

  • 验证当前目录是否连接到两个不同的远程存储库

    git --git-dir=.github remote -v

    git --git-dir=.gitlab remote -v

  • 拉取远程(GitHub 和 GitLab)存储库

    git --git-dir=.github pull origin main
    git --git-dir=.gitlab pull origin main
    
    Run Code Online (Sandbox Code Playgroud)
  • 将文件添加到两个存储库

    git --git-dir=.github add README.md
    git --git-dir=.gitlab add README.md
    
    Run Code Online (Sandbox Code Playgroud)
  • 写入提交消息

    git --git-dir=.github commit -m "operational overview"
    git --git-dir=.gitlab commit -m "operational overview"
    
    Run Code Online (Sandbox Code Playgroud)
  • 推送到远程

    git --git-dir=.github push -u origin main
    git --git-dir=.gitlab push -u origin main
    
    Run Code Online (Sandbox Code Playgroud)

我们在这里做的唯一额外的事情是使用--git-dir标志。

如果您打算经常这样做,您可以在 shell 配置文件中添加一个别名(例如.zprofilebashrc等):

export github="git --git-dir=.github"
export gitlab="git --git-dir=.gitlab"
Run Code Online (Sandbox Code Playgroud)

未来的操作如pull, push, add,可以像 - ,等一样commit执行。github pull origin maingitlab pull origin main