In case you are now entering this right, I just went through it and can generalize where it stands. If you have not tried this yet, some of the details here may help.
I think @Omid Ariyan's approach is the best way. Add pre-commit and post-checkout scripts. DO NOT forget to call them exactly what Omid does, and DO NOT forget to make them executable. If you forget about it, they will have no effect, and you will run git commit again and again, wondering why nothing is happening :) Also, if you cut and paste from a web browser, be careful that the quotation marks and ticks do not change.
If you run the pre-commit script once (by running git commit), then .permissions files will be created. You can add it to the repository, and I think there is no need to add it again and again at the end of the pre-commit script. But it doesn’t hurt, I think (hopefully).
There are a few minor issues with the directory name and the presence of spaces in the file names in Omid scripts. Spaces were a problem here, and I had some problems fixing IFS. For the record, this pre-commit script worked correctly for me:
#!/bin/bash SELF_DIR=`git rev-parse --show-toplevel` DATABASE=$SELF_DIR/.permissions
Now, what do we get from this?
The .permissions file is at the top level of the git repository. It has one line in the file, here is the top of my example:
$ cat .permissions .gitignore;660;pauljohn;pauljohn 05.WhatToReport/05.WhatToReport.doc;664;pauljohn;pauljohn 05.WhatToReport/05.WhatToReport.pdf;664;pauljohn;pauljohn
As you can see, we have
filepath;perms;owner;group
In the comments about this approach, one of the posters complains that it only works with the same username, and this is technically true, but it is very easy to fix. Please note that after checking the script, there are 2 parts to the action,
# Set the file permissions chmod $PERMISSIONS $FILE
This way I save only the first thing I need. My username on the web server is really different, but more importantly, you cannot run chown if you are not root. However, you can run "chgrp". Simple enough how to use this.
The first answer in this most widespread post suggests using git-cache-meta, a script that does the same work as the pre / post hook scripts here (parsing the output from git ls-files ). These scripts are easier for me to understand, git-cache-meta code is more complex. You can save git-cache-meta in the path and write pre-commit and post-checkout scripts that will use it.
Spaces in file names are a problem in both Omid scripts. In the post-checkout script you will find out that you have spaces in the file names if you see errors like this
$ git checkout -- upload.sh Restoring file permissions...chmod: cannot access '04.StartingValuesInLISREL/Open': No such file or directory chmod: cannot access 'Notebook.onetoc2': No such file or directory chown: cannot access '04.StartingValuesInLISREL/Open': No such file or directory chown: cannot access 'Notebook.onetoc2': No such file or directory
I am checking solutions for this. Something works here, but I tested in only one case
#!/bin/bash SELF_DIR=`git rev-parse --show-toplevel` DATABASE=$SELF_DIR/.permissions echo -n "Restoring file permissions..." IFSold=${IFS} IFS=$ while read -r LINE || [[ -n "$LINE" ]]; do FILE=`echo $LINE | cut -d ";" -f 1` PERMISSIONS=`echo $LINE | cut -d ";" -f 2` USER=`echo $LINE | cut -d ";" -f 3` GROUP=`echo $LINE | cut -d ";" -f 4`
Since permission information is one line at a time, I set IFS to $, so only line breaks are treated as new.
I read that it is VERY IMPORTANT to set the IFS environment variable as it was! You can understand why a shell session might go bad if you leave $ as the only delimiter.