Search code examples
bashgitloggingheaderchangelog

How to auto include the newest git commit metadata into the commited files?


I aim to add a rudimentary change log to the top of every file, e.g.:

# 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) ....

Now, in order to not have to do that manually, I would like to include the output of

git log -1

to the files concerned by this commit. (Not sure whether including the commit message is smart though..)

One way of doing this is via a bash script, which prepends the output of the above to the file(s). But this modifies the file(s), and the repo would never be actually up to date.

Hence: Is there a way to "overload" git commit or somehow sneak this in without git noticing?

Thanks in advance =)


Solution

  • After some tinkering, I chose this format (here it is for .m files):

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

    ... and realized that I don't need the commit meta-data to achieve my goal. I get:

    • the dates from $(date)
    • the Author/Modifier from $(git config user.name)
    • the current branch from $(git rev-parse --abbrev-ref HEAD)

    Still I followed @LeGEC's approach of having one script which does two things, as follows:

    • insert_changelog.sh: This ensures that every untracked file with a specific extension receives a changelog. Further, it fills the static information of <date_of_creation> and <author>.
    • update_changelog.sh: This script updates the latter 3 fields of every tracked and modified file.

    For the time being, I run this manually before running git add <modified files>.

    I append the code below. This is my first bash scripting experience so feel free to point out what could be improved <=)


    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;