changeset 5442:25b746aea135

branching: merge with stable
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Fri, 24 Jul 2020 10:50:53 +0200
parents 2bfd0cc1b04c (current diff) d55e83faeaf8 (diff)
children 239071adc54f
files hgext3rd/evolve/evolvecmd.py
diffstat 6 files changed, 174 insertions(+), 104 deletions(-) [+]
line wrap: on
line diff
--- a/hgext3rd/evolve/__init__.py	Fri Jul 24 11:04:07 2020 +0530
+++ b/hgext3rd/evolve/__init__.py	Fri Jul 24 10:50:53 2020 +0200
@@ -179,7 +179,7 @@
 
 evolutionhelptext = b"""
 Obsolescence markers make it possible to mark changesets that have been
-deleted or superset in a new version of the changeset.
+deleted or superseded in a new version of the changeset.
 
 Unlike the previous way of handling such changes, by stripping the old
 changesets from the repository, obsolescence markers can be propagated
--- a/hgext3rd/evolve/obsexchange.py	Fri Jul 24 11:04:07 2020 +0530
+++ b/hgext3rd/evolve/obsexchange.py	Fri Jul 24 10:50:53 2020 +0200
@@ -52,7 +52,7 @@
 
 ARGUMENTS_LIMIT = 200
 
-OVERFLOW_MSG = """obsmarkers differ for %d common nodes
+OVERFLOW_MSG = b"""obsmarkers differ for %d common nodes
 |
 | This might be too much for the remote HTTP server that doesn't accept
 | arguments through POST request. (config: experimental.httppostargs=yes)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-evolve-wdir.t	Fri Jul 24 10:50:53 2020 +0200
@@ -0,0 +1,114 @@
+===============================================
+Testing evolution of obsolete working directory
+===============================================
+
+Pulling changes from other repos can make your working directory parent (wdir)
+obsolete, most probably because now it has a new successor. But there are
+other cases as well where it might be pruned with no successors or split
+in multiple changesets etc.
+
+This test file deals with all the possible cases for the evolution from an
+obsolete working directory parent.
+
+.. Case A: obsolete wdp with single successor
+..     Resolution : simply update to the successor
+..
+.. Case B: obsolete wdp with no successor (simply pruned)
+..     Resolution : update to a not-dead ancestor
+..
+.. Case C: obsolete wdp with multiple successor (divergence rewriting)
+..     Resolution : #TODO: not handled yet
+..
+.. Case D: obsolete wdp with multiple successor (split rewriting)
+..     Resolution : #TODO: not handled yet
+
+A. Obsolete wdp with single successor
+-------------------------------------
+
+Setup
+  $ . $TESTDIR/testlib/common.sh
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > evolve=
+  > rebase=
+  > [alias]
+  > glog = log --graph --template "{rev}:{node|short} ({phase}): {desc|firstline} {if(troubles, '[{troubles}]')}\n"
+  > EOF
+
+  $ hg init repo
+  $ cd repo
+  $ mkcommit c_A
+  $ mkcommit c_B
+  $ hg amend -m "u_B"
+  $ hg up -r 'desc(c_B)' --hidden
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  updated to hidden changeset 707ee88b2870
+  (hidden revision '707ee88b2870' was rewritten as: 9bf151312dec)
+  working directory parent is obsolete! (707ee88b2870)
+  (use 'hg evolve' to update to its successor: 9bf151312dec)
+
+  $ hg evolve
+  update:[2] u_B
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory is now at 9bf151312dec
+  $ hg glog
+  @  2:9bf151312dec (draft): u_B
+  |
+  o  0:9f0188af4c58 (draft): c_A
+  
+
+B. Obsolete wdp with no successor
+---------------------------------
+
+  $ hg prune .
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory is now at 9f0188af4c58
+  1 changesets pruned
+  $ hg up -r 'desc(c_B)' --hidden
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  updated to hidden changeset 707ee88b2870
+  (hidden revision '707ee88b2870' is pruned)
+  working directory parent is obsolete! (707ee88b2870)
+  (use 'hg evolve' to update to its parent successor)
+
+  $ hg evolve
+  update:[0] c_A
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory is now at 9f0188af4c58
+  $ hg glog
+  @  0:9f0188af4c58 (draft): c_A
+  
+
+C. Obsolete wdp with multiple successor (divergence rewriting)
+---------------------------------------------------------------
+
+  $ hg metaedit -r 'desc(u_B)' -d '0 1' --hidden
+  $ hg metaedit -r 'desc(c_B)' -d '0 1' --hidden
+  2 new content-divergent changesets
+  $ hg up -r 'min(desc(c_B))' --hidden
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  updated to hidden changeset 707ee88b2870
+  (hidden revision '707ee88b2870' has diverged)
+  working directory parent is obsolete! (707ee88b2870)
+  (707ee88b2870 has diverged, use 'hg evolve --list --content-divergent' to resolve the issue)
+
+  $ hg evolve
+  parent is obsolete with multiple successors:
+  [3] u_B
+  [4] c_B
+  [2]
+
+  $ hg glog
+  *  4:39e54eb7aa3c (draft): c_B [content-divergent]
+  |
+  | *  3:90624b574289 (draft): u_B [content-divergent]
+  |/
+  | @  1:707ee88b2870 (draft): c_B
+  |/
+  o  0:9f0188af4c58 (draft): c_A
+  
+
+D. Obsolete wdp with multiple successor (split rewriting)
+----------------------------------------------------------
+
+#TODO: yet to write tests for this case
--- a/tests/test-evolve.t	Fri Jul 24 11:04:07 2020 +0530
+++ b/tests/test-evolve.t	Fri Jul 24 10:50:53 2020 +0200
@@ -48,7 +48,7 @@
   """"""""""""""""""""""""
   
       Obsolescence markers make it possible to mark changesets that have been
-      deleted or superset in a new version of the changeset.
+      deleted or superseded in a new version of the changeset.
   
       Unlike the previous way of handling such changes, by stripping the old
       changesets from the repository, obsolescence markers can be propagated
--- a/tests/test-obsolete.t	Fri Jul 24 11:04:07 2020 +0530
+++ b/tests/test-obsolete.t	Fri Jul 24 10:50:53 2020 +0200
@@ -530,22 +530,17 @@
 
 should not rebase extinct changesets
 
-#excluded 'whole rebase set is extinct and ignored.' message not in core
-  $ hg rebase -b '3' -d 4 --traceback --config experimental.rebaseskipobsolete=0
-  rebasing 3:0d3f46688ccc "add obsol_c"
+  $ hg rebase -b '3' -d 4 --traceback
+  note: not rebasing 3:0d3f46688ccc "add obsol_c", already in destination as 4:725c380fe99b "add obsol_c'"
   rebasing 8:159dfc9fa5d3 "add obsol_d''"
-  2 new content-divergent changesets
-  $ hg --hidden log -q -r 'successors(3)'
+  $ hg --hidden log -q -r 'successors(min(desc("re:^add obsol_c$")))'
   4:725c380fe99b
-  10:2033b4e49474
   $ hg up tip
   ? files updated, 0 files merged, 0 files removed, 0 files unresolved (glob)
   $ hg log -G --template='{rev} - {node|short} {desc}\n'
-  @  11 - 9468a5f5d8b2 add obsol_d''
+  @  10 - 8396b69aa9f7 add obsol_d''
   |
-  *  10 - 2033b4e49474 add obsol_c
-  |
-  *  4 - 725c380fe99b add obsol_c'
+  o  4 - 725c380fe99b add obsol_c'
   |
   o  1 - 7c3bad9141dc add b
   |
@@ -561,14 +556,13 @@
   adding changesets
   adding manifests
   adding file changes
-  added 2 changesets with 1 changes to [12] files (re)
-  3 new obsolescence markers
+  added 1 changesets with 1 changes to 1 files
+  2 new obsolescence markers
   obsoleted 1 changesets
-  2 new content-divergent changesets
-  $ hg up -q 10
+  $ hg up -q 'desc("re:^add obsol_c'\''$")'
   $ mkcommit "obsol_d'''"
   created new head
-  $ hg debugobsolete `getid 11` `getid 12`
+  $ hg debugobsolete `getid 'max(desc("re:^add obsol_d'\'\''$"))'` `getid 'desc("re:^add obsol_d'\'\'\''$")'`
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg push ../other-new --traceback
@@ -586,15 +580,13 @@
 (make an obsolete changeset public)
 
   $ cd local
-  $ hg phase --hidden --public 11
+  $ hg phase --hidden --public 'max(desc("re:^add obsol_d'\'\''$"))'
   1 new phase-divergent changesets
   $ hg log -G --template='{rev} - ({phase}) {node|short} {desc}\n'
-  @  12 - (draft) 6db5e282cb91 add obsol_d'''
+  @  11 - (draft) 5a9eef7b778b add obsol_d'''
   |
-  | o  11 - (public) 9468a5f5d8b2 add obsol_d''
+  | o  10 - (public) 8396b69aa9f7 add obsol_d''
   |/
-  o  10 - (public) 2033b4e49474 add obsol_c
-  |
   o  4 - (public) 725c380fe99b add obsol_c'
   |
   o  1 - (public) 7c3bad9141dc add b
@@ -602,9 +594,9 @@
   o  0 - (public) 1f0dee641bb7 add a
   
   $ hg log -r 'phasedivergent()'
-  changeset:   12:6db5e282cb91
+  changeset:   11:5a9eef7b778b
   tag:         tip
-  parent:      10:2033b4e49474
+  parent:      4:725c380fe99b
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   instability: phase-divergent
@@ -613,7 +605,7 @@
   $ hg push ../other-new/
   pushing to ../other-new/
   searching for changes
-  abort: push includes phase-divergent changeset: 6db5e282cb91!
+  abort: push includes phase-divergent changeset: 5a9eef7b778b!
   (use 'hg evolve' to get a stable history or --force to ignore warnings)
   [255]
 
@@ -626,31 +618,26 @@
   $ echo 42 >> f
   $ hg commit --amend --traceback --quiet
   $ hg log -G
-  @  changeset:   14:705ab2a6b72e
+  @  changeset:   13:6491691ca36f
   |  tag:         tip
-  |  parent:      10:2033b4e49474
+  |  parent:      4:725c380fe99b
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     add f
   |
-  | *  changeset:   12:6db5e282cb91
-  |/   parent:      10:2033b4e49474
+  | *  changeset:   11:5a9eef7b778b
+  |/   parent:      4:725c380fe99b
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
   |    instability: phase-divergent
   |    summary:     add obsol_d'''
   |
-  | o  changeset:   11:9468a5f5d8b2
-  |/   user:        test
+  | o  changeset:   10:8396b69aa9f7
+  |/   parent:      4:725c380fe99b
+  |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
   |    summary:     add obsol_d''
   |
-  o  changeset:   10:2033b4e49474
-  |  parent:      4:725c380fe99b
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     add obsol_c
-  |
   o  changeset:   4:725c380fe99b
   |  parent:      1:7c3bad9141dc
   |  user:        test
@@ -675,77 +662,52 @@
   909a0fb57e5d909f353d89e394ffd7e0890fec88 159dfc9fa5d334d7e03a0aecfc7f7ab4c3431fea 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   1f0dee641bb7258c56bd60e93edfa2405381c41e 83b5778897adafb967ef2f75be3aaa4fce49a4cc 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   83b5778897adafb967ef2f75be3aaa4fce49a4cc 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
-  0d3f46688ccc6e756c7e96cf64c391c411309597 2033b4e494742365851fac84d276640cbf52833e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
-  159dfc9fa5d334d7e03a0aecfc7f7ab4c3431fea 9468a5f5d8b2c5d91e17474e95ae4791e9718fdf 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
-  9468a5f5d8b2c5d91e17474e95ae4791e9718fdf 6db5e282cb91df5c43ff1f1287c119ff83230d42 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
-  0b1b6dd009c037985363e2290a0b579819f659db 705ab2a6b72e2cd86edb799ebe15f2695f86143e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
-#no produced by 2.3
-33d458d86621f3186c40bfccd77652f4a122743e 3734a65252e69ddcced85901647a4f335d40de1e 0 {'date': '* *', 'user': 'test'} (glob)
+  159dfc9fa5d334d7e03a0aecfc7f7ab4c3431fea 8396b69aa9f7b4ea03ed94c63641e3c021d71f0c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
+  8396b69aa9f7b4ea03ed94c63641e3c021d71f0c 5a9eef7b778bf2ba5e6cc1b741ec5a2110ba1480 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  bc294e7f0681bbed7b83047814e9eadabead2f8d 6491691ca36ffa1b1c48d9bf8605ac5a25d200f6 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
 
 Check divergence detection (note: multiple successors is sorted by changeset hash)
 
-  $ hg up 9468a5f5d8b2 #  add obsol_d''
+  $ hg up 'max(desc("re:^add obsol_d'\'\''$"))' #  add obsol_d''
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ mkcommit "obsolet_conflicting_d"
   $ hg summary
-  parent: 15:50f11e5e3a63 tip
+  parent: 14:553bdab4dee8 tip
    add obsolet_conflicting_d
   branch: default
   commit: (clean)
   update: (2|9|11) new changesets, (3|9|10) branch heads \(merge\) (re)
   phases: 3 draft
   phase-divergent: 1 changesets
-  $ hg debugobsolete `getid a7a6f2b5d8a5` `getid 50f11e5e3a63`
+  $ hg debugobsolete `getid 'desc("re:^add d$")'` `getid 'desc("re:^add obsolet_conflicting_d$")'`
   1 new obsolescence markers
   2 new content-divergent changesets
   $ hg log -r 'contentdivergent()'
-  changeset:   12:6db5e282cb91
-  parent:      10:2033b4e49474
+  changeset:   11:5a9eef7b778b
+  parent:      4:725c380fe99b
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   instability: phase-divergent, content-divergent
   summary:     add obsol_d'''
   
-  changeset:   15:50f11e5e3a63
+  changeset:   14:553bdab4dee8
   tag:         tip
-  parent:      11:9468a5f5d8b2
+  parent:      10:8396b69aa9f7
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   instability: content-divergent
   summary:     add obsolet_conflicting_d
   
 
-  $ hg up --hidden 3 -q
-  updated to hidden changeset 0d3f46688ccc
-  (hidden revision '0d3f46688ccc' has diverged)
-  working directory parent is obsolete! (0d3f46688ccc)
-  $ hg evolve
-  parent is obsolete with multiple successors:
-  [4] add obsol_c'
-  [10] add obsol_c
-  [2]
-  $ hg olog -a
-  o  2033b4e49474 (10) add obsol_c
-  |    rebased(parent) from 0d3f46688ccc using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
-  |
-  | o  725c380fe99b (4) add obsol_c'
-  |/     rewritten from 0d3f46688ccc by test (Thu Jan 01 00:00:00 1970 +0000)
-  |
-  @  0d3f46688ccc (3) add obsol_c
-  |    rewritten from 4538525df7e2 by test (Thu Jan 01 00:00:00 1970 +0000)
-  |
-  x  4538525df7e2 (2) add c
-  
-
 Check import reports new unstable changeset:
 
-  $ hg up --hidden 2
-  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg up --hidden 'desc("re:^add c$")'
+  1 files updated, 0 files merged, 3 files removed, 0 files unresolved
   updated to hidden changeset 4538525df7e2
-  (hidden revision '4538525df7e2' has diverged)
+  (hidden revision '4538525df7e2' was rewritten as: 725c380fe99b)
   working directory parent is obsolete! (4538525df7e2)
-  (4538525df7e2 has diverged, use 'hg evolve --list --content-divergent' to resolve the issue)
-  $ hg export 9468a5f5d8b2 | hg import -
+  (use 'hg evolve' to update to its successor: 725c380fe99b)
+  $ hg export 'desc("re:^add obsol_d'\'\''$")' | hg import -
   applying patch from stdin
   1 new orphan changesets
 
@@ -754,7 +716,7 @@
 ==============================
 
   $ hg log -G --hidden
-  @  changeset:   16:a5f7a21fe7bc
+  @  changeset:   15:a5f7a21fe7bc
   |  tag:         tip
   |  parent:      2:4538525df7e2
   |  user:        test
@@ -762,44 +724,39 @@
   |  instability: orphan
   |  summary:     add obsol_d''
   |
-  | *  changeset:   15:50f11e5e3a63
-  | |  parent:      11:9468a5f5d8b2
+  | *  changeset:   14:553bdab4dee8
+  | |  parent:      10:8396b69aa9f7
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  instability: content-divergent
   | |  summary:     add obsolet_conflicting_d
   | |
-  | | o  changeset:   14:705ab2a6b72e
-  | | |  parent:      10:2033b4e49474
+  | | o  changeset:   13:6491691ca36f
+  | | |  parent:      4:725c380fe99b
   | | |  user:        test
   | | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | | |  summary:     add f
   | | |
-  | | | x  changeset:   13:0b1b6dd009c0
-  | | |/   parent:      10:2033b4e49474
+  | | | x  changeset:   12:bc294e7f0681
+  | | |/   parent:      4:725c380fe99b
   | | |    user:        test
   | | |    date:        Thu Jan 01 00:00:00 1970 +0000
-  | | |    obsolete:    amended using amend as 14:705ab2a6b72e
+  | | |    obsolete:    amended using amend as 13:6491691ca36f
   | | |    summary:     add f
   | | |
-  | | | *  changeset:   12:6db5e282cb91
-  | | |/   parent:      10:2033b4e49474
+  | | | *  changeset:   11:5a9eef7b778b
+  | | |/   parent:      4:725c380fe99b
   | | |    user:        test
   | | |    date:        Thu Jan 01 00:00:00 1970 +0000
   | | |    instability: phase-divergent, content-divergent
   | | |    summary:     add obsol_d'''
   | | |
-  | o |  changeset:   11:9468a5f5d8b2
-  | |/   user:        test
+  | o |  changeset:   10:8396b69aa9f7
+  | |/   parent:      4:725c380fe99b
+  | |    user:        test
   | |    date:        Thu Jan 01 00:00:00 1970 +0000
   | |    summary:     add obsol_d''
   | |
-  | o  changeset:   10:2033b4e49474
-  | |  parent:      4:725c380fe99b
-  | |  user:        test
-  | |  date:        Thu Jan 01 00:00:00 1970 +0000
-  | |  summary:     add obsol_c
-  | |
   | | x  changeset:   9:83b5778897ad
   | |    parent:      -1:000000000000
   | |    user:        test
@@ -811,7 +768,7 @@
   | | |  parent:      3:0d3f46688ccc
   | | |  user:        test
   | | |  date:        Thu Jan 01 00:00:00 1970 +0000
-  | | |  obsolete:    rebased using rebase as 11:9468a5f5d8b2
+  | | |  obsolete:    rebased using rebase as 10:8396b69aa9f7
   | | |  summary:     add obsol_d''
   | | |
   | | | x  changeset:   7:909a0fb57e5d
@@ -833,7 +790,7 @@
   | | |    user:        test
   | | |    date:        Thu Jan 01 00:00:00 1970 +0000
   | | |    obsolete:    rewritten as 6:95de7fc6918d
-  | | |    obsolete:    rewritten as 15:50f11e5e3a63
+  | | |    obsolete:    rewritten as 14:553bdab4dee8
   | | |    summary:     add d
   | | |
   | o |  changeset:   4:725c380fe99b
@@ -847,7 +804,6 @@
   | |    user:        test
   | |    date:        Thu Jan 01 00:00:00 1970 +0000
   | |    obsolete:    rewritten as 4:725c380fe99b
-  | |    obsolete:    rebased using rebase as 10:2033b4e49474
   | |    summary:     add obsol_c
   | |
   x |  changeset:   2:4538525df7e2
@@ -869,17 +825,17 @@
 
 Simple rewrite
 
-  $ hg  --hidden debugobsolete --rev 3
+  $ hg  --hidden debugobsolete --rev 'min(desc("re:^add obsol_c$"))'
   4538525df7e2b9f09423636c61ef63a4cb872a2d 0d3f46688ccc6e756c7e96cf64c391c411309597 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
 
 simple rewrite with a prune attached to it
 
-  $ hg debugobsolete --rev 15
-  a7a6f2b5d8a54b81bc7aa2fba2934ad6d700a79e 50f11e5e3a63806e678c734e525502f522d37e38 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ hg debugobsolete --rev 'desc("re:^add obsolet_conflicting_d$")'
+  a7a6f2b5d8a54b81bc7aa2fba2934ad6d700a79e 553bdab4dee8f0032cd60de38be72d1d2e8225d5 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
 
 Transitive rewrite
 
-  $ hg --hidden debugobsolete --rev 8
+  $ hg --hidden debugobsolete --rev 'min(desc("re:^add obsol_d'\'\''$"))'
   909a0fb57e5d909f353d89e394ffd7e0890fec88 159dfc9fa5d334d7e03a0aecfc7f7ab4c3431fea 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   95de7fc6918dea4c9c8d5382f50649794b474c4a 909a0fb57e5d909f353d89e394ffd7e0890fec88 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   a7a6f2b5d8a54b81bc7aa2fba2934ad6d700a79e 95de7fc6918dea4c9c8d5382f50649794b474c4a 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- a/tests/test-topic-rebase.t	Fri Jul 24 11:04:07 2020 +0530
+++ b/tests/test-topic-rebase.t	Fri Jul 24 10:50:53 2020 +0200
@@ -127,7 +127,7 @@
   merging file
   warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
   switching to topic myotherfeature
-  unresolved conflicts (see hg resolve, then hg rebase --continue)
+  unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
   [1]
 
 Resolve the conflict