summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Moser <smoser@brickies.net>2016-12-01 11:50:55 -0500
committerScott Moser <smoser@brickies.net>2016-12-01 16:56:03 -0500
commitbead19184774c586c071c86f430d9c9ac64d0dd7 (patch)
tree00bc284b9e4903d6c5dfdb20e61b080d9e46761e
parent3994f5a0d5ba8b4702a51373c3504ab1035a8d9d (diff)
downloadvyos-cloud-init-bead19184774c586c071c86f430d9c9ac64d0dd7.tar.gz
vyos-cloud-init-bead19184774c586c071c86f430d9c9ac64d0dd7.zip
debian/cherry-pick: add cherry picking tool
* Add a cherry picking tool. * add support for removing cherry picks to new-upstream-snapshot. * remove bzr version of script debian/cherry-pick-rev
-rw-r--r--debian/README.source6
-rwxr-xr-xdebian/cherry-pick187
-rwxr-xr-xdebian/cherry-pick-rev45
-rwxr-xr-xdebian/new-upstream-snapshot38
4 files changed, 230 insertions, 46 deletions
diff --git a/debian/README.source b/debian/README.source
index 86bcf530..df79a3eb 100644
--- a/debian/README.source
+++ b/debian/README.source
@@ -21,3 +21,9 @@ Patches in debian/patches are stored un-applied.
To pull a new upstream snapshot:
./debian/new-upstream-snapshot ../trunk
+
+== Cherry Pick ==
+To cherry pick an upstream commit:
+ ./debian/cherry-pick <hash>
+
+That will add a patch to debian/patches/ and debian/patches/series.
diff --git a/debian/cherry-pick b/debian/cherry-pick
new file mode 100755
index 00000000..0ba2f19d
--- /dev/null
+++ b/debian/cherry-pick
@@ -0,0 +1,187 @@
+#!/bin/bash
+
+VERBOSITY=0
+TEMP_D=""
+CR=$'\n'
+
+error() { echo "$@" 1>&2; }
+fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
+
+Usage() {
+ cat <<EOF
+Usage: ${0##*/} [ options ] <<ARGUMENTS>>
+
+ Cherry pick a patch into debian/patches.
+ Useful to grab an upstream commit to the current packaging branch.
+
+ options:
+ -h | --help show help
+EOF
+}
+
+bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; return 1; }
+cleanup() {
+ [ -z "${TEMP_D}" -o ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
+}
+
+debug() {
+ local level=${1}; shift;
+ [ "${level}" -gt "${VERBOSITY}" ] && return
+ error "${@}"
+}
+
+shorten() {
+ local name="$1" len="70"
+ while [ "${#name}" -gt "$len" ]; do
+ name="${name%-*}"
+ done
+ _RET="$name"
+}
+
+print_commit() {
+ local subject="$1" author="$2" bugs="$3" aname=""
+ aname=${author% <*}
+ echo "$subject${bugs:+ (LP: ${bugs})}"
+}
+
+print_bugs() {
+ local subject="$1" author="$2" bugs="$3" aname=""
+ echo "$bugs"
+}
+
+git_log_to_dch() {
+ local line="" commit="" lcommit="" bugs=""
+ local printer="${1:-print_commit}"
+ while :; do
+ read line || break
+ case "$line" in
+ commit\ *)
+ if [ -n "$commit" ]; then
+ "$printer" "$subject" "$author" "$bugs"
+ fi
+ commit=${line#*: }
+ bugs=""
+ author=""
+ subject=""
+ ;;
+ Author:*) author="${line#Author: }";;
+ LP:*) bugs="${bugs:+${bugs}, }${line#*: }";;
+ "") [ -z "$subject" ] && read subject;;
+ esac
+ done
+ if [ -n "$commit" ]; then
+ "$printer" "$subject" "$author" "$bugs"
+ fi
+}
+
+main() {
+ local short_opts="ho:v"
+ local long_opts="help,verbose"
+ local getopt_out=""
+ getopt_out=$(getopt --name "${0##*/}" \
+ --options "${short_opts}" --long "${long_opts}" -- "$@") &&
+ eval set -- "${getopt_out}" ||
+ { bad_Usage; return; }
+
+ local cur="" next=""
+
+ while [ $# -ne 0 ]; do
+ cur="$1"; next="$2";
+ case "$cur" in
+ -h|--help) Usage ; exit 0;;
+ -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
+ --) shift; break;;
+ esac
+ shift;
+ done
+
+ [ -n "$TEMP_D" ] ||
+ TEMP_D=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX") ||
+ { error "failed to make tempdir"; return 1; }
+ trap cleanup EXIT
+
+ [ $# -gt 0 ] || { bad_Usage "must provide commit-ish"; return; }
+
+ local r="" commit_in="$1" chash="" shash="" sname="" fname="" cur_br=""
+ cur_br=$(git rev-parse --abbrev-ref HEAD) ||
+ { error "failed to get current branch"; return 1; }
+ chash=$(git show --quiet "--pretty=format:%H" "${commit_in}") ||
+ { error "failed git show $commit_in"; return 1; }
+
+ if git merge-base --is-ancestor "$chash" HEAD; then
+ error "current branch '$cur_br' already contains $commit_in ($chash)"
+ return 1
+ fi
+
+ out=$(git show --quiet "--pretty=format:%h %f" "$chash") ||
+ { error "failed git show $chash"; return 1; }
+
+ shash=${out% *}
+ sname=${out#* }
+ longname="cpick-$shash-$sname"
+ shorten "$longname"
+ fname="$_RET"
+
+ [ -d debian/patches ] || mkdir -p debian/patches ||
+ { error "failed to make debian/patches"; return 1; }
+
+ local series="debian/patches/series" fpath="debian/patches/$fname"
+ if [ -e "$series" ] && out=$(grep -- "-${shash}-" "$series"); then
+ error "$chash already exists in $series"
+ error " $out"
+ return 1
+ fi
+
+ if [ -e "$series" ]; then
+ if out=$(quilt applied 2>&1); then
+ error "there are quilt patches applied!"
+ error "$out"
+ return 1
+ fi
+ fi
+
+ git show --no-decorate "$chash" > "$fpath" ||
+ { error "failed git show $chash > $fpath"; return 1; }
+
+ echo "$fname" >> "$series" ||
+ { error "failed to write to $series"; return 1; }
+
+ quilt push "$fname" ||
+ { error "patches do not cleanly apply"; return 1; }
+ quilt refresh && quilt pop -a ||
+ { error "failed to refresh or pop quilt"; return 1; }
+
+ local message=""
+ message=$(git_log_to_dch < "$fpath") ||
+ { error "failed getting log entry from $fpath"; return 1; }
+ dch -i "cherry-pick $shash: $message"
+
+ dch -e || {
+ r=$?;
+ error "dch -e exited $r";
+ return $r;
+ }
+
+ local commit_files=""
+ commit_files=( debian/changelog "$series" "$fpath" )
+ git diff HEAD "${commit_files[@]}"
+
+ echo -n "Commit this change? (Y/n): "
+ read answer || fail "failed to read answer"
+ case "$answer" in
+ n|[Nn][oO]) exit 1;;
+ esac
+
+ bugs=$(git_log_to_dch print_bugs < "$fpath")
+ msg="cherry pick $shash${bugs:+${CR}${CR}LP: ${bugs}}"
+ git add "$series" "$fpath" ||
+ { error "failed to git add $series $fpath"; return 1; }
+
+ git commit -m "$msg" "${commit_files[@]}" ||
+ fail "failed to commit '$msg'"
+
+ return 0
+}
+
+main "$@"
+# vi: ts=4 expandtab
diff --git a/debian/cherry-pick-rev b/debian/cherry-pick-rev
deleted file mode 100755
index 09f60d12..00000000
--- a/debian/cherry-pick-rev
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-Usage() {
- cat <<EOF
-Usage: ${0##*/} repo revno name
- cherry pick revno from trunk branch
-
- This takes care of getting the patch and pulling it into the local
- directory.
-
- End result is modified:
- debian/patches/\${revno}-\${name}
- debian/patches/series
-EOF
-}
-
-[ $# -eq 3 ] || { Usage 1>&2; exit 1; }
-[ "$1" = "--help" -o "$1" = "-h" ] && { Usage; exit 0; }
-
-repo=${1}
-revno=${2}
-name=${3}
-
-name=${name%.patch}
-name=${name%.diff}
-
-fname="${name}.patch"
-
-( cd "${repo}" && bzr log -r${revno}..${revno} &&
- bzr diff -p1 -r$((${revno}-1))..${revno} ) |
- filterdiff --exclude "*/ChangeLog" |
- quilt import -P "${fname}" /dev/stdin
-
-[ $? -eq 0 ] || { echo "failed"; exit 1; }
-
-cat <<EOF
-now,
- quilt push
- quilt refresh
- rm -f .pc/${fname}/.timestamp
- files="\$(quilt files ${fname}) debian/patches/series debian/patches/${fname} .pc/${fname} .pc/applied-patches"
- bzr add \$files
- dch --append "${name} (cherry pick $revno)"
- dch --edit # improve the entry
- debcommit $files
-EOF
diff --git a/debian/new-upstream-snapshot b/debian/new-upstream-snapshot
index ef7510c2..6240de0d 100755
--- a/debian/new-upstream-snapshot
+++ b/debian/new-upstream-snapshot
@@ -1,6 +1,8 @@
#!/bin/sh
TEMP_D=""
+CR='
+'
error() { echo "$@" 1>&2; }
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
Usage() {
@@ -53,6 +55,7 @@ case "$cur_branch" in
*) fail "You are on branch '$cur_branch', expect to be on ubuntu/*";;
esac
+TEMP_D=$(mktemp -d) || fail "failed mktemp"
trap cleanup EXIT
prev_pkg_ver=$(dpkg-parsechangelog --show-field Version) ||
@@ -75,9 +78,42 @@ if [ "${prev_upstream_ver}" = "${new_upstream_ver}" ]; then
exit 0
fi
+dpseries="debian/patches/series"
+if [ -e $dpseries ]; then
+ drops=""
+ while read bname extra; do
+ case "$bname" in
+ cpick-*)
+ commit=${bname#cpick-}
+ commit=${commit%%-*}
+ echo "bname=$bname commit=${commit}" 1>&2
+ if git merge-base --is-ancestor "$commit" "$from_ref"; then
+ drops="${drops} debian/patches/$bname"
+ fi
+ ;;
+ *) echo "$bname${extra:+ ${extra}}";;
+ esac
+ done < $dpseries > "${TEMP_D}/series"
+ drops=${drops# }
+ if [ -n "$drops" ]; then
+ cp "${TEMP_D}/series" "$dpseries" ||
+ fail "failed copying to $dpseries"
+ if [ ! -s $dpseries ]; then
+ git rm --force "$dpseries" ||
+ fail "failed removing empty $dpseries: git rm $dpseries"
+ fi
+ msg="drop cherry picks before merge from ${from_ref} at $new_upstream_ver"
+ msg="$msg${CR}${CR}drop the following cherry picks:"
+ for file in $drops; do
+ git rm "$file" || fail "failed to git rm $file"
+ msg="${msg}$CR $file"
+ done
+ git commit -m "$msg" "$dpseries" $drops
+ fi
+fi
+
git merge "${from_ref}" -m "merge from $from_ref at $new_upstream_ver" ||
fail "failed: git merge ${from_ref} -m 'merge from $from_ref ..'"
-TEMP_D=$(mktemp -d) || fail "failed mktemp"
clog="${TEMP_D}/changelog"
gitlog="${TEMP_D}/gitlog"