changeset 5784:43a5371fa669

divergence-resolution: add support and doc for a special case in divergence Changes in troubles-handling.rst explains the special case in details and also speak about what is the default behavior and how to change it.
author Sushil khanchi <sushilkhanchi97@gmail.com>
date Thu, 18 Feb 2021 23:37:41 +0530
parents c5c879fed91c
children a9ad01ed1539
files docs/troubles-handling.rst hgext3rd/evolve/__init__.py hgext3rd/evolve/evolvecmd.py tests/test-check-sdist.t tests/test-evolve-content-divergent-case-B1.t
diffstat 5 files changed, 224 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/docs/troubles-handling.rst	Mon Feb 01 23:54:53 2021 +0530
+++ b/docs/troubles-handling.rst	Thu Feb 18 23:37:41 2021 +0530
@@ -323,6 +323,21 @@
 
 Set the parent of moved changeset as resolution parent.
 
+Special-case: When parent of moved one is obsolete with a successor
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+By default, evolution will set the successor of obsolete parent as resolution
+parent and will relocate both the divergent cset on it to perform 3-way merge.
+But if the following config is set to True, it will set the obsolete parent as
+resolution parent, so now resolved cset will be orphan, as it will be based on
+the obsolete parent. Some users might not like the evolve to automatically
+resovle this orphan instability as well (while they only wanted to resolve the
+divergence), which is why we are providing this config.
+
+`experimental.evolution.divergence-resolution-minimal=False(default)`
+
+(The default resolution that automatically evolve the orphan instability as well
+seems the best approach for now, but let's also gather user feedback, then we can decide accordingly)
+
 D-A3.2: both moved forward; same branch
 """""""""""""""""""""""""""""""""""""""
 
--- a/hgext3rd/evolve/__init__.py	Mon Feb 01 23:54:53 2021 +0530
+++ b/hgext3rd/evolve/__init__.py	Thu Feb 18 23:37:41 2021 +0530
@@ -348,6 +348,7 @@
 # Configuration
 eh.configitem(b'experimental', b'evolutioncommands', [])
 eh.configitem(b'experimental', b'evolution.allnewcommands', None)
+eh.configitem(b'experimental', b'evolution.divergence-resolution-minimal', False)
 eh.configitem(b'experimental', b'evolution.in-memory', b'false')
 
 #####################################################################
--- a/hgext3rd/evolve/evolvecmd.py	Mon Feb 01 23:54:53 2021 +0530
+++ b/hgext3rd/evolve/evolvecmd.py	Thu Feb 18 23:37:41 2021 +0530
@@ -318,7 +318,7 @@
 
     otherp1 = succsotherp1 = other.p1().rev()
     divp1 = succsdivp1 = divergent.p1().rev()
-    succsbasep1 = base.p1().rev()
+    basep1 = succsbasep1 = base.p1().rev()
 
     # finding single successors of divp1 and otherp1
     try:
@@ -387,6 +387,14 @@
             resolutionparent = succsotherp1
         else:
             pass
+        # a special case of 3) where parent of moved one is obsolete with a
+        # successor. Also, look at section 'D-A3.1' in troubles-handling.rst
+        minimal_resolution = (
+            ui.configbool(b'experimental', b'evolution.divergence-resolution-minimal')
+            and succsdivp1 == succsotherp1 and basep1 in (divp1, otherp1)
+        )
+        if minimal_resolution:
+            resolutionparent = otherp1 if basep1 == divp1 else divp1
     else:
         # the nullrev has to be handled specially because -1 is overloaded to both
         # mean nullrev (this meaning is used for the result of changectx.rev(), as
--- a/tests/test-check-sdist.t	Mon Feb 01 23:54:53 2021 +0530
+++ b/tests/test-check-sdist.t	Thu Feb 18 23:37:41 2021 +0530
@@ -27,7 +27,7 @@
 
   $ tar -tzf hg-evolve-*.tar.gz | sed 's|^hg-evolve-[^/]*/||' | sort > files
   $ wc -l files
-  345 files
+  346 files
   $ fgrep debian files
   tests/test-check-debian.t
   $ fgrep __init__.py files
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-evolve-content-divergent-case-B1.t	Thu Feb 18 23:37:41 2021 +0530
@@ -0,0 +1,198 @@
+===============================================
+Testing content-divergence resolution: Case B.1
+===============================================
+
+Independent rewrites of same changeset can lead to content-divergence. In most
+common cases, it can occur when multiple users rewrite the same changeset
+independently and push it.
+
+This test belongs to a series of tests checking the resolution of content-divergent
+changesets.
+
+Category B: parents are obsolete
+Testcase 1: one side amended changes and other rebased to in-between successor of basep1
+Variants:
+# a: default resolution
+# b: minimal resolution using `experimental.evolution.divergence-resolution-minimal=True`
+
+B.1 Relocated backward; Rebased to parent's successor
+=====================================================
+
+.. (Divergence reason):
+..    local: rebased to the 'in-between' successor of basep1
+..    other: amended some changes
+.. The default resolution here is that we choose the final successor as resolution parent,
+.. but this behavior can be changed to use the 'in-between' successor as resolution parent
+.. by using a config option `experimental.evolution.divergence-resolution-minimal=True`
+..
+.. This test case is considered complicated and can change its behavior acc. to the user
+.. feedback. For more, please look at section 'D-A3.1' in troubles-handling.rst
+..
+.. (local):
+..
+..      B ø → ○ B'
+..        |   |
+..      A ø → ø A' → ○ A''
+..        |   |      |
+..        |----      |
+..        |-----------
+..        |
+..      O ●
+..
+.. (other):
+..
+..      B ø→○ B'
+..        | /
+..      A ○
+..        |
+..      O ●
+..
+.. (Resolution):
+..
+..     ○ B'''
+..     |
+..     ○ A''
+..     |
+..     ● O
+..
+
+Setup
+-----
+  $ . $TESTDIR/testlib/content-divergence-util.sh
+  $ setuprepos B.1
+  creating test repo for test case B.1
+  - upstream
+  - local
+  - other
+  cd into `local` and proceed with env setup
+
+initial
+
+  $ cd upstream
+  $ mkcommit A
+  $ mkcommit B
+  $ cd ../local
+  $ hg pull -qu
+  $ hg prev
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [1] A
+  $ echo fooA >> A
+  $ hg amend -m 'new_A'
+  1 new orphan changesets
+  $ hg evolve
+  move:[2] B
+  atop:[3] new_A
+  $ echo barA >> A
+  $ hg amend -m 'latest_A'
+  1 new orphan changesets
+
+  $ cd ../other
+  $ hg pull -qu
+  $ echo fooB > B
+  $ hg amend -m 'new_B'
+  $ hg push -q
+
+  $ cd ../local
+  $ hg push -fq
+  2 new orphan changesets
+  2 new content-divergent changesets
+  $ hg pull -q
+  1 new orphan changesets
+  2 new content-divergent changesets
+
+
+Actual test of resolution
+-------------------------
+
+Variant_a: default resolution
+-----------------------------
+  $ hg evolve -l
+  429afd16ac76: B
+    orphan: 1ffcccee011c (obsolete parent)
+    content-divergent: 807cc2b37fb3 (draft) (precursor f6fbb35d8ac9)
+  
+  807cc2b37fb3: new_B
+    orphan: f5bc6836db60 (obsolete parent)
+    content-divergent: 429afd16ac76 (draft) (precursor f6fbb35d8ac9)
+  
+  $ hg log -G
+  *  6:807cc2b37fb3 (draft): new_B [orphan content-divergent]
+  |
+  | @  5:45ed635c7cfc (draft): latest_A
+  | |
+  | | *  4:429afd16ac76 (draft): B [orphan content-divergent]
+  | | |
+  | | x  3:1ffcccee011c (draft): new_A
+  | |/
+  x |  1:f5bc6836db60 (draft): A
+  |/
+  o  0:a9bdc8b26820 (public): O
+  
+  $ hg evolve --content-divergent
+  merge:[4] B
+  with: [6] new_B
+  base: [2] B
+  rebasing "divergent" content-divergent changeset 429afd16ac76 on 45ed635c7cfc
+  rebasing "other" content-divergent changeset 807cc2b37fb3 on 45ed635c7cfc
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+  $ hg log -G
+  o  9:6f740085e668 (draft): new_B
+  |
+  @  5:45ed635c7cfc (draft): latest_A
+  |
+  o  0:a9bdc8b26820 (public): O
+  
+  $ hg evolve -l
+
+
+Variant_b: minimal resolution
+-----------------------------
+
+  $ cd ../other
+  $ hg pull -q
+  2 new orphan changesets
+  2 new content-divergent changesets
+  $ hg evolve -l
+  807cc2b37fb3: new_B
+    orphan: f5bc6836db60 (obsolete parent)
+    content-divergent: 429afd16ac76 (draft) (precursor f6fbb35d8ac9)
+  
+  429afd16ac76: B
+    orphan: 1ffcccee011c (obsolete parent)
+    content-divergent: 807cc2b37fb3 (draft) (precursor f6fbb35d8ac9)
+  
+  $ hg log -G
+  o  6:45ed635c7cfc (draft): latest_A
+  |
+  | *  5:429afd16ac76 (draft): B [orphan content-divergent]
+  | |
+  | x  4:1ffcccee011c (draft): new_A
+  |/
+  | @  3:807cc2b37fb3 (draft): new_B [orphan content-divergent]
+  | |
+  | x  1:f5bc6836db60 (draft): A
+  |/
+  o  0:a9bdc8b26820 (public): O
+  
+  $ hg evolve --content-divergent --config experimental.evolution.divergence-resolution-minimal=True
+  merge:[3] new_B
+  with: [5] B
+  base: [2] B
+  rebasing "divergent" content-divergent changeset 807cc2b37fb3 on 1ffcccee011c
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory is now at 2431e876af63
+
+  $ hg log -G
+  @  8:2431e876af63 (draft): new_B [orphan]
+  |
+  | o  6:45ed635c7cfc (draft): latest_A
+  | |
+  x |  4:1ffcccee011c (draft): new_A
+  |/
+  o  0:a9bdc8b26820 (public): O
+  
+  $ hg evolve -l
+  2431e876af63: new_B
+    orphan: 1ffcccee011c (obsolete parent)
+