如何将最新的 git 提交元数据自动包含在提交的文件中?



我的目标是在每个文件的顶部添加一个基本的更改日志,例如:

# Changelog: 
# Last Modified on: 31.2.2020
# Last Modified by: Arthur Dent
# Last Modification: "After a Trillian tries, it works"
# File created: 01.01.1970
def whale2pot(args) ....

现在,为了不必手动执行此操作,我想包含

git log -1

到此提交所涉及的文件。(不确定包含提交消息是否明智。

一种方法是通过 bash 脚本,该脚本将上述内容的输出附加到文件中。 但这会修改文件,并且存储库实际上永远不会是最新的。

因此:有没有办法"超载"git commit或以某种方式潜入它而不引起 git 的注意?

提前感谢=(

在你的存储库中有一个如此明显的合并冲突来源可能会令人惊讶,
并且当您浏览存储库时很容易从 git 中提取信息(git log -1 the/file(。

在深入研究如何在文件内容中实际存储该信息之前, 也许你可以满足于一个方便的外壳快捷方式,或者一个集成到你的编辑器的大纲? 例如,vscode具有git lens扩展名,它为您提供了非常接近的东西(实际上是每行注释(


创建日期将非常静态,因此可以在文件创建时插入并保持这种状态;

对于标题的其他部分:我认为filter是最接近正确方法的

官方文档在这里:gitattributes

请参阅此 SO 答案中的解释:git 可以在提交之前过滤掉某些行吗?

您将编写两个脚本:

  • 一个是clean脚本,它将用常量值替换标题行(例如:# Last Modified :没有日期(
  • 第二个是smudge脚本,它将git log -1运行并用所需的值填充行

clean脚本将在暂存文件时运行,并确保存储在 git 中的 blob 具有常量标头,以避免在合并、变基等时出现问题

smudge脚本将在签出文件时运行,并将在工作树版本中写入正确的内容 - 磁盘上的文件,您将在编辑器中实际打开该文件。


这个答案中没有排序的要点是:污迹脚本在 stdin 上接收文件的内容,而不是文件名,所以我还没有看到从该脚本运行git log -1 file/name的干净方法。

经过一番修补,我选择了这种格式(这里是 .m 文件(:

%% ------------------------------------------------  
%  
% Created on:       <date_of_creation>  
% Author:           <author>  
%  
% Last modifier:    <modifier>  
% Last modified:    <date_of_last_mod>  
% On Branch:        <branch>  
%  
%%-------------------------------------------------

。并意识到我不需要提交元数据来实现我的目标。我得到:

  • $(date)的日期
  • 来自$(git config user.name)的作者/修饰符
  • 当前分支来自$(git rev-parse --abbrev-ref HEAD)

我仍然遵循@LeGEC的方法,即使用一个脚本来做两件事,如下所示:

  • insert_changelog.sh:这可确保每个具有特定扩展名的未跟踪文件都会收到更改日志。此外,它填充了<date_of_creation><author>的静态信息。
  • update_changelog.sh:此脚本更新每个跟踪和修改的文件的后 3 个字段。

目前,我在运行git add <modified files>之前手动运行它。

我附加下面的代码。这是我第一次使用bash脚本,所以请随时指出可以改进的地方<=(

<小时 />

insert_changelog.sh:

#!/bin/bash
#If there are no .m files for which this would apply, suppress the this notification (If i get that right)
shopt -s nullglob
#Act on untracked files 
files=($(git ls-files --others --exclude-standard))
for item in ${files[*]}
do
#For time being, only consider matlab files
if [[ $item == *.m ]]
then
#Check whether the header already exists
read -r first_line < $item 
first_cl_line="%% ------------------------------------------------"
if [ "$first_line" = "$first_cl_line" ]
then
continue
else
#Include Changelog into file
cat changelog_template.txt > tempfile
cat $item >> tempfile 
mv tempfile $item
#Fill in static fields of inception date and author
sed -i "3,4d" $item
sed -i "2 a % Created on:       $(date)" $item
sed -i "3 a % Author:           $(git config user.name)" $item
#Update current changelog
./update_changelog.sh $item
fi
fi
done;

update_changelog.sh:

#!/bin/bash
USER=$(git config user.name)  
BRANCH=$(git rev-parse --abbrev-ref HEAD)  
#Remove outdated lines and replace with updated ones.  
for item in $(git ls-files -m)  
do  
sed -i "5,8d" $item  
sed -i "5 a % Last Modifier:    $USER" $item  
sed -i "6 a % Last Modified:    $(date)" $item  
sed -i "7 a % On Branch:        $BRANCH" $item  
sed -i "8 a %" $item  
done;

最新更新