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