diff options
-rwxr-xr-x | commit.d/10vcs-test | 2 | ||||
-rw-r--r-- | commit.d/30darcs-add | 14 | ||||
-rwxr-xr-x | commit.d/50vcs-commit | 6 | ||||
-rw-r--r-- | debian/changelog | 6 | ||||
-rw-r--r-- | debian/control | 16 | ||||
-rwxr-xr-x | etckeeper | 3 | ||||
-rw-r--r-- | etckeeper.conf | 4 | ||||
-rwxr-xr-x | init.d/40vcs-init | 3 | ||||
-rwxr-xr-x | init.d/50vcs-ignore | 22 | ||||
-rwxr-xr-x | init.d/50vcs-perm | 2 | ||||
-rwxr-xr-x | init.d/50vcs-pre-commit-hook | 15 | ||||
-rw-r--r-- | init.d/60darcs-deleted-symlinks | 48 | ||||
-rwxr-xr-x | init.d/70vcs-add | 11 | ||||
-rwxr-xr-x | pre-commit.d/20warn-hardlinks | 4 | ||||
-rwxr-xr-x | pre-commit.d/20warn-special-file | 4 | ||||
-rwxr-xr-x | pre-commit.d/30store-metadata | 58 | ||||
-rwxr-xr-x | unclean.d/50test | 2 |
17 files changed, 200 insertions, 20 deletions
diff --git a/commit.d/10vcs-test b/commit.d/10vcs-test index 1fd4226..e33d734 100755 --- a/commit.d/10vcs-test +++ b/commit.d/10vcs-test @@ -12,4 +12,6 @@ elif [ "$VCS" = hg ] && [ ! -d .hg ]; then not_enabled_warning elif [ "$VCS" = bzr ] && [ ! -d .bzr ]; then not_enabled_warning +elif [ "$VCS" = darcs ] && [ ! -d _darcs ]; then + not_enabled_warning fi diff --git a/commit.d/30darcs-add b/commit.d/30darcs-add new file mode 100644 index 0000000..98be4bf --- /dev/null +++ b/commit.d/30darcs-add @@ -0,0 +1,14 @@ +#!/bin/sh +set -e + +if [ "$VCS" = darcs ] && [ -d _darcs ]; then + rc=0 + res=$( darcs add -qr . 2>&1 ) || rc=$? + if test $rc -ne 0; then + if ! test $rc -eq 2 -a "${res%No files were added}" != "$res"; then + printf "%s" "$res" + echo "etckeeper warning: darcs add failed" >&2 + fi + fi + unset rc res +fi diff --git a/commit.d/50vcs-commit b/commit.d/50vcs-commit index 8a0c0b6..1f4ab03 100755 --- a/commit.d/50vcs-commit +++ b/commit.d/50vcs-commit @@ -32,4 +32,10 @@ elif [ "$VCS" = bzr ] && [ -d .bzr ]; then else bzr commit $BZR_COMMIT_OPTIONS fi +elif [ "$VCS" = darcs ] && [ -d _darcs ]; then + logfile="$( mktemp -t etckeeper-$VCS.XXXXXXXXXX )" + printf "%b" "$message" > "$logfile" + darcs record $DARCS_COMMIT_OPTIONS --logfile="$logfile" + rm -f "$logfile" + unset logfile fi diff --git a/debian/changelog b/debian/changelog index bb3ddb6..664cdf1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +etckeeper (0.28) UNRELEASED; urgency=low + + * Support darcs. Thanks to Gian Piero Carrubba. Closes: #510032 + + -- Joey Hess <joeyh@debian.org> Wed, 04 Feb 2009 21:44:40 -0500 + etckeeper (0.27) unstable; urgency=low * Use SUDO_USER as the committer if set. Closes: #498739 diff --git a/debian/control b/debian/control index 1a3e6ff..5d0b1f1 100644 --- a/debian/control +++ b/debian/control @@ -11,14 +11,14 @@ Homepage: http://kitenet.net/~joey/code/etckeeper/ Package: etckeeper Architecture: all Section: admin -Depends: git-core (>= 1:1.5.4) | mercurial | bzr (>= 1.4~), ${misc:Depends} +Depends: git-core (>= 1:1.5.4) | mercurial | bzr (>= 1.4~) | darcs, ${misc:Depends} Conflicts: bzr (<< 1.4~) XB-Python-Version: ${python:Versions} -Description: store /etc in git, mercurial, or bzr +Description: store /etc in git, mercurial, bzr or darcs The etckeeper program is a tool to let /etc be stored in a git, mercurial, - or bzr repository. It hooks into APT to automatically commit changes made to - /etc during package upgrades. It tracks file metadata that - version control systems do not normally support, but that is important for - /etc, such as the permissions of /etc/shadow. It's quite modular and - configurable, while also being simple to use if you understand the basics of - working with version control. + bzr or darcs repository. It hooks into APT to automatically commit changes + made to /etc during package upgrades. It tracks file metadata that version + control systems do not normally support, but that is important for /etc, such + as the permissions of /etc/shadow. It's quite modular and configurable, while + also being simple to use if you understand the basics of working with version + control. @@ -26,6 +26,9 @@ fi if [ ! -z "$BZR_COMMIT_OPTIONS" ]; then export BZR_COMMIT_OPTIONS fi +if [ ! -z "$DARCS_COMMIT_OPTIONS" ]; then + export DARCS_COMMIT_OPTIONS +fi if [ ! -z "$HIGHLEVEL_PACKAGE_MANAGER" ]; then export HIGHLEVEL_PACKAGE_MANAGER diff --git a/etckeeper.conf b/etckeeper.conf index f1438ab..11344e1 100644 --- a/etckeeper.conf +++ b/etckeeper.conf @@ -2,6 +2,7 @@ # VCS="hg" VCS="git" # VCS="bzr" +# VCS="darcs" # Options passed to git commit when run by etckeeper. #GIT_COMMIT_OPTIONS="" @@ -12,6 +13,9 @@ VCS="git" # Options passed to bzr commit when run by etckeeper. #BZR_COMMIT_OPTIONS="" +# Options passed to darcs commit when run by etckeeper. +#DARCS_COMMIT_OPTIONS="" + # Uncomment to avoid etckeeper committing existing changes to # /etc before installation. It will cancel the installation, # so you can commit the changes by hand. diff --git a/init.d/40vcs-init b/init.d/40vcs-init index bf2b03e..3c7a3bb 100755 --- a/init.d/40vcs-init +++ b/init.d/40vcs-init @@ -11,4 +11,7 @@ elif [ "$VCS" = hg ] && [ ! -e .hg ]; then elif [ "$VCS" = bzr ] && [ ! -e .bzr ]; then bzr init bzr nick "$(hostname) /etc repository" +elif [ "$VCS" = darcs ] && [ ! -e _darcs ]; then + darcs initialize + echo "$(hostname) /etc repository" > _darcs/prefs/motd fi diff --git a/init.d/50vcs-ignore b/init.d/50vcs-ignore index 43c245d..5c7aa78 100755 --- a/init.d/50vcs-ignore +++ b/init.d/50vcs-ignore @@ -7,6 +7,8 @@ elif [ "$VCS" = hg ] && [ ! -e .hgignore ]; then file=.hgignore elif [ "$VCS" = bzr ] && [ ! -e .bzrignore ]; then file=.bzrignore +elif [ "$VCS" = darcs ] && [ ! -e .darcsignore ]; then + file=.darcsignore fi if [ -z "$file" ] || [ -e "$file" ]; then @@ -40,9 +42,29 @@ ignore() { fi echo "$glob" >> $file ;; + darcs) + # darcs doesn't understand globs, so we need to translate + # them into regexs. Not a complete converter, but suitable + # for given globs. + if [ "${glob%\*}" != "$glob" ]; then + glob="${glob%\*}" + else + glob="$glob"'($|/)' + fi + if [ "${glob#\*}" != "$glob" ]; then + glob="${glob#\*}" + else + glob='(^|/)'"$glob" + fi + glob="$( printf %s $glob | sed -e 's/\./\\./g;s/\*/[^\/]*/g;' )" + echo "$glob" >> $file esac } +if [ "$VCS" = darcs ]; then + darcs setpref boringfile .darcsignore +fi + if [ "$LOWLEVEL_PACKAGE_MANAGER" = dpkg ]; then comment "new and old versions of conffiles, stored by dpkg" ignore "*.dpkg-*" diff --git a/init.d/50vcs-perm b/init.d/50vcs-perm index f9a6b8c..4dd080b 100755 --- a/init.d/50vcs-perm +++ b/init.d/50vcs-perm @@ -7,4 +7,6 @@ elif [ "$VCS" = hg ]; then chmod 700 .hg elif [ "$VCS" = bzr ]; then chmod 700 .bzr +elif [ "$VCS" = darcs ]; then + chmod 700 _darcs fi diff --git a/init.d/50vcs-pre-commit-hook b/init.d/50vcs-pre-commit-hook index de496fe..06d433b 100755 --- a/init.d/50vcs-pre-commit-hook +++ b/init.d/50vcs-pre-commit-hook @@ -29,4 +29,19 @@ precommit = etckeeper pre-commit -d `pwd` EOF fi ;; + darcs) + if [ -e _darcs/prefs/defaults ]; then + if ! ( grep -q "record prehook etckeeper pre-commit" _darcs/prefs/defaults && + grep -q "whatsnew prehook etckeeper pre-commit" _darcs/prefs/defaults ); then + echo "etckeeper warning: _darcs/prefs/defaults needs to be manually modified to run: etckeeper pre-commit -d `pwd`" >&2 + fi + else + cat >_darcs/prefs/defaults <<EOF +record prehook etckeeper pre-commit -d `pwd` +record run-prehook +whatsnew prehook etckeeper pre-commit -d `pwd` +whatsnew run-prehook +EOF + fi + ;; esac diff --git a/init.d/60darcs-deleted-symlinks b/init.d/60darcs-deleted-symlinks new file mode 100644 index 0000000..8d10d56 --- /dev/null +++ b/init.d/60darcs-deleted-symlinks @@ -0,0 +1,48 @@ +#!/bin/sh +set -e + +filter_ignore() { + if [ "$VCS" = darcs ]; then + ignorefile=.darcsignore + fi + + if [ "$VCS" = darcs ] && [ -e "$ignorefile" ]; then + # Spaces embedded into patterns would break it. + # But really, why would anyone want to use ' ' instead of '\s' ? + #patterns=$( grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" | xargs -n 1 printf " -e %s" ) + #grep -Ev $patterns + #unset patterns + # Alternative using a temp file + patternsfile="$( mktemp -t etckeeper-$VCS.XXXXXXXXXX )" + grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" > "$patternsfile" || true + grep -Evf "$patternsfile" + rm -f "$patternsfile" + unset patternsfile + else + cat - + fi +} + + +if [ "$VCS" = darcs ];then + NOVCS='. -wholename ./.git -prune -o -wholename ./.bzr -prune -o -wholename ./.hg -prune -o -wholename ./_darcs -prune -o' + + # We assume that if .etckeeper is empty this is the first run + if [ -s .etckeeper ]; then + linksindex="$( mktemp -t etckeeper-$VCS.XXXXXXXXXX )" + grep '^ln -s' .etckeeper | while IFS="'" read n n n link n; do + printf "%s\n" "$link" >> "$linksindex" + done + + # Warn about symbolic links that shouldn't exist + if links=$( find $NOVCS -type l -print | filter_ignore | grep -vFf "$linksindex" ); then + printf "%s\n%s\n" \ + "The following symbolic links should not exist:" \ + "$links" >&2 + fi + + rm -f "$linksindex" + unset links linksindex + fi + +fi diff --git a/init.d/70vcs-add b/init.d/70vcs-add index e6ab3d1..9a9ec45 100755 --- a/init.d/70vcs-add +++ b/init.d/70vcs-add @@ -13,4 +13,15 @@ elif [ "$VCS" = bzr ]; then if ! bzr add .; then echo "etckeeper warning: bzr add failed" >&2 fi +elif [ "$VCS" = darcs ]; then + # Don't warn if all the files were already added. + rc=0 + res=$( darcs add -qr . 2>&1 ) || rc=$? + if test $rc -ne 0; then + if ! test $rc -eq 2 -a "${res%No files were added}" != "$res"; then + printf "%s" "$res" + echo "etckeeper warning: darcs add failed" >&2 + fi + fi + unset rc res fi diff --git a/pre-commit.d/20warn-hardlinks b/pre-commit.d/20warn-hardlinks index c1fd8f7..008e2f1 100755 --- a/pre-commit.d/20warn-hardlinks +++ b/pre-commit.d/20warn-hardlinks @@ -1,8 +1,8 @@ #!/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 [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ] || [ "$VCS" = darcs ]; then + hardlinks=$(find -type f -not -links 1 | grep -v '/\(.git\|.hg\|.bzr\|_darcs\)/' ) || true if [ -n "$hardlinks" ]; then echo "etckeeper warning: hardlinked files could cause problems with $VCS:" >&2 echo "$hardlinks" >&2 diff --git a/pre-commit.d/20warn-special-file b/pre-commit.d/20warn-special-file index 5712bc5..665a3ce 100755 --- a/pre-commit.d/20warn-special-file +++ b/pre-commit.d/20warn-special-file @@ -1,8 +1,8 @@ #!/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 [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ] || [ "$VCS" = darcs ]; then + special=$(find -not -type d -not -type f -not -type l | grep -v '/\(.git\|.hg\|.bzr\|_darcs\)/') || true if [ -n "$special" ]; then echo "etckeeper warning: special files could cause problems with $VCS:" >&2 echo "$special" >&2 diff --git a/pre-commit.d/30store-metadata b/pre-commit.d/30store-metadata index a481c8f..0416ec6 100755 --- a/pre-commit.d/30store-metadata +++ b/pre-commit.d/30store-metadata @@ -14,6 +14,28 @@ filter_unknown() { done } +filter_ignore() { + if [ "$VCS" = darcs ]; then + ignorefile=.darcsignore + fi + + if [ "$VCS" = darcs ] && [ -e "$ignorefile" ]; then + # Spaces embedded into patterns would break it. + # But really, why would anyone want to use ' ' instead of '\s' ? + #patterns=$( grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" | xargs -n 1 printf " -e %s" ) + #grep -Ev $patterns + #unset patterns + # Alternative using a temp file + patternsfile="$( mktemp -t etckeeper-$VCS.XXXXXXXXXX )" + grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" > "$patternsfile" || true + grep -Evf "$patternsfile" + rm -f "$patternsfile" + unset patternsfile + else + cat - + fi +} + generate_metadata() { # This function generates the script commands to fix any files # that aren't owner=root, group=root, or mode=0644 or 0755. @@ -24,7 +46,11 @@ generate_metadata() { # We maintain the permissions on 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='. -wholename ./.git -prune -o -wholename ./.bzr -prune -o -wholename ./.hg -prune -o -wholename ./_darcs -prune -o' # Keep the sort order the same at all times. LC_COLLATE=C @@ -33,10 +59,19 @@ 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/ | + find $NOVCS -type d -empty -print | sort | sed -e "s/^/mkdir -p '/" -e "s/\$/'/" 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" "$dest" "$link" + done + fi + # Find all files and directories that don't have the current user as the owner find $NOVCS \! -user "$USER" -exec stat --format="maybe chown %U '{}'" {} \; \ | sort | filter_unknown 'maybe chown' owner @@ -48,16 +83,23 @@ generate_metadata() { find $NOVCS -type d \! -perm 0755 \ -exec stat --format="maybe chmod %a '{}'" {} \; | sort - # 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="maybe chmod %a '{}'" {} \; | sort + if [ "$VCS" = darcs ]; then + # Find all files that aren't 0644 (darcs doesn't maintain + # the executable bit). + find $NOVCS -type f \! -perm 0644 \ + -exec stat --format="maybe chmod %a '{}'" {} \; | sort + else + # 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="maybe chmod %a '{}'" {} \; | sort + fi # 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 @@ -83,6 +125,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 diff --git a/unclean.d/50test b/unclean.d/50test index 9dfefc3..84e6be7 100755 --- a/unclean.d/50test +++ b/unclean.d/50test @@ -7,4 +7,6 @@ elif [ "$VCS" = hg ]; then [ -d .hg ] && ! hg status 2>&1 | wc -l | grep -q "^0$" elif [ "$VCS" = bzr ]; then [ -d .bzr ] && ! bzr status 2>/dev/null | wc -l | grep -q "^0$" +elif [ "$VCS" = darcs ]; then + [ -d _darcs ] && darcs whatsnew -l >/dev/null fi |