summaryrefslogtreecommitdiff
path: root/pre-commit.d
diff options
context:
space:
mode:
Diffstat (limited to 'pre-commit.d')
-rwxr-xr-xpre-commit.d/20warn-hardlinks10
-rwxr-xr-xpre-commit.d/20warn-problem-files30
-rwxr-xr-xpre-commit.d/20warn-special-file12
-rwxr-xr-xpre-commit.d/30store-metadata85
4 files changed, 94 insertions, 43 deletions
diff --git a/pre-commit.d/20warn-hardlinks b/pre-commit.d/20warn-hardlinks
deleted file mode 100755
index c1fd8f7..0000000
--- a/pre-commit.d/20warn-hardlinks
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-set -e
-
-if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ]; then
- hardlinks=$(find -type f -not -links 1 | grep -v /.git/ | grep -v /.hg/ | grep -v /.bzr/) || true
- if [ -n "$hardlinks" ]; then
- echo "etckeeper warning: hardlinked files could cause problems with $VCS:" >&2
- echo "$hardlinks" >&2
- fi
-fi
diff --git a/pre-commit.d/20warn-problem-files b/pre-commit.d/20warn-problem-files
new file mode 100755
index 0000000..f7c7580
--- /dev/null
+++ b/pre-commit.d/20warn-problem-files
@@ -0,0 +1,30 @@
+#!/bin/sh
+set -e
+
+exclude_internal () {
+ egrep -v '(^|/)(.git|.hg|.bzr|_darcs)/'
+}
+
+if [ "$VCS" = bzr ] || [ "$VCS" = darcs ]; then
+ special=$(find . -not -type d -not -type f -not -type l | exclude_internal) || true
+ hardlinks=$(find . -type f -not -links 1 | exclude_internal ) || true
+elif [ "$VCS" = hg ]; then
+ special=$(find . -not -type d -not -type f -not -type l | exclude_internal) || true
+ hardlinks=$(find . -type f -not -links 1 -exec hg status {} \; | exclude_internal ) || true
+elif [ "$VCS" = git ]; then
+ special=$(find . -not -type d -not -type f -not -type l -exec git ls-files --exclude-standard --cached --others {} \; | exclude_internal) || true
+ hardlinks=$(find . -type f -not -links 1 -exec git ls-files --exclude-standard --cached --others {} \; | exclude_internal) || true
+else
+ special=""
+fi
+
+if [ -n "$special" ] && [ -z "$AVOID_SPECIAL_FILE_WARNING" ]; then
+ echo "etckeeper warning: special files could cause problems with $VCS:" >&2
+ echo "$special" >&2
+fi
+if [ -n "$hardlinks" ] && [ -z "$AVOID_SPECIAL_FILE_WARNING" ]; then
+ echo "etckeeper warning: hardlinked files could cause problems with $VCS:" >&2
+ echo "$hardlinks" >&2
+fi
+
+true
diff --git a/pre-commit.d/20warn-special-file b/pre-commit.d/20warn-special-file
deleted file mode 100755
index 5712bc5..0000000
--- a/pre-commit.d/20warn-special-file
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-set -e
-
-if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ]; then
- special=$(find -not -type d -not -type f -not -type l | grep -v /.git/ | grep -v /.hg/ | grep -v /.bzr/) || true
- if [ -n "$special" ]; then
- echo "etckeeper warning: special files could cause problems with $VCS:" >&2
- echo "$special" >&2
- fi
-fi
-
-true
diff --git a/pre-commit.d/30store-metadata b/pre-commit.d/30store-metadata
index 243e019..b2a8678 100755
--- a/pre-commit.d/30store-metadata
+++ b/pre-commit.d/30store-metadata
@@ -14,14 +14,50 @@ filter_unknown() {
done
}
+filter_ignore() {
+ if [ "$VCS" = darcs ]; then
+ ignorefile=.darcsignore
+ fi
+
+ if [ "$VCS" = darcs ] && [ -e "$ignorefile" ]; then
+ patternsfile="$( mktemp -t etckeeper-$VCS.XXXXXXXXXX )"
+ grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" > "$patternsfile" || true
+ grep -Evf "$patternsfile"
+ rm -f "$patternsfile"
+ unset patternsfile
+ else
+ cat -
+ fi
+}
+
+statf() {
+ while read statfile; do
+ printf "$(stat --format="$1" "$statfile") "
+ echo "$statfile" | shellquote
+ done
+}
+
+shellquote() {
+ # Single quotes text, escaping existing single quotes.
+ sed -e "s/'/'\"'\"'/" -e "s/^/'/" -e "s/$/'/"
+}
+
generate_metadata() {
- # This function generates the script commands to fix any files
- # that aren't owner=root, group=root, or mode=0644 or 0755.
+ # This function generates the script commands to fix any file
+ # ownerships that aren't owner=root, group=root, as well as to
+ # store the permissions of files.
# The script is produced on stdout. Errors go to stderr.
+ #
+ # The script can use a 'maybe' function, which only runs a command
+ # if the file in its last argument exists.
- # We maintain the permissions on the directory containing VCS data
+ # We want files in the directory containing VCS data
# but we want find to ignore the VCS files themselves.
- NOVCS='. -wholename ./.git -prune -o -wholename ./.bzr -prune -o -wholename ./.hg -prune -o'
+ #
+ # (Note that when using this, the find expression must end with
+ # -print or -exec, else the excluded directories will actually be
+ # printed!)
+ NOVCS='. -path ./.git -prune -o -path ./.bzr -prune -o -path ./.hg -prune -o -path ./_darcs -prune -o'
# Keep the sort order the same at all times.
LC_COLLATE=C
@@ -30,31 +66,38 @@ generate_metadata() {
if [ "$VCS" = git ] || [ "$VCS" = hg ]; then
# These version control systems do not track directories,
# so empty directories must be stored specially.
- find -type d -empty | grep -v /.git/ | grep -v /.hg/ | grep -v /.bzr/ |
- sort | sed -e "s/^/mkdir -p '/" -e "s/\$/'/"
+ find $NOVCS -type d -empty -print |
+ sort | shellquote | sed -e "s/^/mkdir -p /"
fi
- # Find all files and directories that don't have root as the owner
- find $NOVCS \! -user root -exec stat --format="chown %U '{}'" {} \; \
- | sort | filter_unknown chown owner
+ if [ "$VCS" = darcs ]; then
+ # This version control system does not track symlinks,
+ # so they must be stored specially.
+ find $NOVCS -type l -print | sort | filter_ignore | while read link; do
+ dest=$( readlink "$link" )
+ printf "ln -sf '%s' '%s'\n" "$(echo "$dest" | shellquote)" "$(echo "$link" | shellquote)"
+ done
+ fi
+
+ # Find all files and directories that don't have the current user as the owner
+ find $NOVCS \! -user "$(id -u)" -print | statf "maybe chown %U" | sort | filter_unknown 'maybe chown' owner
# Find all files and directories that don't have root as the group
- find $NOVCS \! -group root -exec stat --format="chgrp %G '{}'" {} \; \
- | sort | filter_unknown chgrp group
-
- # Find all directories that aren't 0755
- find $NOVCS -type d \! -perm 0755 \
- -exec stat --format="chmod %a '{}'" {} \; | sort
+ find $NOVCS \! -group $(id -g) -print | statf "maybe chgrp %G" | sort | filter_unknown 'maybe chgrp' group
- # Find all files that aren't 0644 or 0755 (we can assume the VCS will
- # maintain the executable bit).
- find $NOVCS -type f \! -perm 0644 \! -perm 0755 \
- -exec stat --format="chmod %a '{}'" {} \; | sort
+ # Store all file modes, in case the user has an unusual umask.
+ find $NOVCS \( -type f -or -type d \) -print | sort | perl -ne '
+ BEGIN { $q=chr(39) }
+ chomp;
+ my $mode = (stat($_))[2];
+ s/$q/$q"$q"$q/g; # escape single quotes
+ printf "maybe chmod %04o %s\n", $mode & 07777, "$q$_$q";
+ '
# We don't handle xattrs.
# Maybe check for getfattr/setfattr and use them if they're available?
}
-if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ]; then
+if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ] || [ "$VCS" = darcs ]; then
if [ -f .metadata ]; then
# remove obsolete .metadata file
# git allows fully deleting it at this point, other VCS
@@ -80,6 +123,6 @@ if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ]; then
# this will do nothing if the metadata file is unchanged.
git add .etckeeper
fi
- # hg and bzr add not done, they will automatically
+ # hg, bzr and darcs add not done, they will automatically
# include the file in the current commit
fi