3 # ref_prepare - TopGit awk utility script used by tg--awksome
4 # Copyright (C) 2017 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 # depsblob if true include 6th line ".topdeps" blob otherwise not
15 # msgblob if true include 6th or 7th line ".topmsg" blob otherwise not
16 # refsfile ref definitions are read from here and used to output hashes
17 # pckdrefs ref table is in packed-refs format (ignored without refsfile)
18 # rmrf if true run system rm on refsfile (after reading)
19 # topdeps if in form <branch>:<hash> substitute <hash> for branch:.topdeps
20 # topmsg if in form <branch>:<hash> substitute <hash> for branch:.topmsg
21 # teeout if non-empty output lines are written here too
23 # if refsfile is non-empty, each line of the file it names must 2+ fields:
25 # <full-ref-name> <full-hash-for-ref> <anything-else-on-line-ignored>
27 # Unless pckdrefs is true and then packed-refs format is expected instead
29 # if refsfile is non-empty, instead of outputting refnames, the name will be
30 # looked up in the refsfile table and the corresponding hash (or a value
31 # guaranteed to generate a "missing" result) used
33 # if topdeps is provided (and matches <branch>:<hash> e.g. "t/foo:1234") then
34 # when depsblob is requested and the current branch is <branch> then instead
35 # of the normal output, <hash>^{blob} will be output instead which can be
36 # used to substitute an index or working tree version of a .topdeps file
38 # input must be a list of full ref names one per line
40 # output is 5, 6 or 7 lines per input line matching /^$topbases/
43 # git cat-file --batch-check='%(objectname) %(objecttype) %(rest)'
45 # if both depsblob and msgblob are true depsblob is output before msgblob and
46 # both always come after the fixed first 5 lines
48 # note that if teeout is non-empty it will always be truncated before starting
49 # to write the output even if no output is produced; also note that unlike the
50 # other scripts this one writes to teeout simultaneously with stdout
53 BEGIN { exitcode =
"" }
54 function exitnow
(e
) { exitcode=e
; exit e
}
55 END { if (exitcode
!= "") exit exitcode
}
58 sub(/\
/+$
/, "", topbases
)
59 if (topbases ==
"") exitnow
(2)
60 topbases = topbases
"/"
61 tblen =
length(topbases
)
64 if (topbases !~
/^refs\
//) exitnow
(2)
65 if (match(topbases
, /^refs\
/remotes\
/[^\
/]+\
//)) {
66 headbase =
substr(topbases
, 1, RLENGTH)
68 headbase =
"refs/heads/"
71 sub(/\
/+$
/, "", headbase
)
72 if (headbase ==
"") exitnow
(2)
73 headbase = headbase
"/"
75 if (topdeps ~
/^
[^
\t\r\n:]+:[0-9A
-Fa
-f
]{4,}$
/) {
76 colonat =
index(topdeps
, ":")
77 topdepsbr =
substr(topdeps
, 1, colonat
- 1)
78 topdepsha =
tolower(substr(topdeps
, colonat
+ 1))
80 if (topmsg ~
/^
[^
\t\r\n:]+:[0-9A
-Fa
-f
]{4,}$
/) {
81 colonat =
index(topmsg
, ":")
82 topmsgbr =
substr(topmsg
, 1, colonat
- 1)
83 topmsgha =
tolower(substr(topmsg
, colonat
+ 1))
85 if (teeout
!= "") printf "" >teeout
88 function doprint
(line
) {
89 if (teeout
!= "") print line
>teeout
93 function quotevar
(v
) {
94 gsub(/\047/, "\047\\\047\047", v
)
95 return "\047" v
"\047"
100 while ((_e =
(getline info
<refsfile
)) > 0) {
101 cnt =
split(info
, scratch
, " ")
102 if (cnt
< 2 || scratch
[1] ==
"" || scratch
[2] ==
"") continue
104 swapfield = scratch
[1]
105 scratch
[1] = scratch
[2]
106 scratch
[2] = swapfield
108 if (scratch
[1] ~
/^refs\
/.
/ && scratch
[2] ~
/^
[0-9a
-fA
-F
]{4,}$
/)
109 refs
[scratch
[1]] = scratch
[2]
112 if (_e
< 0) exitnow
(2)
114 if (refsfile
!= "" && rmrf
) system("rm -f " quotevar
(refsfile
))
119 function getref
(r
) { return refsfile ==
"" ? r
: (refs
[r
] ? refs
[r
] : "?") }
121 NF ==
1 && substr($
1, 1, tblen
) == topbases
{
122 bn =
substr($
1, tbdrop
)
124 baseref = getref
(topbases bn
)
125 headref = getref
(headbase bn
)
126 doprint
(baseref
" " bn
" :")
127 doprint
(baseref
"^0")
128 doprint
(headref
"^0")
129 doprint
(baseref
"^{tree}")
130 doprint
(headref
"^{tree}")
133 doprint
(topdepsha
"^{blob}")
135 doprint
(headref
"^{tree}:.topdeps")
139 doprint
(topmsgha
"^{blob}")
141 doprint
(headref
"^{tree}:.topmsg")