I have a file in my repository and I only want to allow inserts at the end.
What linux command can I use to validate that between two git commits the file was only modified at the end?
I have a file in my repository and I only want to allow inserts at the end.
What linux command can I use to validate that between two git commits the file was only modified at the end?
There is no Git command that does this, but you can script it in Bash (or your shell of choice):
You can create a script that does this:
#!/bin/bash
# Create a file which is a version of your file of interest before last commit
git --no-pager show HEAD~:<file> > original
# Get the number of lines for that file and call it n:
n=$(cat original | wc -l)
# Test whether the last commit modified the file other than
# by adding content at the end
[[ "$(diff <(cat original) <(head -$n <file>))" == "" ]]
# Finally, clean up by deleting the temp file:
rm original
This will return 0 if the file was modified only at the end (or not at all) and 1 if there was a modification that you want to block (i.e. not at the end).
Of course, you need to replace <file> with the path of your file of interest.
If the 2 commits you are interested in are not the last 2 commits, you can modify the script to be more general. Here, for instance, I will use <hash1> and <hash2> for the 2 commits, but you can use any reference that is convenient to identify any 2 commits:
#!/bin/bash
# Create a file which is a version of your file of interest at the first commit
# you care about (using its hash):
git --no-pager show <hash1>:<file> > original
# Create a file which is a version of your file of interest at the second commit
# you care about (using its hash):
git --no-pager show <hash2>:<file> > next
# Get the number of lines for the first of these files and call it n:
n=$(cat original | wc -l)
# Test whether the commit with hash2 modified the file other
# than by adding content at the end
[[ "$(diff <(cat original) <(head -$n next))" == "" ]]
# Finally, clean up by deleting the 2 temp files:
rm original next
Alternatively, for convenience since you will probably need to test this often in your pipeline, you can create a function and add it to your .bashrc or equivalent:
function check {
local n
git --no-pager show "$2":"$1" > original
git --no-pager show "$3":"$1" > next
n=$(cat original | wc -l)
[[ "$(diff <(cat original) <(head -$n next))" == "" ]]
rm original next
}
You can then use it with:
check <file-path> <commit-hash1> <commit-hash2>
You can use git log hash1..hash2 to see if one file modified with --stat and the modification content with -c.
Note, here the hash2 should be the older commit, and hash2 is the recent commit.Otherwise you'll get nothing
$ git log --stat bdf402d1a387ba9a8..620f05b4c9 library/HQ/groupsql.sql
commit 620f05b4c9ce53549b4ad8003de433e44054dea6
Author: lu <lu.com>
Date: Fri Oct 9 17:57:24 2020 +0800
specify material,price when create class course
library/HQ/groupsql.sql | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
commit ed0c5461c79acd43072ca1d2655cec76076d7de3
Author: lu <lu.com>
Date: Mon Sep 28 20:56:23 2020 +0800
remove material history
library/HQ/groupsql.sql | 14 --------------
1 file changed, 14 deletions(-)