3 # ref_prepare - TopGit awk utility script used by tg--awksome
4 # Copyright (C) 2017,2019 Kyle J. McKay <mackyle@gmail.com>
10 # variable arguments (-v):
12 # topbases the full target topbases prefix (e.g. "refs/top-bases")
13 # headbase the full heads prefix (default is based on topbases value)
14 # chkblob if set spit out a verification line for this blob first
15 # depsblob if true include 6th line ".topdeps" blob otherwise not
16 # msgblob if true include 6th or 7th line ".topmsg" blob otherwise not
17 # refsfile ref definitions are read from here and used to output hashes
18 # pckdrefs ref table is in packed-refs format (ignored without refsfile)
19 # rmrf if true run system rm on refsfile (after reading)
20 # topdeps if in form <branch>:<hash> substitute <hash> for branch:.topdeps
21 # topmsg if in form <branch>:<hash> substitute <hash> for branch:.topmsg
22 # teeout if non-empty output lines are written here too
24 # if refsfile is non-empty, each line of the file it names must be 2+ fields:
26 # <full-ref-name> <full-hash-for-ref> <anything-else-on-line-ignored>
28 # Unless pckdrefs is true and then packed-refs format is expected instead
30 # if refsfile is non-empty, instead of outputting refnames, the name will be
31 # looked up in the refsfile table and the corresponding hash (or a value
32 # guaranteed to generate a "missing" result) used
34 # if topdeps is provided (and matches <branch>:<hash> e.g. "t/foo:1234") then
35 # when depsblob is requested and the current branch is <branch> then instead
36 # of the normal output, <hash>^{blob} will be output instead which can be
37 # used to substitute an index or working tree version of a .topdeps file
39 # input must be a list of full ref names one per line
41 # output is 5, 6 or 7 lines per input line matching /^$topbases/
44 # git cat-file --batch-check='%(objectname) %(objecttype) %(rest)'
46 # if both depsblob and msgblob are true depsblob is output before msgblob and
47 # both always come after the fixed first 5 lines
49 # if chkblob is not empty an additional line will precede all other output
50 # that verifies the existence of the chkblob object (and resolves it to a hash)
52 # note that if teeout is non-empty it will always be truncated before starting
53 # to write the output even if no output is produced; also note that unlike the
54 # other scripts this one writes to teeout simultaneously with stdout
57 BEGIN { exitcode =
"" }
58 function exitnow
(e
) { exitcode=e
; exit e
}
59 END { if (exitcode
!= "") exit exitcode
}
62 sub(/\
/+$
/, "", topbases
)
63 if (topbases ==
"") exitnow
(2)
64 topbases = topbases
"/"
65 tblen =
length(topbases
)
68 if (topbases !~
/^refs\
//) exitnow
(2)
69 if (topbases ~
/^refs\
/remotes\
//) {
70 if (topbases !~
/^refs\
/remotes\
/[^\
/]+\
/[^\
/]+\
//) exitnow
(2)
72 sub(/\
/[^\
/]+\
/$
/, "/", headbase
)
74 headbase =
"refs/heads/"
77 sub(/\
/+$
/, "", headbase
)
78 if (headbase ==
"") exitnow
(2)
79 headbase = headbase
"/"
81 if (topdeps ~
/^
[^
\t\r\n:]+:[0-9A
-Fa
-f
][0-9A
-Fa
-f
][0-9A
-Fa
-f
][0-9A
-Fa
-f
]+$
/) {
82 colonat =
index(topdeps
, ":")
83 topdepsbr =
substr(topdeps
, 1, colonat
- 1)
84 topdepsha =
tolower(substr(topdeps
, colonat
+ 1))
86 if (topmsg ~
/^
[^
\t\r\n:]+:[0-9A
-Fa
-f
][0-9A
-Fa
-f
][0-9A
-Fa
-f
][0-9A
-Fa
-f
]+$
/) {
87 colonat =
index(topmsg
, ":")
88 topmsgbr =
substr(topmsg
, 1, colonat
- 1)
89 topmsgha =
tolower(substr(topmsg
, colonat
+ 1))
91 if (teeout
!= "") printf "" >teeout
94 function doprint
(line
) {
95 if (teeout
!= "") print line
>teeout
99 function quotevar
(v
) {
100 gsub(/\047/, "\047\\\047\047", v
)
101 return "\047" v
"\047"
105 if (refsfile
!= "" && rmrf
) {
106 system("rm -f " quotevar
(refsfile
))
114 if (refsfile
!= "") {
115 while ((_e =
(getline info
<refsfile
)) > 0) {
116 cnt =
split(info
, scratch
, " ")
117 if (cnt
< 2 || scratch
[1] ==
"" || scratch
[2] ==
"") continue
119 swapfield = scratch
[1]
120 scratch
[1] = scratch
[2]
121 scratch
[2] = swapfield
123 if (scratch
[1] ~
/^refs\
/.
/ &&
124 scratch
[2] ~
/^
[0-9a
-fA
-F
][0-9a
-fA
-F
][0-9a
-fA
-F
][0-9a
-fA
-F
]+$
/)
125 refs
[scratch
[1]] = scratch
[2]
128 if (_e
< 0) exitnow
(2)
134 if (chkblob
!= "") doprint
(chkblob
"^{blob}" " check ?")
139 function getref
(r
) { return refsfile ==
"" ? r
: ((r in refs
) ? refs
[r
] : "?") }
141 NF ==
1 && substr($
1, 1, tblen
) == topbases
{
142 bn =
substr($
1, tbdrop
)
144 baseref = getref
(topbases bn
)
145 headref = getref
(headbase bn
)
146 doprint
(baseref
" " bn
" :")
147 doprint
(baseref
"^0")
148 doprint
(headref
"^0")
149 doprint
(baseref
"^{tree}")
150 doprint
(headref
"^{tree}")
153 doprint
(topdepsha
"^{blob}")
155 doprint
(headref
"^{tree}:.topdeps")
159 doprint
(topmsgha
"^{blob}")
161 doprint
(headref
"^{tree}:.topmsg")