-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathgit-revert-file-permissions.sh
executable file
·70 lines (52 loc) · 2.15 KB
/
git-revert-file-permissions.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/bin/bash
# Git stores only the 'execute' file permission, and permissions sometimes gets lost
# when copying files around to/from Windows PCs or to/from FAT/FAT32 disk partitions.
#
# This script restores all file permissions to their original values in the Git repository.
# It is not as terse as the usual tips from the Internet, it will display
# the affected files.
#
# Limitations: This script does not attempt to properly parse the patch lines
# generated by "git diff", therefore:
# - It cannot cleanly display the affected files.
# - It will probably fail if files have been renamed, and those renames
# have not been checked in yet.
#
# Copyright (c) 2015 R. Diez - Licensed under the GNU AGPLv3.
set -o errexit
set -o nounset
set -o pipefail
# set -x # Trace this script
# 1) Generate a patch with the current changes.
# Alternative to git diff -R below: revert the patch lines by piping to 'sed' like this:
# | sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/'
PATCH_LINES="$(git diff --patch -R)"
if false; then
echo "PATCH_LINES: $PATCH_LINES"
fi
# 2) Keep only those patch lines about permission changes.
set +o errexit
PATCH_LINES_DIFF_AND_MODE="$(grep --extended-regexp '^(diff|old mode|new mode)' <<<"$PATCH_LINES")"
GREP_EXIT_CODE="$?"
set -o errexit
PATCH_LINES="" # Release memory as soon as possible.
# Maybe there are no files to patch at all (no changes).
if [ $GREP_EXIT_CODE -eq 1 ]; then
echo "No file permissions need to be reverted."
exit 0
fi
# 3) Count the number of affected files. This is just for display purposes.
set +o errexit
FILE_COUNT="$(grep --count "old mode" <<<"$PATCH_LINES_DIFF_AND_MODE")"
GREP_EXIT_CODE="$?"
set -o errexit
if [ $GREP_EXIT_CODE -eq 1 ]; then
echo "No file permissions need to be reverted."
exit 0
fi
# 4) Display the affected files.
echo "Affected file(s) are (this script does not attempt to extract clean filenames):"
grep --before-context=1 "old mode" <<<"$PATCH_LINES_DIFF_AND_MODE" | grep --extended-regexp '^diff'
# 5) Revert the changes.
git apply <<<"$PATCH_LINES_DIFF_AND_MODE"
echo "Done reverting execute file permission on $FILE_COUNT file(s)."