Patchwork D12181: narrow: add support for merging add and remove outside of the tracked set

login
register
mail settings
Submitter phabricator
Date Feb. 15, 2022, 9:30 a.m.
Message ID <differential-rev-PHID-DREV-ic7746clik7orypmlyui-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/50516/
State New
Headers show

Comments

phabricator - Feb. 15, 2022, 9:30 a.m.
marmoute created this revision.
Herald added a reviewer: durin42.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  This extend f1eb77dceb36 <https://phab.mercurial-scm.org/rHGf1eb77dceb360ff3590a10ca8f7efb7629193fd5> to test and support the remaining action. Or, at least,
  the simple incarnation of them.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D12181

AFFECTED FILES
  mercurial/commit.py
  mercurial/merge.py
  tests/test-narrow-merge-outside.t

CHANGE DETAILS




To: marmoute, durin42, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/tests/test-narrow-merge-outside.t b/tests/test-narrow-merge-outside.t
new file mode 100644
--- /dev/null
+++ b/tests/test-narrow-merge-outside.t
@@ -0,0 +1,111 @@ 
+===================================================================
+Test merge behavior with narrow for item outside of the narrow spec
+===================================================================
+
+This test currently check for  simple "outside of narrow" merge case. I suspect
+there might be more corner case that need testing, so extending this tests, or
+replacing it by a more "generative" version, comparing behavior with and without narow.
+
+This the feature is currently working with flat manifest only. This is the only
+case tested. Consider using test-case if tree start supporting this case of
+merge.
+
+Create some initial setup
+
+  $ . "$TESTDIR/narrow-library.sh"
+
+  $ hg init server
+  $ echo root > server/root
+  $ mkdir server/inside
+  $ mkdir server/outside
+  $ echo babar > server/inside/inside-change
+  $ echo pom > server/outside/outside-changing
+  $ echo arthur > server/outside/outside-removed
+  $ hg -R server add server/
+  adding server/inside/inside-change
+  adding server/outside/outside-changing
+  adding server/outside/outside-removed
+  adding server/root
+  $ hg -R server commit -m root
+
+
+
+  $ hg clone ssh://user@dummy/server client --narrow --include inside
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets a0c415d360e5
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+"trivial" change outside of narrow spec on the server
+
+  $ echo zephir > server/outside/outside-added
+  $ hg -R server add server/outside/outside-added
+  $ echo flore > server/outside/outside-changing
+  $ hg -R server remove server/outside/outside-removed
+  $ hg -R server commit -m "outside change"
+
+Merge them with some unrelated local change
+
+  $ echo celeste > client/inside/inside-change
+  $ hg -R client commit -m "inside change"
+  $ hg -R client pull
+  pulling from ssh://user@dummy/server
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 0 changes to 0 files (+1 heads)
+  new changesets f9ec5453023e
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg -R client merge
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg -R client ci -m 'merge changes'
+  $ hg -R client push -r .
+  pushing to ssh://user@dummy/server
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 1 changes to 1 files
+
+Checking result
+---------------
+
+general sentry of all output
+
+  $ hg --repository server manifest --debug --rev 0
+  360afd990eeff79e4a7f9f3ded5ecd7bc2fd3b59 644   inside/inside-change
+  7db95ce5cd8e734ad12e3f5f37779a08070a1399 644   outside/outside-changing
+  1591f6db41a30b68bd94ddccf4a4ce4f4fbe2a44 644   outside/outside-removed
+  50ecbc31c0e82dd60c2747c434d1f11b85c0e178 644   root
+  $ hg --repository server manifest --debug --rev 1
+  360afd990eeff79e4a7f9f3ded5ecd7bc2fd3b59 644   inside/inside-change
+  486c008d6dddcaeb5e5f99556a121800cdcfb149 644   outside/outside-added
+  153d7af5e4f53f44475bc0ff2b806c86f019eda4 644   outside/outside-changing
+  50ecbc31c0e82dd60c2747c434d1f11b85c0e178 644   root
+
+  $ hg --repository server manifest --debug --rev 2
+  1b3ab69c6c847abc8fd25537241fedcd4d188668 644   inside/inside-change
+  7db95ce5cd8e734ad12e3f5f37779a08070a1399 644   outside/outside-changing
+  1591f6db41a30b68bd94ddccf4a4ce4f4fbe2a44 644   outside/outside-removed
+  50ecbc31c0e82dd60c2747c434d1f11b85c0e178 644   root
+  $ hg --repository server manifest --debug --rev 3
+  1b3ab69c6c847abc8fd25537241fedcd4d188668 644   inside/inside-change
+  486c008d6dddcaeb5e5f99556a121800cdcfb149 644   outside/outside-added
+  153d7af5e4f53f44475bc0ff2b806c86f019eda4 644   outside/outside-changing
+  50ecbc31c0e82dd60c2747c434d1f11b85c0e178 644   root
+
+The file changed outside should be changed by the merge
+
+  $ hg --repository server manifest --debug --rev 'desc("inside change")' | grep outside-changing
+  7db95ce5cd8e734ad12e3f5f37779a08070a1399 644   outside/outside-changing
+
+  $ hg --repository server manifest --debug --rev 'desc("outside change")' | grep outside-changing
+  153d7af5e4f53f44475bc0ff2b806c86f019eda4 644   outside/outside-changing
+  $ hg --repository server manifest --debug --rev 'desc("merge")' | grep outside-changing
+  153d7af5e4f53f44475bc0ff2b806c86f019eda4 644   outside/outside-changing
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -519,10 +519,7 @@ 
         elif action[0].no_op:
             mresult.removefile(f)  # merge does not affect file
         elif action[0].narrow_safe:
-            if (
-                not f.endswith(b'/')
-                and action[0].changes == mergestatemod.CHANGE_MODIFIED
-            ):
+            if not f.endswith(b'/'):
                 mresult.removefile(f)  # merge won't affect on-disk files
 
                 mresult.addcommitinfo(
diff --git a/mercurial/commit.py b/mercurial/commit.py
--- a/mercurial/commit.py
+++ b/mercurial/commit.py
@@ -211,7 +211,16 @@ 
         repo.ui.note(uipathfn(f) + b"\n")
         if f in narrow_files:
             narrow_action = narrow_files.get(f)
-            if narrow_action == mergestate.CHANGE_MODIFIED:
+            if narrow_action == mergestate.CHANGE_REMOVED:
+                files.mark_removed(f)
+                removed.append(f)
+            elif narrow_action == mergestate.CHANGE_ADDED:
+                files.mark_added(f)
+                added.append(f)
+                m[f] = m2[f]
+                flags = m2ctx.find(f)[1] or b''
+                m.setflag(f, flags)
+            elif narrow_action == mergestate.CHANGE_MODIFIED:
                 files.mark_touched(f)
                 added.append(f)
                 m[f] = m2[f]