post-receive hook — if incoming file type *.cgi, then set permission to 755

Every time I modify a *.cgi file locally, the 755 permissions on the remote server get removed after a push to that remote server. Is this best handled with additional code in the post-receive hook, e.g., — if file type *.cgi, then set permission to 755. Or, is there a better way to handle this? If a few additional lines of code in the post-receive hook will do the job, an example would be greatly appreciated.

GIT_WORK_TREE=/home/lawlist git checkout -f

EDIT (April 27, 2014):  I’ve discovered that by setting the desired permissions on a local machine (OSX box) prior to pushing to the remote server (Linux), the permissions are set accordingly on the remote server. This may be an acceptable answer to the question, but there may also be circumstances where a user may not want permissions set on the local machine, so I’m going to think about this some more and examine some bash / shell code that could be used with the post-receive hook before I post an answer. Essentially, the bash / shell script would need to see if a file already exists and what permissions have been assigned, and restore those permissions after the updated push has occurred.

  • How does git know my email?
  • git clone with different file permissions
  • How to download the flat file from GitHub?
  • Git: Combine multiple repositories
  • Count number of lines in a git repository
  • Finding the path where Git is installed on a Windows system
  • How can I know in git if a branch has been already rebased onto master?
  • git branching - how to make current master a branch and then revert master back to previous version?
  • Best practice for applying a Git stash with conflicts?
  • Git merge all but one file, and that file be a (full) conflicted file
  • Why git log --cherry-pick is so slow?
  • How can I clone a git repository and keep remotes?
  • 3 Solutions collect form web for “post-receive hook — if incoming file type *.cgi, then set permission to 755”

    If your goal is to manage permissions on the remote server by using a local machine, then the answers by mockinterface and patthoyts are both valid.

    It is important to point out that a post-receive hook is written in advance and contemplates certain expected conditions. There will undoubtedly be unique situations that arise that are not contemplated by the existing post-receive hook, and another method would need to be used.

    To the extent that you desire 755 permissions in both locations (i.e., remotely and locally), then setting the permissions locally prior to pushing is sufficient.

    To the extent that you desire different permissions in both locations (i.e, remotely and locally), then you will need to use one of the methods suggested by the others in this thread.

    Git doesn’t track file permissions extensively, as it was built to collaborate on content rather than files, across different user permissions and group setups, different machines and different operating systems. The basic notions that are recognised across all the above are: plain files, executable files, (symbolic) links and folders.

    You should manage permissions per-repository, and managing the permissions in a hook is of course valid. However instead of managing the permissions by yourself I’d like to point your attention to the various git-cache-meta implementations, usually based on the original suggestion in this thread.

    You can find it present many times on github, and usually they involve running,

    $ git-cache-meta --store  # create a .git_cache_meta file to store permissions

    and elsewhere,

    $ git-cache-meta --aply  # to apply the permissions from a .git_cache_meta file

    You can modify the .git_cache_meta file to mention only the files you are interested in. Consider using this slightly more standard approach with your hook.

    git update-index --chmod +x filepath will stage a change to the git permissions for this file in the staged tree. This works on windows as well as unix. The result of this is shown below and needs to be committed. It is staging the change rather like staging a file change to the content.

    $ git update-index --chmod +x z
    $ git diff --cached
    diff --git a/z b/z
    old mode 100644
    new mode 100755

    You could add a pre-commit locally to ensure that your commits always set the executable bit on .cgi files using the update-index command.

    Git Baby is a git and github fan, let's start git clone.