X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=topbloke.git;a=blobdiff_plain;f=DESIGN;h=0d5215ff78431c0cc0a1b9b69000e6785ece8396;hp=a7c142b3cefbeed0f09d5129d1caa4efaad527b5;hb=3e8d721402b8e907a2658ef86ce9c05756f85c56;hpb=e7a04f5c030191f438b9556cd0701d1cd4950589 diff --git a/DESIGN b/DESIGN index a7c142b..0d5215f 100644 --- a/DESIGN +++ b/DESIGN @@ -17,7 +17,8 @@ Basic update algorithm: ii. For each source in the best order, do the following merge: (Our base has sources: - the branch for each direct dep - - the remote base) + - the remote base + - the topgit base, if this is a topgit import) Find the (latest) common ancestor. @@ -32,8 +33,8 @@ Basic update algorithm: For each unwanted dependency removal (ie for each such branch), search as follows: * An "unwanted removal commit" is a non-merge commit in the - history of the source, which unwantedly removes the dep - from the actual included deps. + history of the source, which removes the dep from the + actual included deps. * But the search stops at any point where we would have to traverse a commit where .topbloke/deps is empty (which stops us looking into the hitory of non-topbloke-controlled @@ -61,6 +62,10 @@ Basic update algorithm: from the source. iii. + Check whether our list of dependencies has changed. If so + we need to restart the whole base update. + + iv. Check for missing or unwanted dependency inclusions. Compare our base's desired included deps with our base's actual included deps. In exceptional conditions, they will not @@ -86,12 +91,14 @@ Basic update algorithm: * Attempt to apply the appropriate diff to add (resp. remove) the contents of the relevant patch (adjusted appropriately for metadata, XXX??? particularly the actual inclusion list) + XXX if we want to add a dep we need to update the dep first * Go round again looking for another discrepancy. 3. Update our branch. Our branch has sources: - our base - the remote for our branch + - the topgit branch, if this is a topgit import For each source in the best order, do the merge. Double-check the actual dependency inclusions. In @@ -186,3 +193,52 @@ Unnecessary - instead, deal with leaf patches Operations like "go up the stack", goes towards leaf. Hopefully unique. "Down" the stack, uses a "conventional" linearisation Stack reordering op ? auto adjust deps + + +When merging, we need to DTRT with our metadata. +Do this by running write-tree/read-tree etc. ourselves ? +For a source we're merging from, we make a version where the +metadata we shouldn't be merging is removed ? +Or something. +Have discovered that specifying a custom merge driver for a file does +not have any effect if the three-way-merge looks trivial based +on looking at the file contents - at least, if you use git-merge. + +Only thing which knows how to do all the gitattributes stuff and +conflict markers and what have you is git-merge. (git-merge-tree does +too but the output format is unsuitable.) "git-merge-index +... git-merge-one-file" does not honour the merge drivers and is, +contrary to what the git docs seem to suggest but don't actually +state, not actualy used by git-merge. + +OK so here is a plan: + Use git-merge --no-commit + Perhaps on a HEAD, and/or against a tree, which have been massaged + to make the metadata suitable as input. + Filtering out the "merge was successful but we aren't committing" + message. Use a single pipe for stdout/stderr to get interleaving + right; the message from git-merge is not i18n'd. + Afterwards we: + Check for merge success in the index and compare to exit status + from git-merge (which is 1 if the merge failed). + Adjust the metadata. + Print appropriate big fat warnings if we have merge conflicts in our + metadata. + Commit, adjusting the parents of the new commit to the original + parents if we made the merge with special massaged parents. + We may still need to have custom merge drivers for metadata. + + +Strategies for each metadata file merge: + + in base/tip same patch & branch dep -> base base -> tip + + msg T textual merge rm from src not in src + deps B list merge rm from src rm from src + deleted T std existence merge rm from src not in src + patch- BT must be same rm from src must be same + topgit- B std exist/text merge rm from src rm from src + [^+]*- ?? textual merge rm from src rm from src + +included BT list merge rm from non-tb src list merge + +*- ?? textual merge rm from non-tb src textual merge + *[^-] ?? die, aborting all ops, if found in any tb src or branch