t8200: test export subject stripping behaviors
[topgit/pro.git] / awk / topgit_msg_prepare.awk
bloba4a579d95a7099ab7acc625a150663fddfe321dc
1 #!/usr/bin/awk -f
3 # topgit_msg_prepare - TopGit awk utility script used by tg--awksome
4 # Copyright (C) 2017 Kyle J. McKay <mackyle@gmail.com>
5 # All rights reserved.
6 # License GPLv2
8 # topgit_msg_prepare
10 # variable arguments (-v):
12 # brfile if non-empty, the named file gets a list of TopGit branches
13 # anfile if non-empty, annihilated branch names are written here
14 # withan if true, include annihilated branches in brfile and output
15 # withmt empty branches: "" (like withan), true (include) false (exclude)
16 # depsblob if true skip the 6th line of each group as it's a .topdeps blob
17 # missing if non-empty output its value for the .topmsg blob instead
18 # of skipping, but still skip annihilated unless withan is true
19 # misscmd if missing is used and not seen in a "check" line run this once
21 # note that withan affects brfile and output but withmt only affects output
23 # note that empty branches are always included in anfile (and brfile when
24 # withan is true) regardless of any withmt setting
26 # if withan is false annihilated branches are excluded (but see withmt)
28 # if withmt is empty ("") empty branches are treated the same as annihilated
29 # branches; if withmt is true empty branches are always included even if withan
30 # is false; if withmt is false (but not "") empty branches are always excluded
31 # even if withan is true
33 # input must be result of awk_ref_prepare after feeding through the correct
34 # git --batch-check command and must be generated with the "msgblob" variable
35 # set to a TRUE value AND the same depsblob value must be passed as when
36 # awk_ref_prepare was run
38 # if missing is non-empty there are two different possible choices:
40 # 1. the hash of the empty blob, this is the recommended value and will
41 # cause all annihilated (unless withan is false) and non-annihilaed
42 # branches (unless withmt excludes them) without a .topmsg file to
43 # produce an output line which can often be useful
45 # 2. an invalid ref value, do NOT use "missing" as there could be such a ref
46 # name in the repository ("?" or "?missing" are good choices) and it must
47 # not contain any whitespace either; in this case this will trigger the
48 # subsequent git cat-file --batch to generate a "xxx missing" line which
49 # will also remove the item and ultimately have the same effect as leaving
50 # missing unset in the first place
52 # 3. it says "two" above, so don't do this, but if the blob hash of
53 # a different .topmsg file is given its contents will be used as though
54 # it had been the branch's .topmsg file in the first place (only for
55 # annihildated/empty and branches without one though)
57 # If missing is non-empty AND it gets used AND misscmd is non-empty AND no
58 # "blob check ?" line was seen for missing then misscmd will be run the FIRST
59 # time missing is about to be output (it always runs BEFORE the line is output).
61 # output is 1 line per non-excluded TopGit branch with a .topmsg file where
62 # each output line has this format:
64 # <blob_hash_of_.topmsg_file> K <TopGit_branch_name>
66 # where kind of branch value K has these possible values and meanings:
68 # 0 non-annihilated, non-empty branch WITH a .topmsg file
69 # 1 non-annihilated, non-empty branch WITHOUT a .topmsg file
70 # 2 annihilated branch
71 # 3 empty branch (an empty branch has the same branch and base commit hash)
73 # if missing is empty K = 1..3 lines will not be output at all
74 # if missing is anything that causes a "missing" result it will defeat all
75 # K = 1..3 output lines when subsequently fed through git cat-file --batch
77 # in most other contexts empty branches are treated the same as annihilated
78 # branches (because their branch and base trees are necessarily the same), but
79 # here a distinction is made so a different message can be shown for them
81 # output should then be feed to:
83 # git cat-file --batch='%(objecttype) %(objectsize) %(rest)' | tr '\0' '\27'
85 # note that brfile and anfile are both fully written and closed before the
86 # first line of stdout is written and will be truncated to empty even if there
87 # are no lines directed to them
90 BEGIN { exitcode = "" }
91 function exitnow(e) { exitcode=e; exit e }
92 END { if (exitcode != "") exit exitcode }
94 BEGIN {
95 cnt = 0
96 delay = 0
97 if (anfile != "") {
98 printf "" >anfile
99 delay=1
101 if (brfile != "") {
102 printf "" >brfile
103 delay=1
105 FS = " "
108 NF == 4 && $4 == "?" && $3 = "check" && $2 = "blob" && $1 != "" {
109 check[$1] = "blob"
110 next
113 function domissing() {
114 if (misscmd == "" || missing in check) return
115 system(misscmd)
116 check[missing] = ""
119 NF == 4 && $4 == ":" && $3 != "" && $2 != "missing" && $1 != "" {
120 if ((getline bc + getline hc + \
121 getline bct + getline hct + getline hcm) != 5) exitnow(2)
122 if (depsblob && (getline hcm) != 1) exitnow(2)
123 split(bc, abc)
124 split(hc, ahc)
125 split(bct, abct)
126 split(hct, ahct)
127 split(hcm, ahcm)
128 if (abc[2] != "commit" || ahc[2] != "commit" ||
129 abct[2] != "tree" || ahct[2] != "tree") next
130 want = abct[1] != ahct[1]
131 if (!want) {
132 if (withmt != "" && abc[1] == ahc[1]) want = withmt
133 else want = withan
135 K = 0
136 if (abct[1] == ahct[1]) {
137 if (anfile) print $3 >anfile
138 if (!withan || missing == "") {
139 if (!want || missing == "") {
140 if (withan && brfile) print $3 >brfile
141 next
144 ahcm[1] = missing
145 ahcm[2] = "blob"
146 K = (abc[1] == ahc[1]) ? 3 : 2
147 domissing()
149 if (brfile) print $3 >brfile
150 if (missing != "" && ahcm[2] != "blob") {
151 ahcm[1] = missing "^{}"
152 ahcm[2] = "blob"
153 if (!K) K = 1
154 domissing()
156 if (ahcm[2] == "blob") {
157 if (delay)
158 items[++cnt] = ahcm[1] " " K " " $3
159 else
160 print ahcm[1] " " K " " $3
164 END {
165 if (anfile) close(anfile)
166 if (brfile) close(brfile)
167 for (i = 1; i <= cnt; ++i) print items[i]