X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=git-debpush;h=1bfb0936c2e934087b50e4a2f3ec482e0af3cb37;hb=e82d9492c0a63d75c96e2ebdbc93300d57927d60;hp=1902fa93f7ff0cab98ba8661efcb9ce0f4435585;hpb=caa1e709a82e10200b3e1cc310a4a40d2212cbc2;p=dgit.git diff --git a/git-debpush b/git-debpush index 1902fa93..1bfb0936 100755 --- a/git-debpush +++ b/git-debpush @@ -35,7 +35,7 @@ set -o pipefail # mode; if there is a previous tag, and no quilt mode provided, assume # same quilt mode as in previous tag created by this script -# ---- Helper functions and variables +# **** Helper functions and variables **** us="$(basename $0)" @@ -65,14 +65,25 @@ get_file_from_ref () { failed_check=false fail_check () { - if $force; then - echo >&2 "$us: warning: $*" + local check=$1; shift + local check_is_forced=false + + case ",$force," in + *",$check,"*) check_is_forced=true ;; + esac + if $force_all || $check_is_forced; then + echo >&2 "$us: warning: $* ('$check' check)" else - echo >&2 "$us: $*" + echo >&2 "$us: $* ('$check' check)" failed_check=true fi } +fail_check_upstream_nonidentical () { + fail_check upstream-nonidentical \ + "the upstream source in tag $upstream_tag is not identical to the upstream source in $branch" +} + find_last_tag () { local prefix=$1 @@ -86,10 +97,27 @@ find_last_tag () { set -o pipefail } -# ---- Parse command line +check_treesame () { + local first=$1 + local second=$2 + shift 2 + + set +e + git diff --exit-code "$first".."$second" -- . "$@" + git_diff_rc=$? + set -e + + if [ $git_diff_rc -le 1 ]; then + return $git_diff_rc + else + fail "'git diff' exited with unexpected code $git_diff_rc" + fi +} + +# **** Parse command line **** getopt=$(getopt -s bash -o 'nfu:' \ - -l 'no-push,force,branch:,remote:,distro:,upstream:,quilt:,gbp,dpm,\ + -l 'no-push,force::,branch:,remote:,distro:,upstream:,quilt:,gbp,dpm,\ baredebian,baredebian+git,baredebian+tarball' \ -n "$us" -- "$@") eval "set - $getopt" @@ -97,7 +125,8 @@ set -e$DGIT_TEST_DEBPUSH_DEBUG git_tag_opts=() pushing=true -force=false +force_all=false +force="" distro=debian quilt_mode="" branch="HEAD" @@ -106,7 +135,7 @@ while true; do case "$1" in '-n'|'--no-push') pushing=false; shift; continue ;; '-u') git_tag_opts+=(-u "$2"); shift 2; continue ;; - '-f'|'--force') force=true; shift; continue ;; + '-f') force_all=true; shift; continue ;; '--gbp') quilt_mode='gbp'; shift; continue ;; '--dpm') quilt_mode='dpm'; shift; continue ;; '--branch') branch=$2; shift 2; continue ;; @@ -121,6 +150,18 @@ while true; do fail "--baredebian+tarball quilt mode not supported" ;; + # we require the long form of the option to skip individual + # checks, not permitting `-f check`, to avoid problems if we + # later want to introduce positional args + '--force') + case "$2" in + '') + force_all=true ;; + *) + force="$force,$2" ;; + esac + shift 2; continue ;; + '--') shift; break ;; *) badusage "unknown option $1" ;; esac @@ -137,10 +178,10 @@ case "$quilt_mode" in *) badusage "invalid quilt mode: $quilt_mode" ;; esac -# ---- Gather git information +# **** Gather git information **** remoteconfigs=() -push_branch=() +to_push=() # Maybe $branch is a symbolic ref. If so, resolve it branchref="$(git symbolic-ref -q $branch || test $? = 1)" @@ -167,7 +208,7 @@ esac case "$branch" in refs/heads/*) b=${branch#refs/heads/} - push_branch+=("$b") + to_push+=("$b") remoteconfigs+=( branch.$b.pushRemote branch.$b.remote ) ;; esac @@ -186,7 +227,7 @@ if $pushing && [ "x$remote" = "x" ]; then fi fi -# ---- Gather source package information +# **** Gather source package information **** temp=$(mktemp -d) trap cleanup EXIT @@ -198,49 +239,6 @@ target=$(cd $temp; dpkg-parsechangelog -SDistribution) rm -rf "$temp" trap - EXIT -# ---- Gather git history information - -last_debian_tag=$(find_last_tag "debian/") -last_archive_tag=$(find_last_tag "archive/debian/") - -# ---- Useful sanity checks - -if [ "$target" = "UNRELEASED" ]; then - fail_check "UNRELEASED changelog" -fi - -if ! [ "x$last_debian_tag" = "x" ] && ! [ "x$last_archive_tag" = "x" ]; then - last_debian_tag_c=$(git rev-parse "$last_debian_tag"^{}) - last_archive_tag_c=$(git rev-parse "$last_archive_tag"^{}) - if ! [ "$last_debian_tag_c" = "$last_archive_tag_c" ] \ - && git merge-base --is-ancestor \ - "$last_debian_tag" "$last_archive_tag"; then - fail_check \ -"looks like you might be trying to push the dgit view to the maintainer branch?" - fi -fi - -if ! [ "x$last_debian_tag" = "x" ]; then - temp=$(mktemp -d) - trap cleanup EXIT - mkdir "$temp/debian" - git cat-file blob "$last_debian_tag":debian/changelog >"$temp/debian/changelog" - prev_target=$(cd $temp; dpkg-parsechangelog -SDistribution) - rm -rf "$temp" - trap - EXIT - - if ! [ "$prev_target" = "$target" ] && ! [ "$target" = "UNRELEASED" ]; then - fail_check \ -"last upload targeted $prev_target, now targeting $target; might be a mistake?" - fi -fi - -if ! $force && $failed_check; then - fail "some checks failed; you can override with --force" -fi - -# ---- Create the git tag - format="$(get_file_from_ref debian/source/format)" case "$format" in '3.0 (quilt)') upstream=true ;; @@ -259,6 +257,11 @@ case "$format" in ;; esac +# **** Gather git history information **** + +last_debian_tag=$(find_last_tag "debian/") +last_archive_tag=$(find_last_tag "archive/debian/") + upstream_info="" if $upstream; then if [ "x$upstream_tag" = x ]; then @@ -282,12 +285,87 @@ if $upstream; then fi upstream_committish=$(git rev-parse "refs/tags/${upstream_tag}"^{}) upstream_info=" upstream-tag=$upstream_tag upstream=$upstream_committish" + to_push+=("$upstream_tag") +fi + +# **** Useful sanity checks **** + +# ---- UNRELEASED suite + +if [ "$target" = "UNRELEASED" ]; then + fail_check unreleased "UNRELEASED changelog" +fi + +# ---- Pushing dgit view to maintainer view + +if ! [ "x$last_debian_tag" = "x" ] && ! [ "x$last_archive_tag" = "x" ]; then + last_debian_tag_c=$(git rev-parse "$last_debian_tag"^{}) + last_archive_tag_c=$(git rev-parse "$last_archive_tag"^{}) + if ! [ "$last_debian_tag_c" = "$last_archive_tag_c" ] \ + && git merge-base --is-ancestor \ + "$last_debian_tag" "$last_archive_tag"; then + fail_check dgit-view \ +"looks like you might be trying to push the dgit view to the maintainer branch?" + fi +fi + +# ---- Targeting different suite + +if ! [ "x$last_debian_tag" = "x" ]; then + temp=$(mktemp -d) + trap cleanup EXIT + mkdir "$temp/debian" + git cat-file blob "$last_debian_tag":debian/changelog >"$temp/debian/changelog" + prev_target=$(cd $temp; dpkg-parsechangelog -SDistribution) + rm -rf "$temp" + trap - EXIT + + if ! [ "$prev_target" = "$target" ] && ! [ "$target" = "UNRELEASED" ]; then + fail_check suite \ +"last upload targeted $prev_target, now targeting $target; might be a mistake?" + fi +fi + +# ---- Upstream tag is not ancestor of $branch + +if ! [ "x$upstream_tag" = "x" ] \ + && ! git merge-base --is-ancestor "$upstream_tag" "$branch" \ + && ! [ "$quilt_mode" = "baredebian" ]; then + fail_check upstream-nonancestor \ + "upstream tag $upstream_tag is not an ancestor of $branch; probably a mistake" fi +# ---- Upstream tag tree nonidentical + +case "$quilt_mode" in + gbp) + check_treesame "$upstream_tag" "$branch" ':!debian' ':!**.gitignore' \ + || fail_check_upstream_nonidentical + ;; + unapplied) + check_treesame "$upstream_tag" "$branch" ':!debian' \ + || fail_check_upstream_nonidentical + ;; +esac + +# ---- Summary + +if $failed_check; then + # We don't mention the --force=check options here as those are + # mainly for use by scripts, or when you already know what check + # is going to fail before you invoke git-debpush. Keep the + # script's terminal output as simple as possible. No "see the + # manpage"! + fail "some check(s) failed; you can pass --force to ignore them" +fi + +# **** Create the git tag **** + # convert according to DEP-14 rules git_version=$(echo $version | tr ':~' '%_' | sed 's/\.(?=\.|$|lock$)/.#/g') debian_tag="$distro/$git_version" +to_push+=("$debian_tag") # If the user didn't supply a quilt mode, look for it in a previous # tag made by this script @@ -320,12 +398,8 @@ $source release $version for $target [dgit please-upload$upstream_info] EOF -# ---- Do a git push +# **** Do a git push **** if $pushing; then - if [ "x$upstream_tag" = "x" ]; then - git push "$remote" "${push_branch[@]}" "$debian_tag" - else - git push "$remote" "${push_branch[@]}" "$debian_tag" "$upstream_tag" - fi + git push "$remote" "${to_push[@]}" fi