Browse Source

Meta/GRADUATED: rewrite for simplicity and robustness

todo
Junio C Hamano 12 years ago
parent
commit
5734c66905
  1. 188
      GRADUATED

188
GRADUATED

@ -1,141 +1,95 @@
#!/bin/sh #!/bin/sh


# Older first! base=
old_maint=$( while :
git for-each-ref --format='%(refname)' 'refs/heads/maint-*' |
sed -e 's|^refs/heads/||'
)

# Are older maint branches all included in newer ones?
and_or_thru=thru prev=
for m in $old_maint maint
do do
if test -n "$prev" case "$1" in
--base=*)
base=${1#*=} ;;
-*)
echo >&2 "Eh? $1"
exit 1 ;;
*)
break ;;
esac
shift
done

if test -z "$base"
then then
test "$(git rev-list $m..$prev | wc -l)" = 0 || { describe=$(git describe "master")
and_or_thru=and base=$(expr "$describe" : '\(.*\)-\([0-9]*\)-g[0-9a-f]*$') ||
break base="$describe"

git rev-parse --verify "$base^0" >/dev/null 2>/dev/null || {
echo >&2 "Eh? where is your base?"
exit 1
} }
fi fi
prev=$m
done


_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' topics=
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" leftover=
dothis=
LF=' LF='
' '


# disable pager defer () {
GIT_PAGER=cat leftover="$leftover$1$LF"
export GIT_PAGER

find_last_tip () {
topic="$(git rev-parse --verify "$1")" integrate="$2"
git rev-list --first-parent --parents "$2" |
sed -n -e "
/^$_x40 $_x40 $topic$/{
s/^\($_x40\) $_x40 $topic$/\1/p
q
} }
"
dothis () {
dothis="$1$LF$LF$dothis"
} }


one_topic () {
topic="$1" tip="$2" date="$3"
case " $topics" in *" $topic "*) return ;; esac
topics="$topic$topic "


tmp=/tmp/GR.$$ mergeable=no ready=no label=


trap 'rm -f "$tmp".*' 0 master_count=$(git rev-list "$base..$tip" | wc -l)
maint_count=$(git rev-list "maint..$tip" | wc -l)


git branch --merged master | sed -n -e '/\//s/^. //p' | sort >"$tmp.master" test $master_count = $maint_count && mergeable=yes


>"$tmp.known" if current=$(git rev-parse --verify -q "$topic^0") &&
for m in $old_maint maint test "$current" = "$tip"
do
git branch --merged $m | sed -n -e '/\//s/^. //p' | sort >"$tmp.$m"
comm -12 "$tmp.$m" "$tmp.master" >"$tmp.both0"
comm -23 "$tmp.both0" "$tmp.known" >"$tmp.both"
if test -s "$tmp.both"
then then
echo "# Graduated to both $m $and_or_thru master" ready=yes
while read branch label="$topic"
do elif test -z "$current"
d=$(git describe --always $branch)
echo "$(git show -s --format='%ct' "$branch") $branch ;# $d"
done <"$tmp.both" |
sort -r -n |
sed -e 's/^[0-9]* //' \
-e 's/^/git branch -d /' |
sort -V -k 6,6
echo
cat "$tmp.known" "$tmp.both" | sort >"$tmp.next"
mv "$tmp.next" "$tmp.known"
fi
done

comm -13 "$tmp.maint" "$tmp.master" |
{
while read topic
do
t=$(find_last_tip $topic master) &&
test -n "$t" &&
m=$(git rev-parse --verify "$t^1") &&
test -n "$m" || continue

# NEEDSWORK: this misses repeated merges
#
# o---o---maint
# /
# .---o---o topic
# / \ \
# ---o---o---*---*---master

tsize=$(git rev-list "$m..$topic" | wc -l)
rsize=$(git rev-list "maint..$topic" | wc -l)

if test $tsize -eq $rsize
then then
s=$(git show -s --pretty="tformat:%ct %H" $t) ready=yes
echo "$s $topic" label="$tip"
else
s=$(git show -s --pretty="tformat:%ct %H" $t)
echo >&3 "$s $topic"
fi fi
done 3>"$tmp.unmergeable" >"$tmp.mergeable"


if test -s "$tmp.unmergeable" case "$mergeable,$ready" in
then no,*)
echo ": # Graduated to master; unmergeable to maint" defer "# $topic: not mergeable ($master_count vs $maint_count)"
sort -n "$tmp.unmergeable" | ;;
while read timestamp merge topic yes,no)
do topic_count=$(git rev-list "$base..$current" | wc -l)
git show -s --pretty="format:: # %h %cd" $merge defer "# $topic: not ready ($master_count vs $topic_count)"
echo "git branch -d $topic" ;;
done yes,yes)
echo insn="$label # $master_count ($date)"
fi insn="$insn$LF$(git log --oneline "maint..$tip" | sed -e "s/^/# /")"
if test -s "$tmp.mergeable" dothis "$insn"
then ;;
sort -n "$tmp.mergeable" | esac
while read timestamp merge topic }
do
{
git show -s --pretty="format:%h %cd" $merge
git log --pretty=oneline --abbrev-commit maint..$topic
} |
sed -e 's/^/: # /'
maint=maint
these=$(git rev-list maint..$topic)
for m in $old_maint maint
do
those=$(git rev-list $m..$topic)
if test "z$these" = "z$those"
then
maint=$m
break
fi
done


echo "git checkout $maint && git merge $topic" git log --first-parent --min-parents=2 --max-parents=2 \
echo --format='%ci %H %P %s' "$base..master" | {
while read date time zone commit parent tip subject
do
topic=$(expr "$subject" : "Merge branch '\(.*\)'$") || {
echo >&2 "Cannot parse $commit ($subject)"
continue
}
one_topic "$topic" "$tip" "$date"
done done
fi echo "$leftover"
echo "$dothis"
} }

Loading…
Cancel
Save