ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/scripts/autopick.sh b/scripts/autopick.sh
new file mode 100755
index 0000000..dc1cf4e
--- /dev/null
+++ b/scripts/autopick.sh
@@ -0,0 +1,107 @@
+#!/bin/bash
+set -e
+get_patch_id_commit_id_pairs() {
+ git log "$@" --pretty=tformat:'COMMITm@g1c %H %al %as %f%n%B' | awk 'function p(){if(h){print(d?d:c?c:g?g:(a":"t":"s)),h}};$1=="COMMITm@g1c"{p();h=$2;a=$3;t=$4;s=$5;c=d=g="";next};$1=="Differential"&&$2=="Revision:"{d=$3;sub("http.*/","",d);next};$1=="Change-Id:"{c=$1$2;next};$1=="git-svn-id:"{g=$2;next};END{p()}'
+}
+
+if [ -z "$1" ]; then
+ echo "Usage: `basename "$0"` branch_to_auto_pick_from"
+ exit
+fi
+FROM_BRANCH="$1"
+TO_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
+if [ -z "$TO_BRANCH" ]; then
+ echo "Please git checkout to a branch first"
+ exit 1
+fi
+
+echo "Computing merge base from $FROM_BRANCH to $TO_BRANCH ..."
+MERGE_BASE="$(git merge-base --all "$FROM_BRANCH" "$TO_BRANCH")"
+if [ -z "$MERGE_BASE" ]; then
+ echo "Failed to get merge base"
+ exit 1
+elif [ $(wc -l <<< "$MERGE_BASE") -gt 1 ]; then
+ echo "Git tree with cross merge not supported"
+ exit 1
+fi
+echo "Merge base is $(get_patch_id_commit_id_pairs $MERGE_BASE^..$MERGE_BASE)"
+
+echo -n "Getting patch list on $FROM_BRANCH ... "
+declare -A MAP_FROM_PATCHES
+REV_LIST_FROM_PATCHES=
+while read c d; do
+ if [ -n "$(exec 2>/dev/null; echo ${MAP_FROM_PATCHES[$c]})" ]; then
+ echo "Duplicate patch name found for $c $d ${MAP_FROM_PATCHES[$c]}"
+ d="$d ${MAP_FROM_PATCHES[$c]}"
+ fi
+ MAP_FROM_PATCHES[$c]="$d"
+ REV_LIST_FROM_PATCHES="$c
+$REV_LIST_FROM_PATCHES"
+done < <(get_patch_id_commit_id_pairs "$MERGE_BASE..$FROM_BRANCH")
+echo "${#MAP_FROM_PATCHES[@]} patches"
+
+echo -n "Getting patch list on $TO_BRANCH ... "
+declare -A MAP_TO_PATCHES
+declare -A MAP_TO_PATCHES_DUP
+while read c d; do
+ if [ -n "$(exec 2>/dev/null; echo ${MAP_TO_PATCHES[$c]})" ]; then
+ echo "Duplicate patch name found for $c $d ${MAP_TO_PATCHES[$c]}"
+ d="$d ${MAP_TO_PATCHES[$c]}"
+ MAP_TO_PATCHES_DUP[$c]="$d"
+ fi
+ MAP_TO_PATCHES[$c]="$d"
+done < <(get_patch_id_commit_id_pairs "$MERGE_BASE..$TO_BRANCH")
+echo "${#MAP_TO_PATCHES[@]} patches"
+for d in ${MAP_TO_PATCHES_DUP[@]}; do
+ HASH="$(git diff --binary $d^..$d | sha1sum | cut -d ' ' -f 1)"
+ eval "HAS_$HASH=true"
+done
+
+echo "Computing patches to cherry-pick ..."
+PATCHES_TO_PICK=
+while read c; do
+ if [ -z "$c" ]; then
+ continue
+ fi
+ if [ -z "$(exec 2>/dev/null; echo ${MAP_TO_PATCHES[$c]})" ] || [ ${#MAP_FROM_PATCHES[$c]} -ne ${#MAP_TO_PATCHES[$c]} ]; then
+ echo -ne "$c\t"
+ if [[ "${MAP_FROM_PATCHES[$c]}" == *" "* ]]; then
+ if [ -z "$(exec 2>/dev/null; echo ${MAP_TO_PATCHES_DUP[$c]})" ]; then
+ for d in ${MAP_TO_PATCHES[$c]}; do
+ HASH="$(git diff --binary $d^..$d | sha1sum | cut -d ' ' -f 1)"
+ eval "HAS_$HASH=true"
+ done
+ fi
+ for d in ${MAP_FROM_PATCHES[$c]}; do
+ if [ -z "$(eval echo "\${VISITED_$d}")" ]; then
+ break
+ fi
+ done
+ if [ -n "$(eval echo "\${VISITED_$d}")" ]; then
+ echo "All patches visited for $c: ${MAP_FROM_PATCHES[$c]}"
+ exit 1
+ fi
+ eval "VISITED_$d=true"
+ HASH="$(git diff --binary $d^..$d | sha1sum | cut -d ' ' -f 1)"
+ if [ -n "$(eval echo "\${HAS_$HASH}")" ]; then
+ echo "$d skipped"
+ continue
+ fi
+ c="$c-$HASH"
+ MAP_FROM_PATCHES[$c]="$d"
+ fi
+ echo "${MAP_FROM_PATCHES[$c]}"
+ PATCHES_TO_PICK="$PATCHES_TO_PICK
+$c"
+ fi
+done <<< "$REV_LIST_FROM_PATCHES"
+while read c; do
+ if [ -z "$c" ]; then
+ continue
+ fi
+ d="${MAP_FROM_PATCHES[$c]}"
+ echo "Cherry-picking $d for $c ..."
+ git cherry-pick "$d"
+done <<< "$PATCHES_TO_PICK"
+
+echo "Done"