打印版本、作者、修改日期到一个文件

Printing version, author, date modified to a file

我之前使用 SVN 开发了 Tcl/Python 脚本进行版本控制;现在我正在使用 git。对于 SVN,我使用关键字将修改日期和其他信息打印到文件 headers,但 git 不提供此类功能。我已经阅读了这样做的原因,并且我同意这个功能在大多数情况下并不是真正必需的。如果可以从 git 本身获取信息,为什么要将此信息打印到文件中?

但是,如果我正在使用 git 版本控制开发脚本,但我想让 read-only 未使用 git 的用户可以使用该脚本怎么办?在这种情况下,文件中需要一些信息来告诉用户它是什么版本,也许还有谁修改了它以及何时修改了它。 SVN 关键字提供了这个功能,但是 git 没有一个简单的方法来做到这一点,除非编写一些复杂的 pre-commit 钩子,无论如何都会使工作副本变脏。

有没有人有类似的用例,以及使用 git 的方法?

这取决于您打算如何发布文件(用户从您的存储库下载它们,例如从 Github 或 Bitbucket)或者您是否准备了可以从您的站点下载的包。您可以在提交 "written" 之前将信息添加到存储库(即使用 pre-commit 挂钩),或者在从存储库签出文件时(即使用 smudge/cleanup 过滤器,请参阅http://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes)。

另一种选择是使用自定义脚本检查您的文件,从 git 获取信息并在发布文件之前将相关部分插入文件。

因此,如果有人感兴趣,我在查看下面的评论后想出了一个解决方案。我编写了一个 bash 脚本,可以使用 git archive$gitFiles 文件夹中包含的文件发布到 $publishFolder 位置。然后脚本使用 git log 获取每个文件的信息,并使用 sed s/findstr/repstr/ $file.

打印到每个文件 header
#!/bin/bash

publishFolder="./Release"
gitFiles="./PythonFiles"

updateFindStr="\$Last Update[^\$]*\$"
commentFindStr="\$Comment[^\$]*\$"
hashFindStr="\$Hash[^\$]*\$"

# Archive the whole folder
folderHash=$(git log -1 --pretty=format:"%H" $gitFiles)
git archive $folderHash --format tar $gitFiles > $publishFolder/archive.tar

# Unpack the tar file and delete it
tar xf $publishFolder/archive.tar -C $publishFolder
rm $publishFolder/archive.tar

# Loop through all files in the gitfiles folder and write git info to the published files
for file in $(ls $gitFiles/*.*)

do
    echo "Publishing $(basename $file)..."

    # Grab the git info and save as string in format date;author;comment;hash
    gitInfo=$(git log -1 --pretty=format:"%cd;%an;%s;%H" --date=short $file)

    # Split the string and save to separate variables
    IFS=";" read date author comment hash <<< "$gitInfo"

    # build update, comment and hash strings
    updateRepStr="\$Last Update: ${date} by ${author} \$"
    commentRepStr="\$Comment: ${comment} \$"
    hashRepStr="\$Hash: ${hash} \$"

    # Write git hash and info into the new file
    sed -i "s/${updateFindStr}/${updateRepStr}/; s/${commentFindStr}/${commentRepStr}/; s/${hashFindStr}/${hashRepStr}/" $publishFolder${file:1}

done

所以我从这样的文件 header 开始:

# ------------------------------------------------------------------------------
# PYTHONSCRIPT:     myfile.py
# ------------------------------------------------------------------------------
# Project:      n/a
# Created by:   user on 22/7/2015
# $Last Update: $
# $Comment:     $
# $Hash:        $
# ------------------------------------------------------------------------------

最后我得到了一个 header 看起来像这样的已发布文件,这正是我想要的:)

# ------------------------------------------------------------------------------
# PYTHONSCRIPT:     myfile.py
# ------------------------------------------------------------------------------
# Project:      n/a
# Created by:   user on 22/7/2015
# $Last Update: 2015-09-09 by user $
# $Comment: Added comment keyword $
# $Hash: ec56f527333c0c0af98c2ed3ab3395c6c8a50624 $
# ------------------------------------------------------------------------------

由于您想在 git 中模拟类似于 SVN $Header$ 的东西,这里有一个实现该确切功能的解决方案:

  1. 添加以下pre-commit挂钩:

    #!/bin/sh
    git diff --cached --name-only -z --diff-filter=ACM |
            xargs -r0 .filters/keywords --
    git diff --cached --name-only -z --diff-filter=ACM |
            xargs -r0 git add -u -v --
    
  2. 添加以下commit-msg挂钩:

    #!/bin/sh
    awk '!/^[[:space:]]*(#|$)/{exit f++}END{exit !f}' "" && exit
    # NOTREACHED unless commit was aborted
    git diff --cached --name-only -z --diff-filter=ACM |
            xargs -r0 .filters/keywords -d --
    git diff --cached --name-only -z --diff-filter=ACM |
            xargs -r0 git add -u -v --
    
  3. 下载“.filters/fraubsd-keywords”但将文件重命名为"keywords":

    https://raw.githubusercontent.com/freebsdfrau/FrauBSD/master/.filters/fraubsd-keywords

  4. 编辑 "keywords",在顶部的配置部分进行更改:

    • FrauBSD 到 Header
    • _FrauBSD 到 _Header

之后,每次执行 git commit 时,文本 $Header$ and/or $Header: ... $ 将被翻译成 $Header: file YYYY-MM-DD HH:MM:SS GMTOFFSET committer $

注意:您可能需要修改 "keywords" 脚本的一小部分才能对 more-or-less 类型的文件进行操作。在撰写本文时,它仅对 "ASCII text" 或 "shell scripts".

的文件进行操作