summaryrefslogtreecommitdiffstats
path: root/project.py
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2012-10-26 12:18:00 -0700
committerShawn O. Pearce <sop@google.com>2012-10-26 12:24:57 -0700
commitcd81dd6403fc8dbe6ec5920c517d9083902c3c1f (patch)
tree935f3f82d2eb32c06b812f66d56d138074309ef8 /project.py
parent80d2ceb22267b7dc61b107934ff5264b6439a785 (diff)
downloadgit-repo-cd81dd6403fc8dbe6ec5920c517d9083902c3c1f.tar.gz
Revert "Represent git-submodule as nested projects"v1.11.1
This reverts commit 69998b0c6ff724bf620480140ccce648fec7d6a9. Broke Android's non-gitmodule use case. Conflicts: project.py subcmds/sync.py Change-Id: I68ceeb63d8ee3b939f85a64736bdc81dfa352aed
Diffstat (limited to 'project.py')
-rw-r--r--project.py179
1 files changed, 1 insertions, 178 deletions
diff --git a/project.py b/project.py
index c5ee50fc..2f471692 100644
--- a/project.py
+++ b/project.py
@@ -22,7 +22,6 @@ import shutil
22import stat 22import stat
23import subprocess 23import subprocess
24import sys 24import sys
25import tempfile
26import time 25import time
27 26
28from color import Coloring 27from color import Coloring
@@ -485,28 +484,7 @@ class Project(object):
485 rebase = True, 484 rebase = True,
486 groups = None, 485 groups = None,
487 sync_c = False, 486 sync_c = False,
488 upstream = None, 487 upstream = None):
489 parent = None,
490 is_derived = False):
491 """Init a Project object.
492
493 Args:
494 manifest: The XmlManifest object.
495 name: The `name` attribute of manifest.xml's project element.
496 remote: RemoteSpec object specifying its remote's properties.
497 gitdir: Absolute path of git directory.
498 worktree: Absolute path of git working tree.
499 relpath: Relative path of git working tree to repo's top directory.
500 revisionExpr: The `revision` attribute of manifest.xml's project element.
501 revisionId: git commit id for checking out.
502 rebase: The `rebase` attribute of manifest.xml's project element.
503 groups: The `groups` attribute of manifest.xml's project element.
504 sync_c: The `sync-c` attribute of manifest.xml's project element.
505 upstream: The `upstream` attribute of manifest.xml's project element.
506 parent: The parent Project object.
507 is_derived: False if the project was explicitly defined in the manifest;
508 True if the project is a discovered submodule.
509 """
510 self.manifest = manifest 488 self.manifest = manifest
511 self.name = name 489 self.name = name
512 self.remote = remote 490 self.remote = remote
@@ -529,9 +507,6 @@ class Project(object):
529 self.groups = groups 507 self.groups = groups
530 self.sync_c = sync_c 508 self.sync_c = sync_c
531 self.upstream = upstream 509 self.upstream = upstream
532 self.parent = parent
533 self.is_derived = is_derived
534 self.subprojects = []
535 510
536 self.snapshots = {} 511 self.snapshots = {}
537 self.copyfiles = [] 512 self.copyfiles = []
@@ -552,14 +527,6 @@ class Project(object):
552 self.enabled_repo_hooks = [] 527 self.enabled_repo_hooks = []
553 528
554 @property 529 @property
555 def Registered(self):
556 return self.parent and not self.is_derived
557
558 @property
559 def Derived(self):
560 return self.is_derived
561
562 @property
563 def Exists(self): 530 def Exists(self):
564 return os.path.isdir(self.gitdir) 531 return os.path.isdir(self.gitdir)
565 532
@@ -1403,150 +1370,6 @@ class Project(object):
1403 return kept 1370 return kept
1404 1371
1405 1372
1406## Submodule Management ##
1407
1408 def GetRegisteredSubprojects(self):
1409 result = []
1410 def rec(subprojects):
1411 if not subprojects:
1412 return
1413 result.extend(subprojects)
1414 for p in subprojects:
1415 rec(p.subprojects)
1416 rec(self.subprojects)
1417 return result
1418
1419 def _GetSubmodules(self):
1420 # Unfortunately we cannot call `git submodule status --recursive` here
1421 # because the working tree might not exist yet, and it cannot be used
1422 # without a working tree in its current implementation.
1423
1424 def get_submodules(gitdir, rev):
1425 # Parse .gitmodules for submodule sub_paths and sub_urls
1426 sub_paths, sub_urls = parse_gitmodules(gitdir, rev)
1427 if not sub_paths:
1428 return []
1429 # Run `git ls-tree` to read SHAs of submodule object, which happen to be
1430 # revision of submodule repository
1431 sub_revs = git_ls_tree(gitdir, rev, sub_paths)
1432 submodules = []
1433 for sub_path, sub_url in zip(sub_paths, sub_urls):
1434 try:
1435 sub_rev = sub_revs[sub_path]
1436 except KeyError:
1437 # Ignore non-exist submodules
1438 continue
1439 submodules.append((sub_rev, sub_path, sub_url))
1440 return submodules
1441
1442 re_path = re.compile(r'submodule.(\w+).path')
1443 re_url = re.compile(r'submodule.(\w+).url')
1444 def parse_gitmodules(gitdir, rev):
1445 cmd = ['cat-file', 'blob', '%s:.gitmodules' % rev]
1446 try:
1447 p = GitCommand(None, cmd, capture_stdout = True, capture_stderr = True,
1448 bare = True, gitdir = gitdir)
1449 except GitError:
1450 return [], []
1451 if p.Wait() != 0:
1452 return [], []
1453
1454 gitmodules_lines = []
1455 fd, temp_gitmodules_path = tempfile.mkstemp()
1456 try:
1457 os.write(fd, p.stdout)
1458 os.close(fd)
1459 cmd = ['config', '--file', temp_gitmodules_path, '--list']
1460 p = GitCommand(None, cmd, capture_stdout = True, capture_stderr = True,
1461 bare = True, gitdir = gitdir)
1462 if p.Wait() != 0:
1463 return [], []
1464 gitmodules_lines = p.stdout.split('\n')
1465 except GitError:
1466 return [], []
1467 finally:
1468 os.remove(temp_gitmodules_path)
1469
1470 names = set()
1471 paths = {}
1472 urls = {}
1473 for line in gitmodules_lines:
1474 if not line:
1475 continue
1476 key, value = line.split('=')
1477 m = re_path.match(key)
1478 if m:
1479 names.add(m.group(1))
1480 paths[m.group(1)] = value
1481 continue
1482 m = re_url.match(key)
1483 if m:
1484 names.add(m.group(1))
1485 urls[m.group(1)] = value
1486 continue
1487 names = sorted(names)
1488 return [paths[name] for name in names], [urls[name] for name in names]
1489
1490 def git_ls_tree(gitdir, rev, paths):
1491 cmd = ['ls-tree', rev, '--']
1492 cmd.extend(paths)
1493 try:
1494 p = GitCommand(None, cmd, capture_stdout = True, capture_stderr = True,
1495 bare = True, gitdir = gitdir)
1496 except GitError:
1497 return []
1498 if p.Wait() != 0:
1499 return []
1500 objects = {}
1501 for line in p.stdout.split('\n'):
1502 if not line.strip():
1503 continue
1504 object_rev, object_path = line.split()[2:4]
1505 objects[object_path] = object_rev
1506 return objects
1507
1508 try:
1509 rev = self.GetRevisionId()
1510 except GitError:
1511 return []
1512 return get_submodules(self.gitdir, rev)
1513
1514 def GetDerivedSubprojects(self):
1515 result = []
1516 if not self.Exists:
1517 # If git repo does not exist yet, querying its submodules will
1518 # mess up its states; so return here.
1519 return result
1520 for rev, path, url in self._GetSubmodules():
1521 name = self.manifest.GetSubprojectName(self, path)
1522 project = self.manifest.projects.get(name)
1523 if project and project.Registered:
1524 # If it has been registered, skip it because we are searching
1525 # derived subprojects, but search for its derived subprojects.
1526 result.extend(project.GetDerivedSubprojects())
1527 continue
1528 relpath, worktree, gitdir = self.manifest.GetSubprojectPaths(self, path)
1529 remote = RemoteSpec(self.remote.name,
1530 url = url,
1531 review = self.remote.review)
1532 subproject = Project(manifest = self.manifest,
1533 name = name,
1534 remote = remote,
1535 gitdir = gitdir,
1536 worktree = worktree,
1537 relpath = relpath,
1538 revisionExpr = self.revisionExpr,
1539 revisionId = rev,
1540 rebase = self.rebase,
1541 groups = self.groups,
1542 sync_c = self.sync_c,
1543 parent = self,
1544 is_derived = True)
1545 result.append(subproject)
1546 result.extend(subproject.GetDerivedSubprojects())
1547 return result
1548
1549
1550## Direct Git Commands ## 1373## Direct Git Commands ##
1551 1374
1552 def _RemoteFetch(self, name=None, 1375 def _RemoteFetch(self, name=None,