comparison hgext/mq.py @ 17152:f287d4a62031

mq: create patch file after commit to import diff of ".hgsubstate" at qrefresh Even though the committed revision contains diff of ".hgsubstate", the patch file created by qrefresh doesn't contain it, because: - ".hgsubstate" is not listed up as one of target files of the patch for reasons below, so diff of ".hgsubstate" is not imported into patch file - status of ".hgsubstate" in working directory is usually "clean" - ".hgsubstate" is not specified explicitly by users - the patch file is created before commit processing which updates or creates ".hgsubstate" automatically, so there is no diff for it at that time This patch resolves this problem by: - putting ".hgsubstate" into target list of the patch, if needed: this allows "patch.diff()" to import diff of ".hgsubstate" into patch file. - creating the patch file after commit processing: this updates ".hgsubstate" before "patch.diff()" invocation. For the former fixing, this patch introduces "putsubstate2changes()" to share same implementation with qnew. This is invoked only once per qnew/qrefresh at most, so there is less performance impact. This patch also omits "match" argument for "patch.diff()" invocation, because "patch.diff()" ignores "match" if "changes" is specified.
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Wed, 27 Jun 2012 22:03:27 +0900
parents 986df5249b65
children 54da604fefee
comparison
equal deleted inserted replaced
17151:986df5249b65 17152:f287d4a62031
943 raise util.Abort( 943 raise util.Abort(
944 _("uncommitted changes in subrepository %s") % s) 944 _("uncommitted changes in subrepository %s") % s)
945 elif wctx.sub(s).dirty(): 945 elif wctx.sub(s).dirty():
946 inclsubs.append(s) 946 inclsubs.append(s)
947 return inclsubs 947 return inclsubs
948
949 def putsubstate2changes(self, substatestate, changes):
950 for files in changes[:3]:
951 if '.hgsubstate' in files:
952 return # already listed up
953 # not yet listed up
954 if substatestate in 'a?':
955 changes[1].append('.hgsubstate')
956 elif substatestate in 'r':
957 changes[2].append('.hgsubstate')
958 else: # modified
959 changes[0].append('.hgsubstate')
948 960
949 def localchangesfound(self, refresh=True): 961 def localchangesfound(self, refresh=True):
950 if refresh: 962 if refresh:
951 raise util.Abort(_("local changes found, refresh first")) 963 raise util.Abort(_("local changes found, refresh first"))
952 else: 964 else:
1062 msg = msg + "\n\n" 1074 msg = msg + "\n\n"
1063 p.write(msg) 1075 p.write(msg)
1064 if commitfiles: 1076 if commitfiles:
1065 parent = self.qparents(repo, n) 1077 parent = self.qparents(repo, n)
1066 if inclsubs: 1078 if inclsubs:
1067 for files in changes[:3]: 1079 self.putsubstate2changes(substatestate, changes)
1068 if '.hgsubstate' in files:
1069 break # already listed up
1070 else:
1071 # not yet listed up
1072 if substatestate in 'a?':
1073 changes[1].append('.hgsubstate')
1074 elif substatestate in 'r':
1075 changes[2].append('.hgsubstate')
1076 else: # modified
1077 changes[0].append('.hgsubstate')
1078 chunks = patchmod.diff(repo, node1=parent, node2=n, 1080 chunks = patchmod.diff(repo, node1=parent, node2=n,
1079 changes=changes, opts=diffopts) 1081 changes=changes, opts=diffopts)
1080 for chunk in chunks: 1082 for chunk in chunks:
1081 p.write(chunk) 1083 p.write(chunk)
1082 p.close() 1084 p.close()
1485 if not repo[top].mutable(): 1487 if not repo[top].mutable():
1486 raise util.Abort(_("cannot refresh immutable revision"), 1488 raise util.Abort(_("cannot refresh immutable revision"),
1487 hint=_('see "hg help phases" for details')) 1489 hint=_('see "hg help phases" for details'))
1488 1490
1489 inclsubs = self.checksubstate(repo) 1491 inclsubs = self.checksubstate(repo)
1492 if inclsubs:
1493 inclsubs.append('.hgsubstate')
1494 substatestate = repo.dirstate['.hgsubstate']
1490 1495
1491 cparents = repo.changelog.parents(top) 1496 cparents = repo.changelog.parents(top)
1492 patchparent = self.qparents(repo, top) 1497 patchparent = self.qparents(repo, top)
1493 ph = patchheader(self.join(patchfn), self.plainmode) 1498 ph = patchheader(self.join(patchfn), self.plainmode)
1494 diffopts = self.diffopts({'git': opts.get('git')}, patchfn) 1499 diffopts = self.diffopts({'git': opts.get('git')}, patchfn)
1565 m = list(mm) 1570 m = list(mm)
1566 r = list(dd) 1571 r = list(dd)
1567 a = list(aa) 1572 a = list(aa)
1568 c = [filter(matchfn, l) for l in (m, a, r)] 1573 c = [filter(matchfn, l) for l in (m, a, r)]
1569 match = scmutil.matchfiles(repo, set(c[0] + c[1] + c[2] + inclsubs)) 1574 match = scmutil.matchfiles(repo, set(c[0] + c[1] + c[2] + inclsubs))
1570 chunks = patchmod.diff(repo, patchparent, match=match,
1571 changes=c, opts=diffopts)
1572 for chunk in chunks:
1573 patchf.write(chunk)
1574 1575
1575 try: 1576 try:
1576 if diffopts.git or diffopts.upgrade: 1577 if diffopts.git or diffopts.upgrade:
1577 copies = {} 1578 copies = {}
1578 for dst in a: 1579 for dst in a:
1647 # Ensure we create a new changeset in the same phase than 1648 # Ensure we create a new changeset in the same phase than
1648 # the old one. 1649 # the old one.
1649 n = newcommit(repo, oldphase, message, user, ph.date, 1650 n = newcommit(repo, oldphase, message, user, ph.date,
1650 match=match, force=True) 1651 match=match, force=True)
1651 # only write patch after a successful commit 1652 # only write patch after a successful commit
1653 if inclsubs:
1654 self.putsubstate2changes(substatestate, c)
1655 chunks = patchmod.diff(repo, patchparent,
1656 changes=c, opts=diffopts)
1657 for chunk in chunks:
1658 patchf.write(chunk)
1652 patchf.close() 1659 patchf.close()
1653 self.applied.append(statusentry(n, patchfn)) 1660 self.applied.append(statusentry(n, patchfn))
1654 except: # re-raises 1661 except: # re-raises
1655 ctx = repo[cparents[0]] 1662 ctx = repo[cparents[0]]
1656 repo.dirstate.rebuild(ctx.node(), ctx.manifest()) 1663 repo.dirstate.rebuild(ctx.node(), ctx.manifest())