Home > Blockchain >  git: prevent non-adders from deleting/renaming a file
git: prevent non-adders from deleting/renaming a file

Time:07-21

In git - how can I prevent a person from deleting/renaming/moving files he has not added? Maybe some commit hook? I prefer the check to happen locally, i.e. as soon as possible and on the sever side as well. Here is how one can check who actually added a file:

git log --diff-filter=A --pretty=format:"%an" <file>

In my case it is not about creating a bulletproof security mechanism that can't be bypassed, but rather a "reminder" for the team to obey the above mentioned rule. I don't expect my team to manipulate hooks but I'm sure that renaming/moving might happen by mistake.

CodePudding user response:

note that git doesn't track individual files, the notion of "renaming/moving" is just guesswork based on the files' content comparison.

You can look, in git help diff, at the description of the -M, -C, --find-copies-harder and -l options.

Also : unless the committers have to sign their commits, the "author name" is purely informational and can be set to any value.

You may still try use git to detect those renames and add a hook (as @JoachimSauer correctly commented: a central hook on the server side) to reject them, but know that these checks may be somehow bypassed (e.g: I can first create a file config.copy whose content is foobar, push it, then update it to have the same content as config).

Depending on what your repository holds (code ? 1 file = 1 blog post ? chapters of a book ?) you may want to think further about what you want to ignore.


To spot renamings, all git commands that deal with displaying information about commits (git diff, git show, git log) have a --name-status option.

Here is an example :

$ git diff --name-status HEAD^ HEAD
R097    a.txt   aa.txt
$ git log -1 --format=""
R097    a.txt   aa.txt

Depending on the hook you use, there will be slight variations on what diff you should be looking at :

  • in a pre-commit hook (client side, run before each commit), you should be looking at staged differences :
git diff --cached --name-status
  • in a pre-push hook (client side, run before each push), you probably want to look at :
git diff --name-status $remote_sha...$local_sha

(see the sample pre-push script provided with git for an explanation of the names)

  • in a pre-receive hook (server side, run before accepting a push), you probably want to look at :
git diff --name-status $old_sha...$new_sha

(see the doc section on pre-receive hooks)

Then, you can look for lines starting with an R, and check if the "creator" of the first filename matches the author of the latest commit.

  • Related