/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/plugins/git/workingtree.py

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2018-05-21 21:16:48 UTC
  • mfrom: (6973.1.1 git-cleanup)
  • Revision ID: breezy.the.bot@gmail.com-20180521211648-d3emlyz0qi3gwxh5
Make InterIndexGitTree suitable for use with MemoryGitTree.

Merged from https://code.launchpad.net/~jelmer/brz/inter-memorygittree/+merge/346426

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
    SHA1Writer,
32
32
    build_index_from_tree,
33
33
    changes_from_tree,
34
 
    cleanup_mode,
35
 
    commit_tree,
36
34
    index_entry_from_path,
37
35
    index_entry_from_stat,
38
36
    iter_fresh_entries,
39
 
    blob_from_path_and_stat,
40
37
    FLAG_STAGEMASK,
41
38
    read_submodule_head,
42
39
    validate_path,
734
731
    def _lstat(self, path):
735
732
        return os.lstat(self.abspath(path))
736
733
 
 
734
    def _live_entry(self, path):
 
735
        return index_entry_from_path(self.abspath(path.decode('utf-8')).encode(osutils._fs_enc))
 
736
 
737
737
    def is_executable(self, path, file_id=None):
738
738
        with self.lock_read():
739
739
            if getattr(self, "_supports_executable", osutils.supports_executable)():
1339
1339
        for hook in MutableTree.hooks['post_build_tree']:
1340
1340
            hook(wt)
1341
1341
        return wt
1342
 
 
1343
 
 
1344
 
class InterIndexGitTree(InterGitTrees):
1345
 
    """InterTree that works between a Git revision tree and an index."""
1346
 
 
1347
 
    def __init__(self, source, target):
1348
 
        super(InterIndexGitTree, self).__init__(source, target)
1349
 
        self._index = target.index
1350
 
 
1351
 
    @classmethod
1352
 
    def is_compatible(cls, source, target):
1353
 
        from .repository import GitRevisionTree
1354
 
        return (isinstance(source, GitRevisionTree) and
1355
 
                isinstance(target, GitWorkingTree))
1356
 
 
1357
 
    def _iter_git_changes(self, want_unchanged=False, specific_files=None,
1358
 
            require_versioned=False, extra_trees=None,
1359
 
            want_unversioned=False):
1360
 
        trees = [self.source]
1361
 
        if extra_trees is not None:
1362
 
            trees.extend(extra_trees)
1363
 
        if specific_files is not None:
1364
 
            specific_files = self.target.find_related_paths_across_trees(
1365
 
                    specific_files, trees,
1366
 
                    require_versioned=require_versioned)
1367
 
        # TODO(jelmer): Restrict to specific_files, for performance reasons.
1368
 
        with self.lock_read():
1369
 
            return changes_between_git_tree_and_working_copy(
1370
 
                self.source.store, self.source.tree,
1371
 
                self.target, want_unchanged=want_unchanged,
1372
 
                want_unversioned=want_unversioned)
1373
 
 
1374
 
 
1375
 
tree.InterTree.register_optimiser(InterIndexGitTree)
1376
 
 
1377
 
 
1378
 
def changes_between_git_tree_and_working_copy(store, from_tree_sha, target,
1379
 
        want_unchanged=False, want_unversioned=False):
1380
 
    """Determine the changes between a git tree and a working tree with index.
1381
 
 
1382
 
    """
1383
 
    extras = set()
1384
 
    blobs = {}
1385
 
    # Report dirified directories to commit_tree first, so that they can be
1386
 
    # replaced with non-empty directories if they have contents.
1387
 
    dirified = []
1388
 
    target_root_path = target.abspath('.').encode(sys.getfilesystemencoding())
1389
 
    for path, index_entry in target._recurse_index_entries():
1390
 
        try:
1391
 
            live_entry = index_entry_from_path(
1392
 
                    target.abspath(path.decode('utf-8')).encode(osutils._fs_enc))
1393
 
        except EnvironmentError as e:
1394
 
            if e.errno == errno.ENOENT:
1395
 
                # Entry was removed; keep it listed, but mark it as gone.
1396
 
                blobs[path] = (ZERO_SHA, 0)
1397
 
            elif e.errno == errno.EISDIR:
1398
 
                # Entry was turned into a directory
1399
 
                dirified.append((path, Tree().id, stat.S_IFDIR))
1400
 
                store.add_object(Tree())
1401
 
            else:
1402
 
                raise
1403
 
        else:
1404
 
            blobs[path] = (live_entry.sha, cleanup_mode(live_entry.mode))
1405
 
    if want_unversioned:
1406
 
        for e in target.extras():
1407
 
            ap = target.abspath(e)
1408
 
            st = os.lstat(ap)
1409
 
            try:
1410
 
                np, accessible = osutils.normalized_filename(e)
1411
 
            except UnicodeDecodeError:
1412
 
                raise errors.BadFilenameEncoding(
1413
 
                    e, osutils._fs_enc)
1414
 
            if stat.S_ISDIR(st.st_mode):
1415
 
                blob = Tree()
1416
 
            else:
1417
 
                blob = blob_from_path_and_stat(ap.encode('utf-8'), st)
1418
 
            store.add_object(blob)
1419
 
            np = np.encode('utf-8')
1420
 
            blobs[np] = (blob.id, cleanup_mode(st.st_mode))
1421
 
            extras.add(np)
1422
 
    to_tree_sha = commit_tree(store, dirified + [(p, s, m) for (p, (s, m)) in blobs.items()])
1423
 
    return store.tree_changes(
1424
 
        from_tree_sha, to_tree_sha, include_trees=True,
1425
 
        want_unchanged=want_unchanged, change_type_same=True), extras