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
     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.
 
 
        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
        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
           * 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.
        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
        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)
          * 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
          * 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
        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
 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