Topbloke patch is: - branch in refs/topbloke-tips/ contains the working version, fast-forwarding - branch in refs/topbloke-bases/ contains the base version, being the pulling merge of all the bases In-tree, there are metadata files in .topbloke Files which are per-patch and do not inherit any contents or changes from bases or dependencies: msg patch "commit message" exists only in tip branch EDITED BY USER patch name of this topbloke patch (plus a newline) exists in base and tip, identical value base commit id of corresponding base B(C) exists only in tip branch this is how we tell tip from base commits deps direct dependencies, one per line as either: - exists only in base branch deleted exists (but empty) if patch is deleted exists only in tip branch #TBD# topgit- name of the topgit branch that this was #TBD# imported from and which we should merge from #TBD# (plus a newline) #TBD# exists only in base branch [^+]*- another property that applies to this patch; if not known to this version of topbloke then it is safe to: - merge this file as text when merging from base into base, or tip into tip, and perhaps ask user to fix up conflicts after warning if they feel expert - throw away this file when merging from from dep into base or base into tip Files which inherit contents and changes from dependencies have names starting with "+": +included actual included deps, one per line format as for deps, only includes topbloke patches exists in tip and base branches +ends list of ends E(C,Px+) format is one line per Px for which E(C,Px+) != { } the line contains the patch name Px plus the commit object names for E(C,Px+), separated by spaces in the case of tip commits, the commit's patch is not listed; for these implicitly E(C,Px+) = { C } always exists in tip and base branches, perhaps as an empty file +*- another property that is inherited; it is also safe to: - merge this file as text when merging from tb dep into base, base into tip or tip into tip Any unknown metadata files not ending in "-" are fatal: tb will refuse to operate on patches either of whose branches have such files. has the format: @/--
TZ/ where none of nickname-path's components may start with a digit or contain ~ or @ (: is not allowed in refs hence the squashing after T) eg ijackson@chiark.greenend.org.uk/2012-01-20T225127Z/reorg/sponge NB only exactly that date format is allowed and timezone must be Z. Patches may be specified with this grammar: spec := lump | lump ',' spec lump := datetime-spec ('/' email-spec) [abs-path] | email-spec ('/' datetime-spec) [abs-path] | '/' abs-path | rel-path abs-path = '/' path-tail rel-path := path-tail # Interpretation depends on current patch nickname path: # each path-component replaces one path-component from the # current path, starting from the rhs, so that the specified # nickname path has the same number of components. # Matching patches are only those with an identical nickname path path-tail := path-component | path-component '/' rel-path email-spec := [email-local-part] '@' [domain-name] # If email-local-part is specified, matches only identical ones. # If domain-name is specified, matches only identical ones. # If no email-spec is specified at all (not even an empty one) # then we search as follows: # 1. Are there any patches with the same email address as # our current patch, which match the rest of the spec ? # If so, only those are considered. # 2. Otherwise, are there any patches datetime-spec := nearby-date-spec | datetime-pattern datetime-pattern := date-pattern | [date-pattern] 'T' time-pattern # Matching patches are those which match on all specified # components. The chosen patch is the most recent one # which matches everything in the spec. date-pattern := [[ year '-' ] [month] '-' ] [mday] year := | month := | | month-name mday :=
| time-pattern := [ [ [ ]]] nearby-date-spec := some string containing '~' # Each '~' is replaced with ' ' and then the result is # fed to date -d. Of the matching patches (ie with any date) # the one matching all the rest of the spec but with # the date closest to that specified is chosen. path-component := anything valid in a git ref name but no ',' or '/' or '@' and not starting with digit email-local-part := has the syntax of a valid git ref name without any '@' or '/' or ',' Patch specification semantics: * Calling context provides a scope, which restricts the set of possible patches. * If no email address in spec, look for patches in that set whose email address is the same as the user's email address. * ... ??? Search algorithm: 1. prefer patches with email address (or domain) matching current patch 2. prefer patches with our own email address (or domain) 3. other patches Within this there may be patches with multiple dates; prefer the most recent. So overall, if the current patch is ijackson@chiark.greenend.org.uk/2011-08-20T120320Z/fixes/pudding then all of the following can refer to the same patch ijackson@chiark.greenend.org.uk/2012-01-20T225127Z/reorg/sponge sponge reorg/sponge /reorg/sponge sponge,2012 2012,/reorg/sponge ijackson@,sponge sponge,ijackson@ ijackson@,reorg/sponge ijackson@,/reorg/sponge jan~,sponge ijackson@chiark.greenend.org.uk,sponge sponge reorg/sponge /reorg/sponge 2012/reorg/sponge jan~/reorg/sponge ijackson@/reorg/sponge ijackson@/2012/reorg/sponge ijackson@chiark.greenend.org.uk/reorg/sponge Other notes re searching and patch identification: ??? if using series defined by tips, how to stop other people stealing our tips - have a way to limit refs pull by email address have a way to limit head overlappingness by email address pairs, stops other people extending your series series name in each patch ? some patches marked as definitely series tip ? some bases marked as definitively series base ? "insert after this patch, rewrite all deps everywhere" option ?