我的目标是在每个文件的顶部添加一个基本的更改日志,例如:
# 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;