Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Sed动态注入分支名称的Git预提交_Git_Bash_Sed_Osx Elcapitan_Pre Commit Hook - Fatal编程技术网

使用Sed动态注入分支名称的Git预提交

使用Sed动态注入分支名称的Git预提交,git,bash,sed,osx-elcapitan,pre-commit-hook,Git,Bash,Sed,Osx Elcapitan,Pre Commit Hook,我正在使用一个gitpre-commit钩子来: 获取当前分支名称 将分支名称插入生成状态映像代码中 在README.md文件中搜索字符串/模式,然后将该字符串/模式用作要插入动态生成的构建状态映像的位置的标记 注意,我使用的是OSX El Capitan v10.11.5,为了执行这段代码,我必须在预提交脚本上运行chmod+x.git/hooks/pre-commit 以下是我正在使用的代码: #!/bin/bash function git_branch { git rev-pa

我正在使用一个
git
pre-commit钩子来:

  • 获取当前分支名称
  • 将分支名称插入生成状态映像代码中
  • 在README.md文件中搜索字符串/模式,然后将该字符串/模式用作要插入动态生成的构建状态映像的位置的标记
  • 注意,我使用的是OSX El Capitan v10.11.5,为了执行这段代码,我必须在预提交脚本上运行
    chmod+x.git/hooks/pre-commit

    以下是我正在使用的代码:

    #!/bin/bash
    
    function git_branch {
        git rev-parse --abbrev-ref HEAD
    }
    
    branch=$(git_branch)
    id="{{CODESHIP_CODE}}"
    
    codeship_build_status="[ ![Codeship Status for ExampleUser/exampleRepo](https://codeship.com/projects/a99d9999-9b9f-9999-99aa-999k9b9b0999/status?branch=$branch)](https://codeship.com/projects/999999)"
    
    sed -i -e "s%{{CODESHIP_CODE}}%$codeship_build_status%g" README.md
    
    到目前为止,代码正在运行。我的意思是:

  • 正确搜索README.md文件
  • 删除字符串/模式标记
  • codeship\u build\u status
    变量替换字符串/模式标记
  • 问题在于,这似乎并没有在git提交之前实际更改README.md文件,而是生成另一个名为README.md-e的文件

    当我转到git push并在repo中查看代码时,README.md文件尚未更新,而是仍然包含字符串/模式标记,而不是更新的构建状态图像。具有讽刺意味的是,README.md文件确实在我的本地开发分支中发生了更改


    有没有办法解决这个问题或者是什么原因造成的?

    问题是
    sed-i
    。这将告诉
    sed
    创建一个新文件,并使用下一个参数(在您的示例中,
    -e
    )作为后缀,以新名称保留旧文件

    对于Mac版的
    sed
    ,必须为
    -i
    提供一个限定参数。要使其与gnu/linux版本使用这些命令行选项做的事情相同,您需要提供一个空白选项,如下所示:

    sed -i '' -e "s%{{CODESHIP_CODE}}%$codeship_build_status%g" README.md
    

    ++; 这确实是问题所在;狡辩:
    -i
    不会创建新文件;相反,如果指定了非空选项参数,它将重命名原始文件(否则它只删除原始文件);正是sed的输出创建了一个新文件,并最终重命名为原始名称。(旁注:正是这种创建临时文件然后重命名以替换原始文件的方法可能会导致问题,最明显的是破坏符号链接。)最终的结果是,使用
    -i.bak
    ,您将得到两个文件:创建一个文件。使用
    -i'
    ,您将得到一个文件。没有关于最终结果的参数。我的观点是,重命名原始文件并替换为新的临时文件可能很重要。然后重命名为原始文件名的文件。使用这种
    sed
    使用的方法,您可能会丢失原始文件的以下属性:最明显的是,它是否是符号链接,以及它的创建时间戳(在支持它的文件系统上(例如,OSX))、扩展文件系统属性(在支持它的文件系统上(例如,OSX))。(续)
    -i.bak
    后跟
    rm file.bak
    是否在这两种情况下都起作用?@Corey:通过指定任何非空选项参数--
    .bak
    ,在这种情况下,您可以使两种实现都满意(GNU Sed仅在直接附加到
    -i
    时才接受选项参数;BSD/OSX Sed也接受这一点(除了允许空格将
    -i
    与其选项参数分隔开之外))。指定非空选项参数的代价始终是保留原始文件(重命名为原始文件名,后缀为选项参数),因此您必须使用单独的命令删除不需要的“备份”文件。