Initial commit.
This commit is contained in:
31
etckeeper/pre-commit.d/20warn-problem-files
Executable file
31
etckeeper/pre-commit.d/20warn-problem-files
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# (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'
|
||||
|
||||
if [ "$VCS" = bzr ] || [ "$VCS" = darcs ]; then
|
||||
special=$(find $NOVCS ! -type d ! -type f ! -type l -print) || true
|
||||
hardlinks=$(find $NOVCS -type f ! -links 1 -print) || true
|
||||
elif [ "$VCS" = hg ]; then
|
||||
special=$(find $NOVCS ! -type d ! -type f ! -type l -print) || true
|
||||
hardlinks=$(find $NOVCS -type f ! -links 1 -exec hg status {} \; -print) || true
|
||||
elif [ "$VCS" = git ]; then
|
||||
special=$(find $NOVCS ! -type d ! -type f ! -type l -exec git ls-files --exclude-standard --cached --others {} + -print) || true
|
||||
hardlinks=$(find $NOVCS -type f ! -links 1 -exec git ls-files --exclude-standard --cached --others {} + -print) || 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
|
||||
171
etckeeper/pre-commit.d/30store-metadata
Executable file
171
etckeeper/pre-commit.d/30store-metadata
Executable file
@@ -0,0 +1,171 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Keep the sort order the same at all times.
|
||||
LC_COLLATE=C
|
||||
export LC_COLLATE
|
||||
unset LC_ALL
|
||||
|
||||
filter_ignore() {
|
||||
case "$VCS" in
|
||||
darcs) ignorefile=.darcsignore ;;
|
||||
git) ignorefile=.gitignore ;;
|
||||
esac
|
||||
|
||||
if [ -n "$ignorefile" ] && [ -e "$ignorefile" ]; then
|
||||
listfile="$( mktemp -t etckeeper-$VCS.XXXXXXXXXX )"
|
||||
case "$VCS" in
|
||||
darcs)
|
||||
grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" > "$listfile" || true
|
||||
grep -Evf "$listfile"
|
||||
;;
|
||||
git)
|
||||
(git ls-files -oi --exclude-standard; git ls-files -oi --exclude-standard --directory) | sort | uniq > "$listfile" || true
|
||||
if [ -s "$listfile" ]; then
|
||||
sed 's/^\.\///' | grep -xFvf "$listfile"
|
||||
else
|
||||
cat -
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
rm -f "$listfile"
|
||||
unset listfile
|
||||
else
|
||||
cat -
|
||||
fi
|
||||
}
|
||||
|
||||
shellquote() {
|
||||
# Single quotes text, escaping existing single quotes.
|
||||
sed -e "s/'/'\"'\"'/g" -e "s/^/'/" -e "s/$/'/"
|
||||
}
|
||||
|
||||
generate_metadata() {
|
||||
# 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 want files in the directory containing VCS data
|
||||
# but we want find to ignore the VCS files themselves.
|
||||
#
|
||||
# (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'
|
||||
|
||||
if [ "$VCS" = git ] || [ "$VCS" = hg ]; then
|
||||
# These version control systems do not track directories,
|
||||
# so empty directories must be stored specially.
|
||||
find $NOVCS -type d -empty -print |
|
||||
sort | shellquote | sed -e "s/^/mkdir -p /"
|
||||
fi
|
||||
|
||||
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
|
||||
|
||||
# Store things that don't have the default user or group.
|
||||
# Store all file modes, in case the user has an unusual umask.
|
||||
find $NOVCS \( -type f -or -type d \) -print | filter_ignore | sort | maybe_chmod_chown
|
||||
|
||||
# We don't handle xattrs.
|
||||
# Maybe check for getfattr/setfattr and use them if they're available?
|
||||
}
|
||||
|
||||
maybe_chmod_chown() {
|
||||
if command -v perl >/dev/null; then
|
||||
perl -ne '
|
||||
BEGIN { $q=chr(39) }
|
||||
sub uidname {
|
||||
my $want=shift;
|
||||
if (exists $uidcache{$want}) {
|
||||
return $uidcache{$want};
|
||||
}
|
||||
my $name=scalar getpwuid($want);
|
||||
return $uidcache{$want}=defined $name ? $name : $want;
|
||||
}
|
||||
sub gidname {
|
||||
my $want=shift;
|
||||
if (exists $gidcache{$want}) {
|
||||
return $gidcache{$want};
|
||||
}
|
||||
my $name=scalar getgrgid($want);
|
||||
return $gidcache{$want}=defined $name ? $name : $want;
|
||||
}
|
||||
chomp;
|
||||
my @stat=stat($_);
|
||||
my $mode = $stat[2];
|
||||
my $uid = $stat[4];
|
||||
my $gid = $stat[5];
|
||||
s/$q/$q"$q"$q/g; # escape single quotes
|
||||
s/^/$q/;
|
||||
s/$/$q/;
|
||||
if ($uid != $>) {
|
||||
printf "maybe chown $q%s$q %s\n", uidname($uid), $_;
|
||||
}
|
||||
if ($gid != $)) {
|
||||
printf "maybe chgrp $q%s$q %s\n", gidname($gid), $_;
|
||||
}
|
||||
printf "maybe chmod %04o %s\n", $mode & 07777, $_;
|
||||
'
|
||||
return $?
|
||||
else
|
||||
# fallback if perl isn't present
|
||||
euid=$(id -u)
|
||||
egid=$(id -g)
|
||||
q="'"
|
||||
while read x; do
|
||||
stat=$(stat -c "%f:%u:%g:%a:%U:%G" $x)
|
||||
IFS=":" read mode uid gid perm uname gname <<EOF
|
||||
$stat
|
||||
EOF
|
||||
x=$q$(echo $x | sed "s/$q/$q\"$q\"$q/")$q
|
||||
if [ $uid -ne $euid ]; then
|
||||
echo maybe chown "'$uname'" $x
|
||||
fi
|
||||
if [ $gid -ne $egid ]; then
|
||||
echo maybe chgrp "'$gname'" $x
|
||||
fi
|
||||
echo maybe chmod 0$perm $x
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
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
|
||||
# may not (the repo is locked for hg).
|
||||
if [ "$VCS" = git ]; then
|
||||
$VCS rm .metadata
|
||||
else
|
||||
rm -f .metadata
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "# Generated by etckeeper. Do not edit." > .etckeeper
|
||||
echo >> .etckeeper
|
||||
|
||||
# Make sure the file is not readable by others, since it can leak
|
||||
# information about contents of non-readable directories in /etc.
|
||||
chmod 700 .etckeeper
|
||||
|
||||
generate_metadata >> .etckeeper
|
||||
|
||||
# stage the file as part of the current commit
|
||||
if [ "$VCS" = git ]; then
|
||||
# this will do nothing if the metadata file is unchanged.
|
||||
git add .etckeeper
|
||||
fi
|
||||
# hg, bzr and darcs add not done, they will automatically
|
||||
# include the file in the current commit
|
||||
fi
|
||||
2
etckeeper/pre-commit.d/README
Normal file
2
etckeeper/pre-commit.d/README
Normal file
@@ -0,0 +1,2 @@
|
||||
This is run by a git pre-commit hook before committing changes to the
|
||||
repository. This can be used for storing metadata, and for sanity checks.
|
||||
Reference in New Issue
Block a user