如何在维护多个代码仓库时设置GIT_DIR和GIT_WORK_TREE

13
这个 Stack Overflow 帖子类似,我有以下希望在 git 中保持的工作流程:
  1. 多个人在本地开发
  2. 提交一些东西
  3. 再次提交更多东西
  4. 推送到测试环境
  5. 在测试环境上测试新代码
  6. 推送到生产环境
我们的测试环境服务器提供了许多不同的站点。我想为每个站点/仓库在用户主目录下的不同文件夹中设置存储库。每个存储库都将有一个 post-receive 钩子(比如the Daniel Messier article),它会将更改检出到该站点/存储库的网站根目录中。
最后一个步骤第六步使我烦恼。
当我尝试运行任何 git 命令时,都会收到“致命错误:此操作必须在工作树中运行”的错误。无论我是从存储库 (/home/gituser/website1.git - 我认为这样不应该工作..) 还是从网站根目录 (/var/www/website1) 运行 'git status',都会遇到此错误。
但是,如果我指定了 GIT_DIR 和 GIT_WORK_TREE,则可以运行 git 命令。这两个命令都有效:
$ git --git-dir /home/gituser/website1.git --work-tree /var/www/website1 status
$ GIT_DIR=/home/gituser/website1.git GIT_WORK_TREE=/var/www/website1 git status 

所以我需要:

  1. 在每个命令中输入目录和工作树的替代方法
  2. 在持久环境变量中设置它们的替代方法,因为那只适用于网站1,而不是网站2、网站3等

我这样做对吗?如何为每个存储库获取git所需的目录信息?

4个回答

19

如果我理解正确,您为每个Web根目录都有一个不同的存储库。 如果是这种情况,您可以在存储库级别(在.git/config文件中)设置工作树:core.worktree。 如果repo配置为bare,则不起作用:

[core]
    bare = false
    worktree = /webroot/dir/for/this/repo

设置完成后,Git命令(例如git status)应该可以再次从存储库文件夹中工作,并且任何使用工作树的命令(git statusgit checkout等)都将使用core.worktree位置。(请注意,Git命令仍然无法从工作树位置工作,因为它不是一个存储库。)


1
谢谢。我已经尝试了config.worktree方法,但我没有注意到bare=true。 - doub1ejack

5

仅供建议。

实现一个名为“git”的脚本文件,该文件放置在用户路径之前的目录中,然后是/usr/bin下的git可执行文件。 git shell脚本只是/usr/bin/git上面的薄包装器(wrapper)。它首先检测从哪个目录调用了git,并尝试自动推断它正在处理的repo。也许通过在每个存储库的根目录中有一个“my.config”文件,脚本可以读取它。然后,脚本调用"/usr/bin/git --git-dir"并设置GIT_DIR和GIT_WORK_TREE变量,然后使用相同的命令行参数调用/usr/bin/git。


哦,我喜欢这个想法。不幸的是,我不擅长编写shell脚本..能帮一下吗? :) - doub1ejack

2

三种选项:

1)添加本地别名:

$ git config alias.root '!pwd'

2)添加全局别名($HOME/.gitconfig):

[alias]
 findroot = "!f () { [[ -d ".git" ]] && echo "Found git in [`pwd`]" && exit 0; cd .. && echo "IN `pwd`" && f;}; f"

3) 一个脚本,例如findgitroot.sh

#!/bin/sh
f () { [[ -d ".git" ]] && echo "Found git in [`pwd`]" && exit 0; cd .. && f;}
f

很抱歉在这里表现得像个白痴——选项1,是写在.bash_profile还是git配置文件中的片段?再次感谢您为这个问题提供了一些示例。 - Rustavore
1
选项1将用于git配置。然而,自那时以来,我发现了许多其他更好的选项: 3)git config alias.root'!pwd' (这将为您提供所需结果的“git root”命令) 4)git rev-parse --show-toplevel - FractalSpace
谢谢!所以对于第三点,你应该使用git root commit -am“Commit Msg”而不是git commit -am“Commit Msg” - Rustavore
不,您将使用此新别名仅查找根目录的位置,例如:'$ git root' 或 'cd git root 等。 - FractalSpace

1

您可以始终按上箭头获取所有信息,然后只需删除命令并替换为另一个命令。您不应该需要重新输入整个命令。

如果您已经发出了许多其他命令,并且不想通过历史记录进行“上箭头”太多,您可以按CTRL-R并开始键入“tree”或“work”。您应该能够找到其中一个运行的历史记录点。

否则,按照先前建议的脚本设置这些变量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接