comparison mercurial/cmdutil.py @ 24837:edf907bd8144 stable

record: fix record with change on moved file crashes (issue4619) reverting 79fceed67676, add a test to prevent the issue from coming back.
author Laurent Charignon <lcharignon@fb.com>
date Wed, 22 Apr 2015 13:56:30 -0700
parents c560d8c68791
children 21b33f0460e0
comparison
equal deleted inserted replaced
24836:1f9127c9239b 24837:edf907bd8144
57 return newchunks 57 return newchunks
58 58
59 def dorecord(ui, repo, commitfunc, cmdsuggest, backupall, 59 def dorecord(ui, repo, commitfunc, cmdsuggest, backupall,
60 filterfn, *pats, **opts): 60 filterfn, *pats, **opts):
61 import merge as mergemod 61 import merge as mergemod
62 hunkclasses = (crecordmod.uihunk, patch.recordhunk)
63 ishunk = lambda x: isinstance(x, hunkclasses)
64 62
65 if not ui.interactive(): 63 if not ui.interactive():
66 raise util.Abort(_('running non-interactively, use %s instead') % 64 raise util.Abort(_('running non-interactively, use %s instead') %
67 cmdsuggest) 65 cmdsuggest)
68 66
115 newfiles = [f for f in changed if f in contenders] 113 newfiles = [f for f in changed if f in contenders]
116 if not newfiles: 114 if not newfiles:
117 ui.status(_('no changes to record\n')) 115 ui.status(_('no changes to record\n'))
118 return 0 116 return 0
119 117
120 newandmodifiedfiles = set()
121 for h in chunks:
122 isnew = h.filename() in status.added
123 if ishunk(h) and isnew and not h in originalchunks:
124 newandmodifiedfiles.add(h.filename())
125
126 modified = set(status.modified) 118 modified = set(status.modified)
127 119
128 # 2. backup changed files, so we can restore them in the end 120 # 2. backup changed files, so we can restore them in the end
129 121
130 if backupall: 122 if backupall:
131 tobackup = changed 123 tobackup = changed
132 else: 124 else:
133 tobackup = [f for f in newfiles 125 tobackup = [f for f in newfiles if f in modified]
134 if f in modified or f in newandmodifiedfiles]
135 126
136 backups = {} 127 backups = {}
137 if tobackup: 128 if tobackup:
138 backupdir = repo.join('record-backups') 129 backupdir = repo.join('record-backups')
139 try: 130 try:
153 backups[f] = tmpname 144 backups[f] = tmpname
154 145
155 fp = cStringIO.StringIO() 146 fp = cStringIO.StringIO()
156 for c in chunks: 147 for c in chunks:
157 fname = c.filename() 148 fname = c.filename()
158 if fname in backups or fname in newandmodifiedfiles: 149 if fname in backups:
159 c.write(fp) 150 c.write(fp)
160 dopatch = fp.tell() 151 dopatch = fp.tell()
161 fp.seek(0) 152 fp.seek(0)
162
163 [os.unlink(c) for c in newandmodifiedfiles]
164 153
165 # 3a. apply filtered patch to clean repo (clean) 154 # 3a. apply filtered patch to clean repo (clean)
166 if backups: 155 if backups:
167 # Equivalent to hg.revert 156 # Equivalent to hg.revert
168 choices = lambda key: key in backups 157 choices = lambda key: key in backups