Git change index content directly to bind pre-commit formatting

I would like to automatically format files before adding them to the Git index. Right now, I have a pre-commit binding that looks like this:

#!/bin/bash

set -e
exec 1>&2

workingext="working.$$"
ext="bak.$$"
git diff -z --cached --name-only | egrep -z '\.(pl|pm|t)$' | \
        while read -d'' -r f; do
    # First modify the file in the index
    mv "$f" "$f.$workingext"
    git show :"$f" > "$f"
    perl -c "$f"
    perltidy -pbp -nst -b -bext="$ext" "$f";
    rm -f "$f.$ext"
    git add "$f"
    mv "$f.$workingext" "$f"
    # Then the working copy
    perl -c "$f"
    perltidy -pbp -nst -b -bext="$ext" "$f";
    rm -f "$f.$ext"
done

      

Basically, I back up my working copies, check out the indexed copies, format them, add them to the index, and then restore the working copies and formats them so that the differences between the working and indexed copies don't grow too large. I first check the syntax of the files using perl -c

so that the formatter perltidy

can't get too confused by the syntactically invalid file.

So far this has worked very well. However, I would like to know if there is a way to add the contents of one file to the index under the name of another file. That is, a command like will git update-index-from-file --from-file foo.pl.tmp foo.pl

update the file foo.pl

so that its contents in the index come entirely from foo.pl.tmp

, but whose version in the working directory remains unchanged. This might avoid the dance of renaming I'm doing right now (although it might be useful to ensure that I don't irrevocably lose the contents of the index).

+3


source to share


1 answer


Yes it is possible. First, you need to create a blob from your file by running the following command:

git hash-object -w foo.pl.tmp

      

See it here: http://www.kernel.org/pub/software/scm/git/docs/git-hash-object.html

Computes an object identifier value for an object of the specified type with the contents of a named file (which may be outside of the working tree) and possibly writes the resulting object to the object's database. Reports its object identifier to stdout.

Using the blob sha that is git hash-object

sent to STDOUT, you can now add this blob as "foo.pl" to your index by running



git update-index --add --cacheinfo 100644 *YOURSHA* foo.pl

      

From the update index manpage :

- cacheinfo is used to register a file that is not in the current working directory. This is useful for merging with minimal styling.

To pretend you have a mode and sha1 file along the way, say:

$ git update-index --cacheinfo mode sha1 path

      

But Id like to notice that your situation is very similar that you really should be using a smudge filter to do this. See here to learn about them: https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#Keyword-Expansion

+8


source







All Articles