diff options
Diffstat (limited to 'usr/src/tools/scripts/webrev.sh')
-rw-r--r-- | usr/src/tools/scripts/webrev.sh | 291 |
1 files changed, 264 insertions, 27 deletions
diff --git a/usr/src/tools/scripts/webrev.sh b/usr/src/tools/scripts/webrev.sh index 74a4fa2877..2d5b31f162 100644 --- a/usr/src/tools/scripts/webrev.sh +++ b/usr/src/tools/scripts/webrev.sh @@ -516,6 +516,16 @@ html_quote() $SED -e "s/&/\&/g" -e "s/</\</g" -e "s/>/\>/g" "$@" | expand } +# +# Trim a digest-style revision to a conventionally readable yet useful length +# +trim_digest() +{ + typeset digest=$1 + + echo $digest | $SED -e 's/\([0-9a-f]\{12\}\).*/\1/' +} + # # input_cmd | its2url | output_cmd # @@ -1780,6 +1790,81 @@ function flist_from_mercurial } # +# Transform a specified 'git log' output format into a wx-like active list. +# +function git_wxfile +{ + typeset child="$1" + typeset parent="$2" + + TMPFLIST=/tmp/$$.active + $PERL -e 'my (%files, %realfiles, $msg); + my $branch = $ARGV[0]; + + open(F, "git diff -M --name-status $branch |"); + while (<F>) { + chomp; + if (/^R(\d+)\s+([^ ]+)\s+([^ ]+)/) { # rename + if ($1 >= 75) { # Probably worth treating as a rename + $realfiles{$3} = $2 + } else { + $realfiles{$3} = $3; + $realfiles{$2} = $2; + } + } else { + my $f = (split /\s+/, $_)[1]; + $realfiles{$f} = $f; + } + } + close(F); + + my $state = 1; # 0|comments, 1|files + open(F, "git whatchanged --pretty=format:%B $branch.. |"); + while (<F>) { + chomp; + if (/^:[0-9]{6}/) { + my $fname = (split /\t/, $_)[1]; + next if !defined($realfiles{$fname}); # No real change + $state = 1; + $files{$fname} = $msg; + } else { + if ($state == 1) { + $state = 0; + $msg = /^\n/ ? "" : "\n"; + } + $msg .= "$_\n" if ($_); + } + } + close(F); + + for (sort keys %files) { + if ($realfiles{$_} ne $_) { + print "$_ $realfiles{$_}\n$files{$_}\n"; + } else { + print "$_\n$files{$_}\n" + } + }' ${parent} > $TMPFLIST + + wxfile=$TMPFLIST +} + +# +# flist_from_git +# Build a wx-style active list, and hand it off to flist_from_wx +# +function flist_from_git +{ + typeset child=$1 + typeset parent=$2 + + print " File list from: git ...\c" + git_wxfile "$child" "$parent"; + + # flist_from_wx prints the Done, so we don't have to. + flist_from_wx $TMPFLIST +} + +# # flist_from_subversion # # Generate the file list by extracting file names from svn status. @@ -1999,6 +2084,64 @@ function build_old_new_mercurial fi } +function build_old_new_git +{ + typeset olddir="$1" + typeset newdir="$2" + typeset o_mode= + typeset n_mode= + typeset o_object= + typeset n_object= + typeset OWD=$PWD + typeset file + typeset type + + cd $CWS + + # + # Get old file and its mode from the git object tree + # + if [[ "$PDIR" == "." ]]; then + file="$PF" + else + file="$PDIR/$PF" + fi + + if [[ -n $parent_webrev && -e $PWS/$PDIR/$PF ]]; then + cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF + else + $GIT ls-tree $GIT_PARENT $file | read o_mode type o_object junk + $GIT cat-file $type $o_object > $olddir/$file 2>/dev/null + + if (( $? != 0 )); then + rm -f $olddir/$file + elif [[ -n $o_mode ]]; then + # Strip the first 3 digits, to get a regular octal mode + o_mode=${o_mode/???/} + chmod $o_mode $olddir/$file + else + # should never happen + print -u2 "ERROR: set mode of $olddir/$file" + fi + fi + + # + # new version of the file. + # + if [[ "$DIR" == "." ]]; then + file="$F" + else + file="$DIR/$F" + fi + rm -rf $newdir/$file + + if [[ -e $CWS/$DIR/$F ]]; then + cp $CWS/$DIR/$F $newdir/$DIR/$F + chmod $(get_file_mode $CWS/$DIR/$F) $newdir/$DIR/$F + fi + cd $OWD +} + function build_old_new_subversion { typeset olddir="$1" @@ -2059,6 +2202,8 @@ function build_old_new build_old_new_teamware "$olddir" "$newdir" elif [[ $SCM_MODE == "mercurial" ]]; then build_old_new_mercurial "$olddir" "$newdir" + elif [[ $SCM_MODE == "git" ]]; then + build_old_new_git "$olddir" "$newdir" elif [[ $SCM_MODE == "subversion" ]]; then build_old_new_subversion "$olddir" "$newdir" elif [[ $SCM_MODE == "unknown" ]]; then @@ -2120,11 +2265,12 @@ trap "rm -f /tmp/$$.* ; exit" 0 1 2 3 15 set +o noclobber -PATH=$(dirname $(whence $0)):$PATH +PATH=$(/bin/dirname "$(whence $0)"):$PATH [[ -z $WDIFF ]] && WDIFF=`look_for_prog wdiff` [[ -z $WX ]] && WX=`look_for_prog wx` [[ -z $HG_ACTIVE ]] && HG_ACTIVE=`look_for_prog hg-active` +[[ -z $GIT ]] && GIT=`look_for_prog git` [[ -z $WHICH_SCM ]] && WHICH_SCM=`look_for_prog which_scm` [[ -z $CODEREVIEW ]] && CODEREVIEW=`look_for_prog codereview` [[ -z $PS2PDF ]] && PS2PDF=`look_for_prog ps2pdf` @@ -2307,6 +2453,24 @@ elif [[ $SCM_MODE == "mercurial" ]]; then codemgr_ws=$(hg root -R $testparent 2>/dev/null) [[ -z $codemgr_ws ]] && codemgr_ws=$(hg root 2>/dev/null) CWS=$codemgr_ws +elif [[ $SCM_MODE == "git" ]]; then + # + # Git priorities: + # 1. git rev-parse --git-dir from CODEMGR_WS environment variable + # 2. git rev-parse --git-dir from directory of invocation + # + [[ -z $codemgr_ws && -n $CODEMGR_WS ]] && \ + codemgr_ws=$($GIT --git-dir=$CODEMGR_WS/.git rev-parse --git-dir \ + 2>/dev/null) + [[ -z $codemgr_ws ]] && \ + codemgr_ws=$($GIT rev-parse --git-dir 2>/dev/null) + + if [[ "$codemgr_ws" == ".git" ]]; then + codemgr_ws="${PWD}/${codemgr_ws}" + fi + + codemgr_ws=$(dirname $codemgr_ws) # Lose the '/.git' + CWS="$codemgr_ws" elif [[ $SCM_MODE == "subversion" ]]; then # # Subversion priorities: @@ -2358,8 +2522,8 @@ fi # then note that fact and set the parent to the raw_files/new subdirectory. # if [[ -n $pflag && -d $codemgr_parent/raw_files/new ]]; then - parent_webrev="$codemgr_parent" - codemgr_parent="$codemgr_parent/raw_files/new" + parent_webrev=$(readlink -f "$codemgr_parent") + codemgr_parent=$(readlink -f "$codemgr_parent/raw_files/new") fi if [[ -z $wflag && -z $lflag ]]; then @@ -2390,7 +2554,7 @@ fi # is in use. # case "$SCM_MODE" in -teamware|mercurial|subversion) +teamware|mercurial|git|subversion) ;; unknown) if [[ $flist_mode == "auto" ]]; then @@ -2552,7 +2716,6 @@ elif [[ $SCM_MODE == "mercurial" ]]; then codemgr_parent=`hg path -R $codemgr_ws default 2>/dev/null` fi - CWS_REV=`hg parent -R $codemgr_ws --template '{node|short}' 2>/dev/null` PWS=$codemgr_parent # @@ -2616,6 +2779,96 @@ elif [[ $SCM_MODE == "mercurial" ]]; then print -u2 "Error: Cannot discover parent revision" exit 1 fi + + pnode=$(trim_digest $HG_PARENT) + PRETTY_PWS="${PWS} (at ${pnode})" + cnode=$(hg parent -R $codemgr_ws --template '{node|short}' \ + 2>/dev/null) + PRETTY_CWS="${CWS} (at ${cnode})"} +elif [[ $SCM_MODE == "git" ]]; then + # + # Parent can either be specified with -p, or specified with + # CODEMGR_PARENT in the environment. + # + + if [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]]; then + codemgr_parent=$CODEMGR_PARENT + fi + + # Try to figure out the parent based on the branch the current + # branch is tracking, if we fail, use origin/master + this_branch=$($GIT branch | nawk '$1 == "*" { print $2 }') + par_branch="origin/master" + + # If we're not on a branch there's nothing we can do + if [[ $this_branch != "(no branch)" ]]; then + $GIT for-each-ref \ + --format='%(refname:short) %(upstream:short)' refs/heads/ | \ + while read local remote; do \ + [[ "$local" == "$this_branch" ]] && par_branch="$remote"; \ + done + fi + + if [[ -z $codemgr_parent ]]; then + codemgr_parent=$par_branch + fi + PWS=$codemgr_parent + + # + # If the parent is a webrev, we want to do some things against + # the natural workspace parent (file list, comments, etc) + # + if [[ -n $parent_webrev ]]; then + real_parent=$par_branch + else + real_parent=$PWS + fi + + if [[ -z $flist_done ]]; then + flist_from_git "$CWS" "$real_parent" + flist_done=1 + fi + + # + # If we have a file list now, pull out any variables set + # therein. + # + if [[ -n $flist_done ]]; then + env_from_flist + fi + + # + # If we don't have a wx-format file list, build one we can pull change + # comments from. + # + if [[ -z $wxfile ]]; then + print " Comments from: git...\c" + git_wxfile "$CWS" "$real_parent" + print " Done." + fi + + if [[ -z $GIT_PARENT ]]; then + GIT_PARENT=$($GIT merge-base "$real_parent" HEAD) + fi + if [[ -z $GIT_PARENT ]]; then + print -u2 "Error: Cannot discover parent revision" + exit 1 + fi + + pnode=$(trim_digest $GIT_PARENT) + + if [[ $real_parent == */* ]]; then + origin=$(echo $real_parent | cut -d/ -f1) + origin=$($GIT remote -v | \ + $AWK '$1 == "'$origin'" { print $2; exit }') + PRETTY_PWS="${PWS} (${origin} at ${pnode})" + else + PRETTY_PWS="${PWS} (at ${pnode})" + fi + + cnode=$($GIT --git-dir=${codemgr_ws}/.git rev-parse --short=12 HEAD \ + 2>/dev/null) + PRETTY_CWS="${CWS} (at ${cnode})" elif [[ $SCM_MODE == "subversion" ]]; then # @@ -2682,7 +2935,7 @@ typeset -A itsinfo typeset -r its_sed_script=/tmp/$$.its_sed valid_prefixes= if [[ -z $nflag ]]; then - DEFREGFILE="$(dirname $(whence $0))/../etc/its.reg" + DEFREGFILE="$(/bin/dirname "$(whence $0)")/../etc/its.reg" if [[ -n $Iflag ]]; then REGFILE=$ITSREG elif [[ -r $HOME/.its.reg ]]; then @@ -2711,7 +2964,7 @@ if [[ -z $nflag ]]; then done - DEFCONFFILE="$(dirname $(whence $0))/../etc/its.conf" + DEFCONFFILE="$(/bin/dirname "$(whence $0)")/../etc/its.conf" CONFFILES=$DEFCONFFILE if [[ -r $HOME/.its.conf ]]; then CONFFILES="${CONFFILES} $HOME/.its.conf" @@ -2895,21 +3148,11 @@ fi # # Summarize what we're going to do. # -if [[ -n $CWS_REV ]]; then - print " Workspace: $CWS (at $CWS_REV)" -else - print " Workspace: $CWS" -fi +print " Workspace: ${PRETTY_CWS:-$CWS}" if [[ -n $parent_webrev ]]; then print "Compare against: webrev at $parent_webrev" else - if [[ -n $HG_PARENT ]]; then - hg_parent_short=`echo $HG_PARENT \ - | $SED -e 's/\([0-9a-f]\{12\}\).*/\1/'` - print "Compare against: $PWS (at $hg_parent_short)" - else - print "Compare against: $PWS" - fi + print "Compare against: ${PRETTY_PWS:-$PWS}" fi [[ -n $INCLUDE_FILE ]] && print " Including: $INCLUDE_FILE" @@ -3260,19 +3503,13 @@ fi PREPDATE=$(LC_ALL=C /usr/bin/date +%Y-%b-%d\ %R\ %z\ %Z) print "<tr><th>Prepared by:</th><td>$preparer on $PREPDATE</td></tr>" -print "<tr><th>Workspace:</th><td>$CWS" -if [[ -n $CWS_REV ]]; then - print "(at $CWS_REV)" -fi +print "<tr><th>Workspace:</th><td>${PRETTY_CWS:-$CWS}" print "</td></tr>" print "<tr><th>Compare against:</th><td>" if [[ -n $parent_webrev ]]; then print "webrev at $parent_webrev" else - print "$PWS" - if [[ -n $hg_parent_short ]]; then - print "(at $hg_parent_short)" - fi + print "${PRETTY_PWS:-$PWS}" fi print "</td></tr>" print "<tr><th>Summary of changes:</th><td>" |