##// END OF EJS Templates
merge: return a mergeresult obj from manifestmerge(), calculateupdates() (API)...
Pulkit Goyal -
r45831:0e18861f default
parent child Browse files
Show More
@@ -217,7 +217,7 b' class mercurial_sink(common.converter_si'
217 """
217 """
218 anc = [p1ctx.ancestor(p2ctx)]
218 anc = [p1ctx.ancestor(p2ctx)]
219 # Calculate what files are coming from p2
219 # Calculate what files are coming from p2
220 actions, diverge, rename = mergemod.calculateupdates(
220 mresult = mergemod.calculateupdates(
221 self.repo,
221 self.repo,
222 p1ctx,
222 p1ctx,
223 p2ctx,
223 p2ctx,
@@ -228,7 +228,7 b' class mercurial_sink(common.converter_si'
228 followcopies=False,
228 followcopies=False,
229 )
229 )
230
230
231 for file, (action, info, msg) in pycompat.iteritems(actions):
231 for file, (action, info, msg) in pycompat.iteritems(mresult.actions):
232 if source.targetfilebelongstosource(file):
232 if source.targetfilebelongstosource(file):
233 # If the file belongs to the source repo, ignore the p2
233 # If the file belongs to the source repo, ignore the p2
234 # since it will be covered by the existing fileset.
234 # since it will be covered by the existing fileset.
@@ -543,16 +543,16 b' def overridecalculateupdates('
543 origfn, repo, p1, p2, pas, branchmerge, force, acceptremote, *args, **kwargs
543 origfn, repo, p1, p2, pas, branchmerge, force, acceptremote, *args, **kwargs
544 ):
544 ):
545 overwrite = force and not branchmerge
545 overwrite = force and not branchmerge
546 actions, diverge, renamedelete = origfn(
546 mresult = origfn(
547 repo, p1, p2, pas, branchmerge, force, acceptremote, *args, **kwargs
547 repo, p1, p2, pas, branchmerge, force, acceptremote, *args, **kwargs
548 )
548 )
549
549
550 if overwrite:
550 if overwrite:
551 return actions, diverge, renamedelete
551 return mresult
552
552
553 # Convert to dictionary with filename as key and action as value.
553 # Convert to dictionary with filename as key and action as value.
554 lfiles = set()
554 lfiles = set()
555 for f in actions:
555 for f in mresult.actions:
556 splitstandin = lfutil.splitstandin(f)
556 splitstandin = lfutil.splitstandin(f)
557 if splitstandin is not None and splitstandin in p1:
557 if splitstandin is not None and splitstandin in p1:
558 lfiles.add(splitstandin)
558 lfiles.add(splitstandin)
@@ -561,8 +561,8 b' def overridecalculateupdates('
561
561
562 for lfile in sorted(lfiles):
562 for lfile in sorted(lfiles):
563 standin = lfutil.standin(lfile)
563 standin = lfutil.standin(lfile)
564 (lm, largs, lmsg) = actions.get(lfile, (None, None, None))
564 (lm, largs, lmsg) = mresult.actions.get(lfile, (None, None, None))
565 (sm, sargs, smsg) = actions.get(standin, (None, None, None))
565 (sm, sargs, smsg) = mresult.actions.get(standin, (None, None, None))
566 if sm in (b'g', b'dc') and lm != b'r':
566 if sm in (b'g', b'dc') and lm != b'r':
567 if sm == b'dc':
567 if sm == b'dc':
568 f1, f2, fa, move, anc = sargs
568 f1, f2, fa, move, anc = sargs
@@ -578,14 +578,22 b' def overridecalculateupdates('
578 % lfile
578 % lfile
579 )
579 )
580 if repo.ui.promptchoice(usermsg, 0) == 0: # pick remote largefile
580 if repo.ui.promptchoice(usermsg, 0) == 0: # pick remote largefile
581 actions[lfile] = (b'r', None, b'replaced by standin')
581 mresult.actions[lfile] = (b'r', None, b'replaced by standin')
582 actions[standin] = (b'g', sargs, b'replaces standin')
582 mresult.actions[standin] = (b'g', sargs, b'replaces standin')
583 else: # keep local normal file
583 else: # keep local normal file
584 actions[lfile] = (b'k', None, b'replaces standin')
584 mresult.actions[lfile] = (b'k', None, b'replaces standin')
585 if branchmerge:
585 if branchmerge:
586 actions[standin] = (b'k', None, b'replaced by non-standin')
586 mresult.actions[standin] = (
587 b'k',
588 None,
589 b'replaced by non-standin',
590 )
587 else:
591 else:
588 actions[standin] = (b'r', None, b'replaced by non-standin')
592 mresult.actions[standin] = (
593 b'r',
594 None,
595 b'replaced by non-standin',
596 )
589 elif lm in (b'g', b'dc') and sm != b'r':
597 elif lm in (b'g', b'dc') and sm != b'r':
590 if lm == b'dc':
598 if lm == b'dc':
591 f1, f2, fa, move, anc = largs
599 f1, f2, fa, move, anc = largs
@@ -603,24 +611,32 b' def overridecalculateupdates('
603 if repo.ui.promptchoice(usermsg, 0) == 0: # keep local largefile
611 if repo.ui.promptchoice(usermsg, 0) == 0: # keep local largefile
604 if branchmerge:
612 if branchmerge:
605 # largefile can be restored from standin safely
613 # largefile can be restored from standin safely
606 actions[lfile] = (b'k', None, b'replaced by standin')
614 mresult.actions[lfile] = (
607 actions[standin] = (b'k', None, b'replaces standin')
615 b'k',
616 None,
617 b'replaced by standin',
618 )
619 mresult.actions[standin] = (b'k', None, b'replaces standin')
608 else:
620 else:
609 # "lfile" should be marked as "removed" without
621 # "lfile" should be marked as "removed" without
610 # removal of itself
622 # removal of itself
611 actions[lfile] = (
623 mresult.actions[lfile] = (
612 b'lfmr',
624 b'lfmr',
613 None,
625 None,
614 b'forget non-standin largefile',
626 b'forget non-standin largefile',
615 )
627 )
616
628
617 # linear-merge should treat this largefile as 're-added'
629 # linear-merge should treat this largefile as 're-added'
618 actions[standin] = (b'a', None, b'keep standin')
630 mresult.actions[standin] = (b'a', None, b'keep standin')
619 else: # pick remote normal file
631 else: # pick remote normal file
620 actions[lfile] = (b'g', largs, b'replaces standin')
632 mresult.actions[lfile] = (b'g', largs, b'replaces standin')
621 actions[standin] = (b'r', None, b'replaced by non-standin')
633 mresult.actions[standin] = (
634 b'r',
635 None,
636 b'replaced by non-standin',
637 )
622
638
623 return actions, diverge, renamedelete
639 return mresult
624
640
625
641
626 @eh.wrapfunction(mergestatemod, b'recordupdates')
642 @eh.wrapfunction(mergestatemod, b'recordupdates')
@@ -540,6 +540,41 b' def _filternarrowactions(narrowmatch, br'
540 )
540 )
541
541
542
542
543 class mergeresult(object):
544 ''''An object representing result of merging manifests.
545
546 It has information about what actions need to be performed on dirstate
547 mapping of divergent renames and other such cases. '''
548
549 def __init__(self, actions, diverge, renamedelete):
550 """
551 actions: dict of filename as keys and action related info as values
552 diverge: mapping of source name -> list of dest name for
553 divergent renames
554 renamedelete: mapping of source name -> list of destinations for files
555 deleted on one side and renamed on other.
556 """
557
558 self._actions = actions
559 self._diverge = diverge
560 self._renamedelete = renamedelete
561
562 @property
563 def actions(self):
564 return self._actions
565
566 @property
567 def diverge(self):
568 return self._diverge
569
570 @property
571 def renamedelete(self):
572 return self._renamedelete
573
574 def setactions(self, actions):
575 self._actions = actions
576
577
543 def manifestmerge(
578 def manifestmerge(
544 repo,
579 repo,
545 wctx,
580 wctx,
@@ -559,12 +594,7 b' def manifestmerge('
559 matcher = matcher to filter file lists
594 matcher = matcher to filter file lists
560 acceptremote = accept the incoming changes without prompting
595 acceptremote = accept the incoming changes without prompting
561
596
562 Returns:
597 Returns an object of mergeresult class
563
564 actions: dict of filename as keys and action related info as values
565 diverge: mapping of source name -> list of dest name for divergent renames
566 renamedelete: mapping of source name -> list of destinations for files
567 deleted on one side and renamed on other.
568 """
598 """
569 if matcher is not None and matcher.always():
599 if matcher is not None and matcher.always():
570 matcher = None
600 matcher = None
@@ -845,7 +875,7 b' def manifestmerge('
845 renamedelete = branch_copies1.renamedelete
875 renamedelete = branch_copies1.renamedelete
846 renamedelete.update(branch_copies2.renamedelete)
876 renamedelete.update(branch_copies2.renamedelete)
847
877
848 return actions, diverge, renamedelete
878 return mergeresult(actions, diverge, renamedelete)
849
879
850
880
851 def _resolvetrivial(repo, wctx, mctx, ancestor, actions):
881 def _resolvetrivial(repo, wctx, mctx, ancestor, actions):
@@ -891,13 +921,13 b' def calculateupdates('
891
921
892 Also filters out actions which are unrequired if repository is sparse.
922 Also filters out actions which are unrequired if repository is sparse.
893
923
894 Returns same 3 element tuple as manifestmerge().
924 Returns mergeresult object same as manifestmerge().
895 """
925 """
896 # Avoid cycle.
926 # Avoid cycle.
897 from . import sparse
927 from . import sparse
898
928
899 if len(ancestors) == 1: # default
929 if len(ancestors) == 1: # default
900 actions, diverge, renamedelete = manifestmerge(
930 mresult = manifestmerge(
901 repo,
931 repo,
902 wctx,
932 wctx,
903 mctx,
933 mctx,
@@ -908,7 +938,7 b' def calculateupdates('
908 acceptremote,
938 acceptremote,
909 followcopies,
939 followcopies,
910 )
940 )
911 _checkunknownfiles(repo, wctx, mctx, force, actions, mergeforce)
941 _checkunknownfiles(repo, wctx, mctx, force, mresult.actions, mergeforce)
912
942
913 else: # only when merge.preferancestor=* - the default
943 else: # only when merge.preferancestor=* - the default
914 repo.ui.note(
944 repo.ui.note(
@@ -927,7 +957,7 b' def calculateupdates('
927 diverge, renamedelete = None, None
957 diverge, renamedelete = None, None
928 for ancestor in ancestors:
958 for ancestor in ancestors:
929 repo.ui.note(_(b'\ncalculating bids for ancestor %s\n') % ancestor)
959 repo.ui.note(_(b'\ncalculating bids for ancestor %s\n') % ancestor)
930 actions, diverge1, renamedelete1 = manifestmerge(
960 mresult1 = manifestmerge(
931 repo,
961 repo,
932 wctx,
962 wctx,
933 mctx,
963 mctx,
@@ -939,16 +969,20 b' def calculateupdates('
939 followcopies,
969 followcopies,
940 forcefulldiff=True,
970 forcefulldiff=True,
941 )
971 )
942 _checkunknownfiles(repo, wctx, mctx, force, actions, mergeforce)
972 _checkunknownfiles(
973 repo, wctx, mctx, force, mresult1.actions, mergeforce
974 )
943
975
944 # Track the shortest set of warning on the theory that bid
976 # Track the shortest set of warning on the theory that bid
945 # merge will correctly incorporate more information
977 # merge will correctly incorporate more information
946 if diverge is None or len(diverge1) < len(diverge):
978 if diverge is None or len(mresult1.diverge) < len(diverge):
947 diverge = diverge1
979 diverge = mresult1.diverge
948 if renamedelete is None or len(renamedelete) < len(renamedelete1):
980 if renamedelete is None or len(renamedelete) < len(
949 renamedelete = renamedelete1
981 mresult1.renamedelete
982 ):
983 renamedelete = mresult1.renamedelete
950
984
951 for f, a in sorted(pycompat.iteritems(actions)):
985 for f, a in sorted(pycompat.iteritems(mresult1.actions)):
952 m, args, msg = a
986 m, args, msg = a
953 if m == mergestatemod.ACTION_GET_OTHER_AND_STORE:
987 if m == mergestatemod.ACTION_GET_OTHER_AND_STORE:
954 m = mergestatemod.ACTION_GET
988 m = mergestatemod.ACTION_GET
@@ -1000,17 +1034,19 b' def calculateupdates('
1000 actions[f] = l[0]
1034 actions[f] = l[0]
1001 continue
1035 continue
1002 repo.ui.note(_(b'end of auction\n\n'))
1036 repo.ui.note(_(b'end of auction\n\n'))
1037 mresult = mergeresult(actions, diverge, renamedelete)
1003
1038
1004 if wctx.rev() is None:
1039 if wctx.rev() is None:
1005 fractions = _forgetremoved(wctx, mctx, branchmerge)
1040 fractions = _forgetremoved(wctx, mctx, branchmerge)
1006 actions.update(fractions)
1041 mresult.actions.update(fractions)
1007
1042
1008 prunedactions = sparse.filterupdatesactions(
1043 prunedactions = sparse.filterupdatesactions(
1009 repo, wctx, mctx, branchmerge, actions
1044 repo, wctx, mctx, branchmerge, mresult.actions
1010 )
1045 )
1011 _resolvetrivial(repo, wctx, mctx, ancestors[0], actions)
1046 _resolvetrivial(repo, wctx, mctx, ancestors[0], mresult.actions)
1012
1047
1013 return prunedactions, diverge, renamedelete
1048 mresult.setactions(prunedactions)
1049 return mresult
1014
1050
1015
1051
1016 def _getcwd():
1052 def _getcwd():
@@ -1734,7 +1770,7 b' def update('
1734 followcopies = False
1770 followcopies = False
1735
1771
1736 ### calculate phase
1772 ### calculate phase
1737 actionbyfile, diverge, renamedelete = calculateupdates(
1773 mresult = calculateupdates(
1738 repo,
1774 repo,
1739 wc,
1775 wc,
1740 p2,
1776 p2,
@@ -1747,6 +1783,8 b' def update('
1747 mergeforce=mergeforce,
1783 mergeforce=mergeforce,
1748 )
1784 )
1749
1785
1786 actionbyfile = mresult.actions
1787
1750 if updatecheck == UPDATECHECK_NO_CONFLICT:
1788 if updatecheck == UPDATECHECK_NO_CONFLICT:
1751 for f, (m, args, msg) in pycompat.iteritems(actionbyfile):
1789 for f, (m, args, msg) in pycompat.iteritems(actionbyfile):
1752 if m not in (
1790 if m not in (
@@ -1840,7 +1878,7 b' def update('
1840 _checkcollision(repo, wc.manifest(), actions)
1878 _checkcollision(repo, wc.manifest(), actions)
1841
1879
1842 # divergent renames
1880 # divergent renames
1843 for f, fl in sorted(pycompat.iteritems(diverge)):
1881 for f, fl in sorted(pycompat.iteritems(mresult.diverge)):
1844 repo.ui.warn(
1882 repo.ui.warn(
1845 _(
1883 _(
1846 b"note: possible conflict - %s was renamed "
1884 b"note: possible conflict - %s was renamed "
@@ -1852,7 +1890,7 b' def update('
1852 repo.ui.warn(b" %s\n" % nf)
1890 repo.ui.warn(b" %s\n" % nf)
1853
1891
1854 # rename and delete
1892 # rename and delete
1855 for f, fl in sorted(pycompat.iteritems(renamedelete)):
1893 for f, fl in sorted(pycompat.iteritems(mresult.renamedelete)):
1856 repo.ui.warn(
1894 repo.ui.warn(
1857 _(
1895 _(
1858 b"note: possible conflict - %s was deleted "
1896 b"note: possible conflict - %s was deleted "
General Comments 0
You need to be logged in to leave comments. Login now