X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=do_merge;h=d7ecb2f06c373da945bd450740172ec210b4b1d8;hb=HEAD;hp=829340135074150ea93ccb6a35fd7993fe1a6dfb;hpb=289ab26c1f6db8510ca7537e53417ffd1b7a1a08;p=next-scripts diff --git a/do_merge b/do_merge index 8293401..34bb2f7 100755 --- a/do_merge +++ b/do_merge @@ -1,24 +1,30 @@ -#!/bin/bash +#!/bin/sh no_build=false start_from="" -[ "$1" = "-n" ] && { - shift - no_build=true -} -[ "$1" = "-s" ] && { - shift - start_from="$1" - [ -z "$start_from" ] && { - echo "-s requires a start tree" 1>&2 +while getopts 'ns:' opt; do + case "$opt" in + n) + no_build=true + ;; + s) + if [ -f "$SHA1_FILE" ]; then + printf '%s: %s exists, so -s is invalid\n' "$0" "$SHA1_FILE" 1>&2 + exit 1 + fi + start_from="$OPTARG" + ;; + *) exit 1 - } - shift -} + ;; + esac +done +shift $((OPTIND - 1)) -tool_dir=$(dirname "$0") -. "$tool_dir/common.sh" +tools_dir=$(dirname "$0") +. "$tools_dir/common.sh" +. "$tools_dir/check_dups.sh" log() { @@ -27,178 +33,180 @@ log() execute() { - log "$" "$@" - "$@" 2>&1 | tee -a "$LOG_FILE" - return "${PIPESTATUS[0]}" + log '$' "$@" + _out="$( "$@" 2>&1 )" + _err=$? + echo "$_out" | tee -a "$LOG_FILE" + return "$_err" } -do_rebase() +report() { - rbase=${1#*/} - rbase="$2/${rbase%%:*}" - rtop="$2/${1#*:}" - rbid=$(git rev-parse "$rbase") - rtid=$(git rev-parse "$rtop") - [ "$rbid" = "$rtid" ] && { - echo Empty tree - return - } - [ "$(git rev-list HEAD..$rtop)" ] || { - echo Already merged - return - } - execute git clone -s -l -n -q . ../rebase-tmp || { - echo Clone failed 1>&2 - bash -i || exit - } - log '$' cd ../rebase-tmp - cd ../rebase-tmp - execute git fetch --no-tags ../next "refs/remotes/$rtop:$rtop" || { - echo Fetch of top failed 1>&2 - bash -i || exit - } - execute git fetch --no-tags ../next "refs/remotes/$rbase:$rbase" || { - echo Fetch of base failed 1>&2 - bash -i || exit - } - execute git checkout "$rtop" || { - echo Checkout of top failed 1>&2 - bash -i || exit - } - execute git rebase --onto master "$rbase" || { - echo Rebase failed 1>&2 - bash -i || exit - } - log '$' cd ../next - cd ../next - execute git pull -f ../rebase-tmp "$rtop" || { - echo Pull failed 1>&2 - echo "$h" >>../merge.debug - git diff >>../merge.debug 2>&1 - git diff 2>&1 | egrep -q '<<<<<|^\*' && { - bash -i || exit - } - } - execute rm -rf ../rebase-tmp + if [ -n "$1" ]; then + linux-next-notify "$1" + fi + if [ -n "$2" ]; then + printf '%s\n' "$2" 1>&2 + fi } -[ -n "$start_from" ] || { +fix_up() +{ + report "$@" + if ! bash -i; then + exit + fi +} + +if [ -f "$SHA1_FILE" ]; then + previous_tree=$(tail -n1 "$SHA1_FILE" | cut -f1 -d"$_TAB") +elif [ -z "$start_from" ]; then cp /dev/null "$LOG_FILE" execute date -R execute git checkout master execute git reset --hard stable printf 'Name\t\tSHA1\n----\t\t----\n' > "$SHA1_FILE" +fi -} - -heads=$(grep -v '^#' "$CTRL_FILE" | awk -F '\t' '$2=="quilt" || $2=="git" { printf("%s/%s ", $3, $5); }') +heads=$(awk -F '\t' ' + /^#/ { next; } + $2=="git" { printf("git/%s/%s ", $3, $5); } + $2=="branch" { printf("branch/%s ", $1); } + $2=="switch" { printf("switch/%s/%s ", $3, $4); }' "$CTRL_FILE") need_build=false for h in $heads; do - tree=${h%%/*} - - [ -n "$start_from" ] && { - if [ "$tree" = "$start_from" ]; then + op=${h%%/*} + args=${h#*/} + arg1=${args%%/*} + arg2=${args#*/} + + if [ -n "$previous_tree" ]; then + if [ "$op" = 'git' ] && [ "$arg1" = "$previous_tree" ]; then + previous_tree='' + fi + continue + elif [ -n "$start_from" ]; then + if [ "$op" = 'git' ] && [ "$arg1" = "$start_from" ]; then start_from="" else continue fi - } + fi - hlog=$(git log -1 --oneline "${h/\/*://}") 2>/dev/null + if [ "$op" = "branch" ]; then + git branch -f "$arg1" + linux-next-notify "update branch $arg1" + continue + fi + + if [ "$op" = 'switch' ]; then + new_branch=$arg1 + if [ "$new_branch" = 'master' ]; then + old_branch=$(git branch --show-current) + if ! [ "$old_branch" = 'master' ]; then + if ! git checkout master; then + fix_up 'git checkout master failed' + fi + fi + else + base=$arg2 + if ! git checkout -B "$new_branch" "$base"; then + fix_up "git checkout $new_branch failed" + fi + fi + continue + fi + +# $op == "git" + + tree=$arg1 + branch=$arg2 + h="$tree${branch:+/$branch}" + hlog=$(git log -1 --oneline "$h") 2>/dev/null old_head=$(git rev-parse HEAD) - [ -f "../pre-merge/$tree" ] && { - for p in $(cat "../pre-merge/$tree"); do - "$bin_dir/do_patch" -n "$p" || { - notify-send -u critical -t 0 "premerge patch failed" - bash -i || exit - } - done - } + if [ -f "../pre-merge/$tree" ]; then + while read -r p <&7; do + if ! "$bin_dir/do_patch" -n "$p"; then + fix_up "premerge patch failed" + fi 7<&- + done 7<"../pre-merge/$tree" + fi log Merging "$h" "($hlog)" - case "$h" in - *:*) - do_rebase "$h" "$tree" - ;; - *) - execute git merge "$h" || { - echo Merge failed 1>&2 - echo "$h" >>../merge.debug - git diff >>../merge.debug 2>&1 - um_files=$(git diff 2>&1 | sed -n 's/^\* Unmerged path //p') - [ "$um_files" ] && [ -f "../merge-files/$tree" ] && { - rm_files=$(grep -F "$um_files" "../merge-files/$tree") - [ "$rm_files" ] && - "$bin_dir/do_rm" $rm_files - } - git diff 2>&1 | egrep -q '<<<<<|^\*' && { - notify-send -t 0 -u critical "linux-next new conflict found merging $tree!" - pushover "linux-next new conflict found merging $tree!" - if [ -f "../merge-fixes/$tree" ]; then - echo "Merge fixes exist for this tree:" - cat "../merge-fixes/$tree" - fi - bash -i || exit - } -# [ "$(git status --porcelain)" ] && { - GIT_EDITOR=: execute git commit -v -a || { - notify-send -t 0 -u critical "linux-next commit failed for $tree!" - pushover "linux-next commit failed for $tree!" - bash -i || exit - } - execute git diff -M --stat --summary 'HEAD^..' -# } - } - ;; - esac - [ -f "../merge-fixes/$tree" ] && { - for p in $(cat "../merge-fixes/$tree"); do - "$bin_dir/merge_fix" -n "$p" || { - notify-send -t 0 -u critical "linux-next merge fix failed for $tree!" - pushover "linux-next merge fix failed for $tree!" - bash -i || exit - } - done - } - tab="\t" - [ $(echo "$tree" | wc -c) -le 8 ] && tab="\t\t" - printf "%s$tab%s\n" $tree $(git rev-parse "${h/\/*://}^{}") >> $SHA1_FILE - $no_build && continue - $need_build || { - # See if we need to build after merging this tree - new_head=$(git rev-parse HEAD) - [ "$old_head" = "$new_head" ] || - [ "$(git diff ${old_head}.. | wc -c)" -eq 0 ] || - need_build=true - } - $need_build || + check_dups "$tree" HEAD "$h" | tee -a "$LOG_FILE" + msg=$(printf "Merge branch '%s' of %s" "${branch:-$tree}" "$(get_url "$tree")") + if ! execute git merge -m "$msg" "$h"; then + echo Merge failed 1>&2 + echo "$h" >>../merge.debug + git diff >>../merge.debug 2>&1 + + check_unmerged_files "$tree" + + if git diff 2>&1 | grep -E -q '<<<<<|^\*'; then + if [ -f "../merge-fixes/$tree" ]; then + echo "Merge fixes exist for this tree:" + cat "../merge-fixes/$tree" + fi + fix_up "new conflict found merging $tree" + fi +# if [ "$(git status --porcelain)" ]; then + if ! execute git commit --no-edit -v -a; then + fix_up "next commit failed for $tree" + fi + execute git diff -M --stat --summary 'HEAD^..' +# fi + fi + + tab="$_TAB" + if [ "${#tree}" -lt 8 ]; then + tab="$_TAB$_TAB" + fi + printf '%s%s%s\n' "$tree" "$tab" "$(git rev-parse "$h^{}")" >> "$SHA1_FILE" + + if [ -f "../merge-fixes/$tree" ]; then + while read -r p <&7; do + if ! "$bin_dir/merge_fix" -n "$p"; then + fix_up "merge fix failed for $tree" + fi 7<&- + done 7<"../merge-fixes/$tree" + fi + + if $no_build; then continue - do_build=$(grep -v '^#' $CTRL_FILE | awk -F ' ' '$3=="'$tree'" { print $6; }') - [ "$do_build" = "yes" ] || + fi + + if ! $need_build; then + # See if we need to build after merging this tree + if [ -n "$(git diff "$old_head"..)" ]; then + need_build=true + fi + fi + if ! $need_build; then continue - git push -f "${build_host}${build_host:+:}${build_dir}" master:refs/heads/next || { - echo git push failed 1>&2 - notify-send -t 0 -u critical "linux-next push failed for $tree!" - pushover "linux-next push failed for $tree!" - bash -i || exit - } - [ -x "../pre-build/$tree" ] && { - "../pre-build/$tree" || { - echo Prebuild script failed 1>&2 - notify-send -t 0 -u critical "linux-next pre-build script failed for $tree!" - pushover "linux-next pre-build script failed for $tree!" - bash -i || exit - } - } - "$bin_dir/do_build" "$tree" || { - echo Build failed 1>&2 - notify-send -t 0 -u critical "linux-next build failed for $tree!" - pushover "linux-next build failed for $tree!" - bash -i || exit - } - - notify-send -u normal "Merge and build of $tree successful" + fi + + if [ "$(get_build_flag "$tree")" != "yes" ]; then + if ! [ -f "$top_dir/old-versions/$tree" ]; then + continue + fi + fi + + repo="${build_host:+$build_host:}${build_dir}" + if ! git push -f "$repo" HEAD:refs/heads/next; then + fix_up "push failed for $tree" "git push failed" + fi + + if [ -x "../pre-build/$tree" ] && + ! "../pre-build/$tree"; then + fix_up "pre-build script failed for $tree" "Prebuild script failed" + fi + if ! "$bin_dir/do_build" "$tree"; then + report "build failed for $tree" "Build failed - run do_merge when fixed" + exit 1 + fi + + rm -f "$top_dir/old-versions/$tree" need_build=false done