chiark / gitweb /
FORMAT: put deps etc. in base branch where we need them
[topbloke.git] / DESIGN
diff --git a/DESIGN b/DESIGN
index a7c142b3cefbeed0f09d5129d1caa4efaad527b5..0d5215ff78431c0cc0a1b9b69000e6785ece8396 100644 (file)
--- 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