1#!/bin/sh 2# 3# Build two documentation trees and diff the resulting formatted output. 4# Compared to a source diff, this can reveal mistakes in the formatting. 5# For example: 6# 7# ./doc-diff origin/master HEAD 8# 9# would show the differences introduced by a branch based on master. 10 11OPTIONS_SPEC="\ 12doc-diff [options] <from> <to> [-- <diff-options>] 13doc-diff (-c|--clean) 14-- 15j=n parallel argument to pass to make 16f force rebuild; do not rely on cached results 17c,clean cleanup temporary working files 18" 19SUBDIRECTORY_OK=1 20. "$(git --exec-path)/git-sh-setup" 21 22parallel= 23force= 24clean= 25whiletest$#-gt0 26do 27case"$1"in 28-j) 29 parallel=$2;shift;; 30-c|--clean) 31 clean=t ;; 32-f) 33 force=t ;; 34--) 35shift;break;; 36*) 37 usage ;; 38esac 39shift 40done 41 42cd_to_toplevel 43tmp=Documentation/tmp-doc-diff 44 45iftest -n"$clean" 46then 47test$#-eq0|| usage 48 git worktree remove --force"$tmp/worktree"2>/dev/null 49rm-rf"$tmp" 50exit0 51fi 52 53iftest -z"$parallel" 54then 55 parallel=$(getconf _NPROCESSORS_ONLN 2>/dev/null) 56iftest $? !=0||test -z"$parallel" 57then 58 parallel=1 59fi 60fi 61 62test$#-gt1|| usage 63from=$1;shift 64to=$1;shift 65 66from_oid=$(git rev-parse --verify "$from")||exit1 67to_oid=$(git rev-parse --verify "$to")||exit1 68 69iftest -n"$force" 70then 71rm-rf"$tmp" 72fi 73 74# We'll do both builds in a single worktree, which lets "make" reuse 75# results that don't differ between the two trees. 76if!test -d"$tmp/worktree" 77then 78 git worktree add -f --detach"$tmp/worktree""$from"&& 79 dots=$(echo "$tmp/worktree" | sed 's#[^/]*#..#g')&& 80ln-s"$dots/config.mak""$tmp/worktree/config.mak" 81fi 82 83# generate_render_makefile <srcdir> <dstdir> 84generate_render_makefile () { 85find"$1"-type f | 86whileread src 87do 88 dst=$2/${src#$1/} 89printf'all:: %s\n'"$dst" 90printf'%s: %s\n'"$dst""$src" 91printf'\t@echo >&2 " RENDER$(notdir $@)" &&\\\n' 92printf'\tmkdir -p$(dir $@)&&\\\n' 93printf'\tMANWIDTH=80 man $< >$@+ &&\\\n' 94printf'\tmv $@+ $@\n' 95done 96} 97 98# render_tree <committish_oid> 99render_tree () { 100# Skip install-man entirely if we already have an installed directory. 101# We can't rely on make here, since "install-man" unconditionally 102# copies the files (spending effort, but also updating timestamps that 103# we then can't rely on during the render step). We use "mv" to make 104# sure we don't get confused by a previous run that failed partway 105# through. 106if!test -d"$tmp/installed/$1" 107then 108 git -C"$tmp/worktree" checkout --detach"$1"&& 109make-j$parallel-C"$tmp/worktree" \ 110 GIT_VERSION=omitted \ 111 SOURCE_DATE_EPOCH=0 \ 112 DESTDIR="$PWD/$tmp/installed/$1+" \ 113install-man&& 114mv"$tmp/installed/$1+""$tmp/installed/$1" 115fi&& 116 117# As with "installed" above, we skip the render if it's already been 118# done. So using make here is primarily just about running in 119# parallel. 120if!test -d"$tmp/rendered/$1" 121then 122 generate_render_makefile "$tmp/installed/$1""$tmp/rendered/$1+"| 123make-j$parallel-f- && 124mv"$tmp/rendered/$1+""$tmp/rendered/$1" 125fi 126} 127 128render_tree $from_oid&& 129render_tree $to_oid&& 130git -C$tmp/rendered diff--no-index"$@"$from_oid $to_oid