Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 2.0.5, 2.1, and 2.1.1

stable qimport: do not fail to qimport a revision when there is a patch name collision

qimport uses the default names for patches, whose format is "REVISION_NUMBER.diff".
Until this patch if you tried to qimport a revision when there was an existing
mq patch with the same target name, the qimport operation would fail, and there
was no obvious way to work around this problem.

It is easy to come into this problem. For instance, this happens if you qimport
a revision, unapply it, perform a new commit and then you try to qimport the new
commit.

This patch solves the problem by checking for name collisions before executing
the qimport command. If there are name collisions it will fall back to a slower
qimport method in which each revision that must be qimported will be imported
individually (starting from the newest), and for each of them thg will try to
find a unique patch name.

Changeset 850986489b41

Parent 898d25973c59

by Angel Ezquerra

Changes to one file · Browse files at 850986489b41 Showing diff from parent 898d25973c59 Diff from another changeset...

 
1374
1375
1376
1377
1378
1379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1380
1381
1382
 
1374
1375
1376
 
 
 
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
@@ -1374,9 +1374,46 @@
  endrev = 'qparent'   else:   endrev = '' - cmdline = ['qimport', '--rev', '%s::%s' % (self.rev, endrev), - '--repository', self.repo.root] - self.runCommand(cmdline) + + # Check whether there are existing patches in the MQ queue whose name + # collides with the revisions that are going to be imported + func = hglib.revsetmatch(self.repo.ui, '%s::%s' % (self.rev, endrev)) + revList = [c for c in func(self.repo, range(len(self.repo)))] + revNameSet = set(['%d.diff' % rev for rev in revList]) + collidingPatchSet = revNameSet.intersection(set(self.repo.mq.series)) + + if collidingPatchSet: + # We will qimport each revision one by one, starting from the newest + # To do so, we will find a valid and unique patch name for each + # revision that we must qimport + # and then we will import them one by one starting from the newest + # one, using these unique names + def getUniquePatchName(baseName): + patchName = baseName + '.diff' + if patchName in collidingPatchSet: + maxRetries = 99 + for n in range(1, maxRetries): + patchName = baseName + '_%02d.diff' % n + if not patchName in collidingPatchSet: + break + return patchName + + patchNames = {} + revList.reverse() + for rev in revList: + patchNames[rev] = getUniquePatchName(str(rev)) + + for rev in revList: + cmdline = ['qimport', '--rev', '%s' % rev, + '--repository', self.repo.root, + '--name', patchNames[rev]] + self.runCommand(cmdline) + else: + # There were no collisions with existing patch names, we can + # simply qimport the whole revision set in a single go + cmdline = ['qimport', '--rev', '%s::%s' % (self.rev, endrev), + '--repository', self.repo.root] + self.runCommand(cmdline)     def qfinishRevision(self):   """Finish applied patches up to and including selected revision"""