comparison hggit/git_handler.py @ 844:da804eac2b00

git_handler.get_files_changed: detect renames when asked to do so We use Dulwich's rename detector to detect any renames over the specified similarity threshold. This isn't fully bidirectional yet -- when the commit is exported to Git the hashes will no longer be the same. That's why that isn't tested here. In upcoming patches we'll make sure it's bidirectional and will add the corresponding tests.
author Siddharth Agarwal <sid0@fb.com>
date Tue, 02 Dec 2014 15:57:21 -0800
parents edcdb7620f4d
children fffe8883960b
comparison
equal deleted inserted replaced
843:cf9dd81b61dc 844:da804eac2b00
1296 btree = None 1296 btree = None
1297 1297
1298 if commit.parents: 1298 if commit.parents:
1299 btree = self.git[commit.parents[0]].tree 1299 btree = self.git[commit.parents[0]].tree
1300 1300
1301 changes = diff_tree.tree_changes(self.git.object_store, btree, tree)
1302 files = {} 1301 files = {}
1303 gitlinks = {} 1302 gitlinks = {}
1304 renames = None 1303 renames = None
1304 rename_detector = None
1305 if detect_renames: 1305 if detect_renames:
1306 renames = {} 1306 renames = {}
1307 rename_detector = self._rename_detector
1308
1309 changes = diff_tree.tree_changes(self.git.object_store, btree, tree,
1310 rename_detector=rename_detector)
1307 1311
1308 for change in changes: 1312 for change in changes:
1309 oldfile, oldmode, oldsha = change.old 1313 oldfile, oldmode, oldsha = change.old
1310 newfile, newmode, newsha = change.new 1314 newfile, newmode, newsha = change.new
1311 # actions are described by the following table ('no' means 'does not 1315 # actions are described by the following table ('no' means 'does not
1320 # gitlink file | delete gitlink and record file 1324 # gitlink file | delete gitlink and record file
1321 # gitlink gitlink | record gitlink 1325 # gitlink gitlink | record gitlink
1322 if newmode == 0160000: 1326 if newmode == 0160000:
1323 # new = gitlink 1327 # new = gitlink
1324 gitlinks[newfile] = newsha 1328 gitlinks[newfile] = newsha
1329 if change.type == diff_tree.CHANGE_RENAME:
1330 # don't record the rename because only file -> file renames
1331 # make sense in Mercurial
1332 gitlinks[oldfile] = None
1325 if oldmode is not None and oldmode != 0160000: 1333 if oldmode is not None and oldmode != 0160000:
1326 # file -> gitlink 1334 # file -> gitlink
1327 files[oldfile] = True, None, None 1335 files[oldfile] = True, None, None
1328 continue 1336 continue
1329 if oldmode == 0160000 and newmode != 0160000: 1337 if oldmode == 0160000 and newmode != 0160000:
1331 gitlinks[oldfile] = None 1339 gitlinks[oldfile] = None
1332 continue 1340 continue
1333 if newfile is not None: 1341 if newfile is not None:
1334 # new = file 1342 # new = file
1335 files[newfile] = False, newmode, newsha 1343 files[newfile] = False, newmode, newsha
1344 if renames is not None and newfile != oldfile:
1345 renames[newfile] = oldfile
1346 if change.type == diff_tree.CHANGE_RENAME:
1347 files[oldfile] = True, None, None
1336 else: 1348 else:
1337 # old = file 1349 # old = file
1338 files[oldfile] = True, None, None 1350 files[oldfile] = True, None, None
1339 1351
1340 return files, gitlinks, renames 1352 return files, gitlinks, renames
1355 if max_files == 0: 1367 if max_files == 0:
1356 max_files = None 1368 max_files = None
1357 1369
1358 find_copies_harder = self.ui.configbool('git', 'findcopiesharder', 1370 find_copies_harder = self.ui.configbool('git', 'findcopiesharder',
1359 default=False) 1371 default=False)
1360 return diff_tree.RenameDetector( 1372 return diff_tree.RenameDetector(self.git.object_store,
1361 rename_threshold=similarity, max_files=max_files, 1373 rename_threshold=similarity, max_files=max_files,
1362 find_copies_harder=find_copies_harder) 1374 find_copies_harder=find_copies_harder)
1363 1375
1364 def parse_gitmodules(self, tree_obj): 1376 def parse_gitmodules(self, tree_obj):
1365 """Parse .gitmodules from a git tree specified by tree_obj 1377 """Parse .gitmodules from a git tree specified by tree_obj