chiark / gitweb /
git-debpush: Check upstream source is identical in the upstream tag
[dgit.git] / git-debpush
index e2ea2b64adf939a03686db14518ba2a11f12029d..1bfb0936c2e934087b50e4a2f3ec482e0af3cb37 100755 (executable)
@@ -65,14 +65,25 @@ get_file_from_ref () {
 
 failed_check=false
 fail_check () {
 
 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
     else
-        echo >&2 "$us: $*"
+        echo >&2 "$us: $* ('$check' check)"
         failed_check=true
     fi
 }
 
         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
 
 find_last_tag () {
     local prefix=$1
 
@@ -86,10 +97,27 @@ find_last_tag () {
     set -o pipefail
 }
 
     set -o pipefail
 }
 
+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:' \
 # **** 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"
 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
 
 git_tag_opts=()
 pushing=true
-force=false
+force_all=false
+force=""
 distro=debian
 quilt_mode=""
 branch="HEAD"
 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 ;;
     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 ;;
         '--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"
             ;;
 
             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
         '--') shift; break ;;
        *) badusage "unknown option $1" ;;
     esac
@@ -252,7 +293,7 @@ fi
 # ---- UNRELEASED suite
 
 if [ "$target" = "UNRELEASED" ]; then
 # ---- UNRELEASED suite
 
 if [ "$target" = "UNRELEASED" ]; then
-    fail_check "UNRELEASED changelog"
+    fail_check unreleased "UNRELEASED changelog"
 fi
 
 # ---- Pushing dgit view to maintainer view
 fi
 
 # ---- Pushing dgit view to maintainer view
@@ -263,7 +304,7 @@ if ! [ "x$last_debian_tag" = "x" ] && ! [ "x$last_archive_tag" = "x" ]; then
     if ! [ "$last_debian_tag_c" = "$last_archive_tag_c" ] \
             && git merge-base --is-ancestor \
                    "$last_debian_tag" "$last_archive_tag"; then
     if ! [ "$last_debian_tag_c" = "$last_archive_tag_c" ] \
             && git merge-base --is-ancestor \
                    "$last_debian_tag" "$last_archive_tag"; then
-        fail_check \
+        fail_check dgit-view \
 "looks like you might be trying to push the dgit view to the maintainer branch?"
     fi
 fi
 "looks like you might be trying to push the dgit view to the maintainer branch?"
     fi
 fi
@@ -280,7 +321,7 @@ if ! [ "x$last_debian_tag" = "x" ]; then
     trap - EXIT
 
     if ! [ "$prev_target" = "$target" ] && ! [ "$target" = "UNRELEASED" ]; then
     trap - EXIT
 
     if ! [ "$prev_target" = "$target" ] && ! [ "$target" = "UNRELEASED" ]; then
-        fail_check \
+        fail_check suite \
 "last upload targeted $prev_target, now targeting $target; might be a mistake?"
     fi
 fi
 "last upload targeted $prev_target, now targeting $target; might be a mistake?"
     fi
 fi
@@ -290,14 +331,32 @@ fi
 if ! [ "x$upstream_tag" = "x" ] \
         && ! git merge-base --is-ancestor "$upstream_tag" "$branch" \
         && ! [ "$quilt_mode" = "baredebian" ]; then
 if ! [ "x$upstream_tag" = "x" ] \
         && ! git merge-base --is-ancestor "$upstream_tag" "$branch" \
         && ! [ "$quilt_mode" = "baredebian" ]; then
-    fail_check \
+    fail_check upstream-nonancestor \
  "upstream tag $upstream_tag is not an ancestor of $branch; probably a mistake"
 fi
 
  "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
 
 # ---- Summary
 
-if ! $force && $failed_check; then
-    fail "some checks failed; you can override with --force"
+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 ****
 fi
 
 # **** Create the git tag ****