2013-04-26 104 views
3

我已经编写了一套Git插件供工作时在内部使用。它需要在全局模板目录中安装一些Git钩子,但是我在编程方式上找不到Git实际安装的目录。我在发现安装在我们的开发服务器:如何找到安装Git的目录?

  • /usr/share/git-core
  • /usr/local/share/git-core
  • /usr/local/git/share/git-core

某些服务器,由于以前的安装,已经安装在这些目录中的一种以上的Git 。我正在寻找一种方法来找出真实的模板目录,其中git init将复制模板文件。

git init代码的问题是在copy_templates()

if (!template_dir) 
    template_dir = getenv(TEMPLATE_DIR_ENVIRONMENT); 
if (!template_dir) 
    template_dir = init_db_template_dir; 
if (!template_dir) 
    template_dir = system_path(DEFAULT_GIT_TEMPLATE_DIR); 
if (!template_dir[0]) 
    return; 

然而,当它实际上将要复制的模板,这个代码仅运行,因此,似乎没有要找出一个方法是什么DEFAULT_GIT_TEMPLATE_DIR真的是事先。

我迄今为止最好的办法是(伪):

for each possible directory: 
    create a random_filename 
    create a file in the template directory with $random_filename 
    `git init` a new temporary repository 
    check for the existence of $random_filename in the new repo 
    if it exists, we found the real template directory 

这仍然具有建构的“可能的”目录列表如上的限制。

有没有更好的方法?

+0

疯狂。我实现了上述想法,但是在一台服务器上,root用户运行'/ usr/bin/git',其他人都在运行'/ usr/local/bin/git',所以它仍然有错误的目录。 – 2013-04-26 04:44:54

+1

我知道这是一个愚蠢的回答,但是在每个git安装中安装模板会有什么危害吗? – Alan 2013-04-26 04:47:02

+0

@Alan:嗯。当然没有。好计划。 – 2013-04-26 04:49:24

回答

1

这是在Python中实现的上述想法。这仍然有可能在$PATH(取决于谁在运行这个)中找到错误的git二进制文件,因此在我的特殊情况下,将模板简单地安装到我们可以找到的所有模板目录中会更好(如Alan在上面的评论)。

# This function attempts to find the global git-core directory from 
# which git will copy template files during 'git init'. This is done 
# empirically because git doesn't appear to offer a way to just ask 
# for this directory. See: 
# http://stackoverflow.com/questions/16228558/how-can-i-find-the-directory-where-git-was-installed 
def find_git_core(): 
    PossibleGitCoreDirs = [ 
     "/usr/share/git-core", 
     "/usr/git/share/git-core", 
     "/usr/local/share/git-core", 
     "/usr/local/git/share/git-core", 
    ] 
    possibles = [x for x in PossibleGitCoreDirs if os.path.exists(x)] 
    if not possibles: 
     return None 
    if len(possibles) == 1: 
     return possibles[0] 
    tmp_repo = tempfile.mkdtemp() 
    try: 
     for path in possibles: 
      tmp_file, tmp_name = tempfile.mkstemp(dir=os.path.join(path, "templates")) 
      os.close(tmp_file) 
      try: 
       subprocess.check_call(["git", "init"], env={"GIT_DIR": tmp_repo}) 
       if os.path.exists(os.path.join(tmp_repo, os.path.basename(tmp_name))): 
        return path 
      finally: 
       os.unlink(tmp_name) 
    finally: 
     shutil.rmtree(tmp_repo) 
    return None