简体   繁体   中英

Prevent git committers from creating certain directories

Is there a way to prevent git committers from creating a directory in the repository.

We have some developers who keep misplacing files in a directory structure. Files that should be in

 a/b/c/file

End up in

 a/a/b/c/file

I simply want to prevent the creation of

 a/a/*

It needs to happen suitably obviously, so that they know their files weren't committed... thus, simply ignoring a/a/* isn't enough.

Is there a way to do this?

EDIT

A few people have pointed out that committers should be 'trained' to not do this. There are a few flaws there:

  • Committers are human and make mistakes; training won't prevent this from happening
  • This is not the kind of information that would stick in the head of a new hire during training (waaay to fine a detail)
  • Mostly, this occurs during merges from one branch to another, so the files are not being manually created, rather they are pulled over in a larger changeset.

Thus, the need for an automated approach.

User education with a 2x4 clue-stick should be the first choice. For a technological solution you could prevent them from making such commits locally with a suitable commit hook. However, they probably would fail to install the hook as well. So you are left with implementing a hook that rejects their pushes. You can do this with an update hook which can reject commits before they get written into the central repository. Here is such a hook script:

#!/bin/sh
#
# update hook - args: refname sha1-old sha1-new

ref="$1"
old="$2"
new="$3"
if [ -z "$ref" -o -z "$old" -o -z "$new" ]; then
  echo >&2 "usage: $0 <ref> <oldrev> <newrev>"
  exit 1
fi

for badpath in a/a a/z/x; do
  if git ls-tree $new:$badpath >/dev/null; then
    bogus=$(git ls-tree -r --name-only $new $badpath)
    echo >&2 "REJECTED DUE TO BOGUS PATH \"$bogus\""
    exit 1
  fi
done

exit 0

If we create a simple bare repository and add this as hooks/update and make it executable (on windows, we don't need to do that - hooks are executed anyway). Then clone the repository and add a banned path (like a/b/c/file as in your example). This is what I get when I push this commit:

C:\Users\Pat\AppData\Local\Temp\x\L>git push origin master
Counting objects: 9, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (7/7), 423 bytes | 0 bytes/s, done.
Total 7 (delta 0), reused 0 (delta 0)
remote: REJECTED DUE TO BOGUS PATH "a/a/b/c/file"
remote: error: hook declined to update refs/heads/master
To C:/Users/Pat/AppData/Local/Temp/x/R
 ! [remote rejected] master -> master (hook declined)
error: failed to push some refs to 'C:/Users/Pat/AppData/Local/Temp/x/R'

This illustrates two things. Firstly, these hook scripts are actually very simple to create and to test in some temporary repository. Anything you echo to stderr or stdout gets copied to the pushing user. Second - this all works on windows too (when using Git for Windows at least).

A commit hook works on the users local repository and would be less obnoxious but you then have the problem of ensuring that all local clones have the correct hooks in place. This is much simpler to handle on the server end.

This would accomplish preventing creation of a subdirectory a , but it's not ideal, and the better answer is probably training:

ln -s . a
git add a
git commit -m "Create top-level self-referential symlink to stifle subdirectory creation"

Submodules (as proposed in the comment) is an option, but that won't prevent the user from creating a/a , it could just prevent him from pushing in unrelated directories.

You can make a git hook that check that no files is placed inside the folder a/a/ and reject the push if that happen. Checkout git hooks over there: http://git-scm.com/book/en/Customizing-Git-Git-Hooks

You're probably looking for the pre-receive hook. Then, you only need to write your own script - shouldn't be too hard.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM