diff options
author | Scott Moser <smoser@brickies.net> | 2016-12-01 11:50:55 -0500 |
---|---|---|
committer | Scott Moser <smoser@brickies.net> | 2016-12-01 16:56:03 -0500 |
commit | bead19184774c586c071c86f430d9c9ac64d0dd7 (patch) | |
tree | 00bc284b9e4903d6c5dfdb20e61b080d9e46761e | |
parent | 3994f5a0d5ba8b4702a51373c3504ab1035a8d9d (diff) | |
download | vyos-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.source | 6 | ||||
-rwxr-xr-x | debian/cherry-pick | 187 | ||||
-rwxr-xr-x | debian/cherry-pick-rev | 45 | ||||
-rwxr-xr-x | debian/new-upstream-snapshot | 38 |
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" |