8

Im struggling for a couple of hours to make git store metadata (permissions/flags/etc) of the files using metastore and I use hooks/pre-commit for this.

The script is invoked correctly, and the file "metadata" is modified but not added into commit.

I tried calling:

git add ./metadata 

and

git add -u ./metadata

from the pre-commit script, but there is no effect. The file ends up uncommited and marked as modified or staged BUT not commited, ever.

Is there any way to make this work? Basically, I want it to update and commit the file "metadata" on each commit (preferably, as the same commit, so I can restore all permissions after checkout)

Thanks!

P.S. If you are wondering why I need this, the answer is I store OS files for an embedded device which needs permisions/suid flags etc.

Phoenix
  • 834
  • 1
  • 6
  • 14
dimovnike
  • 417
  • 2
  • 5
  • 11
  • It should work, maybe you are doing something wrong. Pre-commit hook is executed automatically when you do "git commit". It must have an executable bit set. So try to add some files to the staging are manually and then do "git commit". After that do "git show" to see what changes have been introduced in this commit and see if metadata has been committed. – Arkadiusz Drabczyk Jun 15 '14 at 22:15

3 Answers3

2

You can do something like this:

#!/bin/sh
#

perl -i -pe 's/var app_version = "\d+\.\d+\.\K(\d+)/ $1+1 /e' ./version.js

git add ./version.js

What it does: It changes the string var app_version = "0.1.1"; to var app_version = "0.1.2"; and adds the file back to the git commit process. When you commit the latest change will be included.

Batist
  • 129
  • 2
1

To modify a file in the pre-commit hook in a way that doesn't interfere with unstaged changes (i.e. git-add -p friendly), you need to edit the version of the file in the index.

Here's an example pre-commit hook which updates a timestamp-like version number in a file header:

#!/bin/bash
set -eEuo pipefail

date=$(date +%Y%m%d%H%M)

# Enumerate *.el files that have been edited for this commit
git diff-index --name-only --cached -z HEAD |
    grep -z '\.el$' |
    while read -r -d '' fn
    do
        # Patch index
        blob_sha1=$(git show :"$fn" |
                        sed "s/^;; Version:  .*/;; Version:  $date/" |
                        git hash-object -w --stdin)
        printf '100644 blob %s\t%s\0' "$blob_sha1" "$fn" |
            git update-index -z --index-info

        # Patch working tree to match index
        sed -i "s/^;; Version:  .*/;; Version:  $date/" "$fn"
    done
Vladimir Panteleev
  • 1,389
  • 1
  • 13
  • 20
0

I have found the solution. The problem is that when modified from pre-commit hook file is the only modified file - the commit is not happening. While testing this, I was making changes only in the "metadata" file and thats why it did not work for me.

As soon as I modify some other files in the repo add add/rm new files - the metadata file is properly commited!

Bottom line: In order to commit the modified files from pre-commit hook, git needs some other staged changes, otherwise the commit won't happen (probably, git erroneously detects that there is nothing to commit).

This seems a bit unexpected behaviour to me. I tested this in git 1.8 and git 2.0 the behaviour is the same.

dimovnike
  • 417
  • 2
  • 5
  • 11
  • I got the same problem, but having other staged files changed doesn't solve the issue. Git doesnt pick up changes made by pre-commit in my case.. – frhd Oct 01 '14 at 15:32
  • make sure u do git add for the canges made by pre-commit script (at the end of the script). – dimovnike Oct 01 '14 at 19:10
  • I cant do that. I'm getting an `index.lock` error, since `git-commit` is calling the `pre-commit`. Does it work for you? – frhd Oct 01 '14 at 19:37