4 The TopGit testing library consists of TopGit-specific additions to the testing
5 library that are automatically available whenever the standard testing library
6 functions and variables are.
8 Familiarity with the standard testing library functions and variables as
9 described in `README-TESTLIB` can provide valuable assistance in understanding
10 the contents of this file.
12 The functions described here are defined in the `test-lib-functions-tg.sh`
13 file which contains copious comments for each one should the more succinct
14 descriptions included here prove insufficiently enlightening.
21 TopGit variable | Description
22 --------------------------------|----------------------------------------------
23 TG_TEST_FULL_PATH | full absolute path to `tg` being tested
24 tg_test_bases | "" (default), "refs" or "heads"
25 tg_test_remote | default remote name (default is "")
27 TopGit utility function | Description
28 --------------------------------|----------------------------------------------
29 tg_test_bare_tree | make a bare `tree` out of any treeish
30 tg_test_create_branch | create a TopGit branch (multiple options)
31 tg_test_create_branches | script multiple `tg_test_create_branch` calls
32 tg_test_create_tag | create a TopGit annotated refs state tag
33 tg_test_include | source target `tg` in `tg__include` mode
34 tg_test_setup_topgit | do hook and merge TopGit setup only
35 tg_test_v_getbases | get local or remote full top-bases ref prefix
36 tg_test_v_getremote | error checking `: "${var:=$tg_test_remote}"`
45 Set by the testing library to the full absolute path to the `tg` executable
46 being used for testing.
50 Location of "top-bases" refs for `tg_test_v_getbases` function. May have
53 * "" (the empty string or unset)
54 default top-bases location for this release of TopGit (default value)
56 Use `refs/top-bases` or `refs/remotes/`<remote-name>`/top-bases`
58 Use `refs/heads/{top-bases}` or
59 `refs/remotes/`<remote-name>`/{top-bases}`
61 exit immediately with a fatal error when `tg_test_v_getbases` is called
65 Remote name to use when `tg_test_v_getremote` is called with no remote or
66 with an empty remote name argument. A fatal error will occur if the
67 `tg_test_v_getname` function is called with an empty or omitted remote name
68 and this variable is unset or empty (the default value).
71 ------------------------
72 TopGit Utility Functions
73 ------------------------
75 - tg_test_bare_tree [-C <dirpath>] <treeish>
77 Output the hash of the tree equivalent to <treeish>^{tree} with any
78 top-level .topdeps and .topmsg files removed. The returned tree is
79 guaranteed to exist in the object database.
81 The output tree hash will be located in the current repository unless
82 -C <dirpath> is used in which case it will be located in that Git
85 - tg_test_create_branch [-C <dirpath>] [--notick] [+][\][[<remote>]:[:]]<branch>
86 [--no-topmsg] [-m "message"] [:[:[:]][~]]<start> [<dep>...]
88 Create a new TopGit branch (head and base) named <branch>. If the
89 [<remote>]: prefix is given it will be a remote TopGit branch only (using
90 `tg_test_remote` if the [<remote>] part is empty) or BOTH a local AND
91 remote TopGit branch if the [<remote>]:: prefix (double-colon) form is
94 Unless --notick is used the `test_tick` function will be called before
95 creation of each new commit. All of the refs to be created must not
96 already exist or a fatal error will occur.
98 The new <branch> will be created in the current repository unless
99 -C <dirpath> is used in which case it will be created in that Git
102 Unless the leading "+" is present the branch and its associated base
103 (local, remote or local and remote depending on the ":" prefix part)
104 MUST NOT already exist. With "+" any pre-existing values are stepped on.
105 A leading "\" will be stripped from the branch name allowing branch names
106 that start with "+" to be specified as "\+branch" without having the "+"
107 be interpreted as the overwrite option.
109 If -m "message" is omitted the default is "branch <branch>", but if
110 --no-topmsg is used instead the branch will not have any .topmsg file at
111 all (just like a bare branch, but it could still have a .topdeps file).
112 The message, if given, will still be used for the commit message though.
114 The branch's starting point will be <start> which must be the name of an
115 existing branch under refs/heads and it will also be included as the first
116 line of the created .topdeps file.
118 However, if the :[:[:]]<start> form is used then <start> can be any
119 existing committish and it will NOT be included in the created .topdeps
120 file. If the :~<start> form is used then it works the same way as just
121 :<start> except that the branch will not have a .topdeps file at all (just
122 like a bare branch, but it could still have a .topmsg file).
124 If two colons (e.g. "::start") are used then the created branch will be
125 bare and not have any .topdeps or .topmsg file and the [<dep>...]
126 arguments are forbidden. This is a convenience to save typing as the
127 same thing can be accomplished using --no-topmsg and :~<start>.
129 If three colons are used (e.g. ":::start") the [<dep>...] arguments are
130 also forbidden, no additional .topdeps or .topmsg files added (but
131 existing ones in <start> will be left alone), the bases will NOT be
132 created (making it a non-TopGit branch) but they must also not exist
133 (unless "+" was used) and it will have a commit made on it in the style of
134 `test_commit` (except that only the message can be specified, the <file>,
135 <contents> and <tag> always use default values as described for
136 `test_commit`). Note that since unlike the `test_commit` function, the
137 default message is "branch <<branch>" no tag will be created by default.
138 To cause a tag to be created, an explicit, single-word, refname-friendly
139 message must be provided.
141 With the :[:[:][~]]<start> form only, <start> may be the
142 empty string to start from a new empty tree root commit (or no parent at
143 all in the ":::" case).
145 Note that by combining the "+"<branch> form with a :::<start> line where
146 both <branch> and <start> are the same, more commits can be added to a
149 Each given <dep> argument will be added as a line to the created .topdeps
150 file as-is WITHOUT ANY VALIDATION (except they are forbidden for bare
151 branches and will cause a fatal error in that case if given).
153 The repository in which the branches are created is left unmolested (i.e.
154 its working tree, index and symbolic-ref value of HEAD are unchanged).
155 However, if HEAD was a symbolic-ref to an unborn branch that's then created
156 by this function that could impact Git's interpretation of the worktree and
159 - tg_test_create_branches [-C <dirpath>] [--notick]
161 Read `tg_branch_create` instructions from standard input and then call
162 `tg_test_create_branch` for each set of instructions.
164 Standard input must be a sequence of line groups each consisting of two or
165 more non-empty lines where the groups are separated by a single blank line.
166 Each line group must have this form:
168 [+][\][[<remote>]:[:]]<branch> [--no-topmsg] [optional] [message] [here]
169 [[delete]:[:[:]][~]]<start>
174 Note that any <dep> lines must not be empty. If there are no <dep>s, then
175 there must be no <dep> lines at all.
177 See the description of `tg_test_create_branch` for the meaning of the
178 arguments. The provided <dirpath> and `--notick` options are passed along
179 on each call to `tg_test_create_branch`.
181 The "delete:[:[:]]<start>" form is an extension not handled by the
182 `tg_test_create_branch` function. With "delete", a message is forbidden,
183 no <dep> lines are allowed and if <start> is not empty the branch to be
184 deleted must have the specified <start> value for the delete to succeed.
185 If the "delete:::" (three colon) form is used then any pre-existing base(s)
186 are ignored otherwise they will be removed. Note that since there is only
187 one <start> value, if <start> is not empty, all refs (1, 2 or 4) to be
188 deleted must have that same <start> value. Also note that "delete:..."
189 never removes any tags. If <start> is left empty AND the leading "+" is
190 NOT present then all refs to be deleted must actually exist.
192 This function can be used to easily create a complicated deterministic
193 TopGit DAG for testing purposes. Since each line group represents a call
194 to `tg_test_create_branch`, later groups may use any branch name created
195 by an earlier group as a <start> point.
197 - tg_test_create_tag [-C <dir>] [--notick] [-t] <tag> [<for-each-ref-pat>...]
199 If no for-each-ref patterns are given then refs/heads, refs/top-bases and
200 refs/remotes are used. Only refs that have type `commit` will be put in
201 the tag. The result will be a new annotated tag <tag> that can be used
202 as a source for `tg revert` (and therefore the `tg -w` option too).
204 The for-each-ref-pat arguments are passed directly to `git for-each-ref`
205 and may therefore use all wildcard features available with that command.
207 Unlike ordinary `tg tag` tags, the resulting tags tag the empty blob (or
208 with -t the empty tree) and there is no consolidation commit made at all,
211 - tg_test_include [-C <dirpath>] [-r <remote>] [-u] [-f]
213 Source tg in `tg__include=1` mode to provide access to internal tg
216 If TG_TEST_FULL_PATH is unset a fatal error will occur.
218 The following options are available:
221 Temporarily `cd` to <dirpath> before sourcing `tg`, but then return
222 to the original `$PWD` afterwards.
224 Set `base_remote` to "<remote>" *before* sourcing `tg`.
226 Unset `base_remote` *after* sourcing `tg`.
228 Terminate with a fatal error instead of returning a non-0 result code
230 The `tg__include` variable will be left set to `1` after calling this
231 function. The `base_remote` variable will remain set/unset after calling
232 this function solely based on the presence/absence of any `-r` and/or `-u`
233 options and the behavior of the sourced `tg` file.
235 - tg_test_setup_topgit [-C <dirpath>] [-f]
237 Perform TopGit merge and hook setup for a repository if it's not already
240 If TG_TEST_FULL_PATH is unset a fatal error will occur.
242 The following options are available:
245 Temporarily `cd` to <dirpath> before sourcing `tg`, but then return
246 to the original `$PWD` afterwards.
248 Terminate with a fatal error instead of returning a non-0 result code
250 Other than the repository being setup there are no side effects (the
251 operation happens in a subshell). Note that the setup `pre-commit` script
252 will look for the basename of TG_TEST_FULL_PATH in PATH so the dirname of
253 TG_TEST_FULL_PATH must be in the PATH ahead of any other possible location
254 in order for the hook to actually run the TG_TEST_FULL_PATH version of
257 Normally this will always be guaranteed as the TG_TEST_FULL_PATH being
258 tested is located in the `bin-wrappers` directory which is always added to
259 the front of the PATH by the testing framework when TG_TEST_FULL_PATH is
260 using the `bin-wrappers` version. If TG_TEST_FULL_PATH has been set to
261 something else for some reason either use a different mechanism to set up
262 the `pre-commit` hook or arrange for the dirname of TG_TEST_FULL_PATH to
263 get added to the front of the PATH.
265 The following will make sure the hook uses the correct version of TopGit:
267 PATH="${TG_TEST_FULL_PATH%/*}:$PATH" && export PATH
269 But make sure that's at the top-level of a test script and not in a subtest
270 where its effects will be discared at the end of the subtest subshell.
272 - tg_test_v_getbases <varname> [<remotename>]
274 Set the variable named by <varname> to the appropriate full ref prefix for
275 local bases (if <remotename> is omitted or empty) or the specified remote
276 given by <remotename>.
278 The value of `tg_test_bases` influences the value (see the description of
279 the `tg_test_bases` variable above for details).
281 - tg_test_v_getremote <varname> [<remotename>]
283 Set the variable named by <varname> to "<remotename>" unless <remotename>
284 is omitted or empty in which case use "$tg_test_remote" unless it's empty
285 in which case die with a fatal error.