【问题标题】:Symbolic link to a hook in gitgit中钩子的符号链接
【发布时间】:2011-06-03 07:58:02
【问题描述】:

我编写了自己的自定义合并后钩子,现在我在我的主项目文件夹中添加了一个“钩子”目录(因为 git 不跟踪 .git/hooks 中的更改),在我读到的某个地方我可以创建一个符号从钩子链接到 .git/hooks 所以我不必每次有人更改文件时都将文件从一个文件夹复制到另一个文件夹,所以我尝试了:

ln -s -f hooks/post-merge .git/hooks/post-merge

但它似乎不起作用,任何想法为什么? “ln hooks/post-merge .git/hooks/post-merge” 工作正常,但我猜制作硬链接与 copyin 相同....

【问题讨论】:

  • 因为符号链接是相对于其位置进行解析的。 .git/hooks/ 中指向 hooks/post-merge 的符号链接被解析为不存在的 .git/hooks/hooks/post-merge。你想要ln -s -f ../../hooks/post-merge .git/hooks/post-merge。或者让您的生活更轻松:ln -s -f ../hooks .git/hooks。你的问题与git无关。
  • 如果我错了,请纠正我,但仍然必须为每个工作站设置一个符号链接。唯一可以保存的是手动复制它或编写另一个命令将跟踪的挂钩文件复制到.git/hooks

标签: linux git githooks


【解决方案1】:

你刚才用错了路径,应该是:

ln -s -f ../../hooks/post-merge .git/hooks/post-merge

【讨论】:

  • 我不明白为什么我需要上两个目录来链接位于我cd'd 文件夹中的资源。不应该只是ln -s ./hooks/ 吗?
  • 这个。当 git 评估符号链接时,它显然使用 .git/hooks 作为其工作目录,因此相对路径应该相对于该目录。如果您在创建符号链接之前先将cd 转换为.git/hooks,然后从那里找出相对路径,这将更加不言自明。
  • @Eliot 符号链接的创建和解析都不受工作目录的影响。无论你给ln 什么都将被存储为目标并相对于链接的位置进行解析。
  • @JoóÁdám 你是对的。所以这里的问题是原始命令指定了不正确的相对路径。尽管如此,在创建链接之前cd 进入.git/hooks 将帮助您编写命令,因为您可以自动完成到正确的路径。
  • 所有这些最终都为我工作。唯一的区别是我链接到我自己的prepare-commit-msg。问题是,如果我使用 nano 编辑提交消息,然后 Ctl+X 退出以中止,git 仍然会完成提交,而不是像我进行此更改之前那样中止。有没有办法让 nano 退出而不导致此提交完成?
【解决方案2】:

虽然您可以使用符号链接,但您也可以在 git 设置中更改项目的 hooks 文件夹:

git config core.hooksPath hooks/

默认情况下这是本地的,因此它不会破坏您其他项目的 git 挂钩。它适用于此存储库中的所有钩子,因此如果您有多个钩子,它特别有用。

如果您在 .git/hooks/ 中已有不想与您的团队共享的自定义挂钩,您可以将它们添加到 hooks/ 并添加 .gitignore 以便它们不会共享。

【讨论】:

【解决方案3】:

链接前更改目录

cd /path/to/project-repo/.git/hooks
ln -s -f ../../hooks/post-merge ./post-merge

【讨论】:

  • 更简单,在cd之后:ln -s -f ../../hooks/post-merge
【解决方案4】:

路径计算是相对于符号链接完成的。让我们用一个例子来理解,

ln -s path/to/file symlink/file

这里,文件的路径实际上应该是符号链接路径的相对路径。
系统实际计算文件路径为symlink/path/path/to/file
上面的命令要改写成

ln -s ../path/to/file symlink/path

文件夹结构为,

/代码
------ 符号链接/文件
------ 路径/到/文件

【讨论】:

    【解决方案5】:

    利用 Michael Cihar 的评论,这是我编写的一个 bash 脚本示例,用于简单地创建这些符号链接。该脚本位于项目根目录下的 git_hooks/ 目录中。我的 .git/ 文件夹也在同一目录级别。

    #!/usr/bin/env bash
    
    pwd=$(pwd);
    
    # Script is designed to be ran from git_hooks/ dir
    if [[ "$pwd" == *"git_hooks"* ]]; then
    
      files=$(ls | grep -v -e '.*\.');
    
       while read -r file; do
    
         ln -s ../../git_hooks/$file ../.git/hooks/
         echo "Linked $file -> ../.git/hooks/$file"
    
       done <<< "$files";
    
    else
    
      echo "";
      echo "ERROR: ";
      echo "You must be within the git_hooks/ dir to run this command";
      exit 1;
    
    fi
    

    我的脚本必须在实际的 git_hooks/ 目录中运行。如果您愿意,您可以修改它以使其行为不同。

    此脚本将对 git_hooks/ 目录中没有后缀的任何文件进行符号链接。我在这个目录中有一个 README.txt + 这个脚本(名为 symlink.sh)。所有实际的 git 钩子都被命名为 'pre-commit'、'pre-push' 等,因此它们将被符号链接。

    【讨论】:

      【解决方案6】:

      为什么不只是 cp ./hooks/* .git/hooks/

      这在 Mac OS 中对我有用

      【讨论】:

      • 因为I don't have to copy the file from one folder to the other every time someone changes
      猜你喜欢
      • 2012-02-02
      • 2015-07-31
      • 2011-08-20
      • 2014-05-03
      • 1970-01-01
      • 2017-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多