如果'/'是版本库的根目录,为什么git会中断?
我们希望使用git来维护系统配置。 因为配置数据有时候存在于/ etc之外,所以我们在我们的系统上开始这样做:
# cd /
# git init
# git add etc
# git add some/other/path
# git commit -m 'initial import'
等等。 这起作用,直到一点。 只要你的cwd =='/',git的行为正常。 但是,如果您尝试从例如子目录中运行git:
cd /etc
git status
你会得到垃圾。 在我们的案例中,数千行“已删除:”清单中仍然存在的文件清单。 这种行为似乎是独占在/中运行git; 在其他地方做同样的事情也很好。
我可以“修复”这样的行为:
GIT_WORK_TREE=/ git status
嘿,一切都按照莱纳斯的意图工作......但这是一种痛苦。 我不想单方面将其设置在环境中(因为这会与在其他存储库中使用git相冲突),并且我想避免包装脚本。 我有其他选择吗?
这是一个完全的猜测,你可以用来进一步调查,但我怀疑git的“找到.git
目录”行为正在与/
是它自己的父目录的事实相互作用。 也许“停在根”逻辑有一个fencepost类型的错误。
在存储库上设置core.worktree
选项可以很好地处理这个问题:
git config core.worktree /
这比在环境中设置GIT_WORK_TREE好得多。 好极了!
这将在Git 2.4.1+(Q2 2015)中修复。
见Jeff King( peff
)提交的84ccad8,并合并到7502b23中。
init
:不设置core.worktree
初始化时/.git
如果你使用“ git init /
”在根目录下创建一个git仓库,我们会错误地写一个core.worktree
条目。
这并不是错的, core.worktree
在我们不需要的时候设置core.worktree
是可以的。 但是如果以后将.git
目录移动到另一个路径(通常会移动相对工作树,但是如果存在明确的工作树集则会被挫败),这是不必要的令人惊讶。
问题是我们通过查看我们是否可以通过将“/.git”连接到工作树来创建git_dir来检查core.worktree是否必要 。
这会导致“ //.git
”在这个例子中,但我们实际上有“ /.git
”(没有双斜杠)。
(这就是为什么core.worktree
在这里被错误地设置,当git init
在根文件夹/
完成时)
我们可以通过特殊的方式修复根目录。 我也将逻辑分成了它自己的函数,使得条件更具可读性(并且使用了skip_prefix,我认为它会让事情变得更加明显)。
没有测试,因为我们需要能够写入“/”才能这样做。
我确实手动确认:
sudo git init /
cd /
git rev-parse --show-toplevel
git config core.worktree
仍然找到正确的顶层(如“ /
”),并且没有设置任何core.worktree变量 。
上一篇: Why does git break if '/' is the root of the repository?
下一篇: How to get git and tfs to work side by side in MSVS2013?