summaryrefslogtreecommitdiffstats
path: root/project.py
diff options
context:
space:
mode:
authorPeter Kjellerstedt <pkj@axis.com>2025-11-08 00:06:16 +0100
committerLUCI <gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com>2025-11-26 02:07:35 -0800
commit412367bfafd9de014cfeb37475e0f97b1f6a2509 (patch)
tree100e674dea649546145dbb81532a8f432cc09f52 /project.py
parent47c24b5c4092ce397c94c05d8686c8bcac64fbb2 (diff)
downloadgit-repo-412367bfafd9de014cfeb37475e0f97b1f6a2509.tar.gz
project: Use dicts to keep track of copyfiles and linkfiles
This avoids copying/linking the same file/link multiple times if a copyfile/linkfile element with the same values has been specifed multiple times. This can happen when including a common manifest that uses an extend-project element that has a copyfile/linkfile element. This uses dicts rather than sets to store the copyfiles and linkfiles to make sure the order they are specified in the manifest is maintained. For Python 3.7+, maintaining the order that keys are added to dicts is guaranteed, and for Python 3.6 it happened to be true. The _CopyFile class and the _LinkFile class are changed to inherit from NamedTuple to be able to store them in dicts. Change-Id: I9f5a80298b875251a81c5fe7d353e262d104fae4 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/525322 Reviewed-by: Mike Frysinger <vapier@google.com> Reviewed-by: Gavin Mak <gavinmak@google.com> Tested-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com> Commit-Queue: Peter Kjellerstedt <peter.kjellerstedt@axis.com>
Diffstat (limited to 'project.py')
-rw-r--r--project.py55
1 files changed, 23 insertions, 32 deletions
diff --git a/project.py b/project.py
index 8e430175..41606442 100644
--- a/project.py
+++ b/project.py
@@ -390,22 +390,17 @@ def _SafeExpandPath(base, subpath, skipfinal=False):
390 return path 390 return path
391 391
392 392
393class _CopyFile: 393class _CopyFile(NamedTuple):
394 """Container for <copyfile> manifest element.""" 394 """Container for <copyfile> manifest element."""
395 395
396 def __init__(self, git_worktree, src, topdir, dest): 396 # Absolute path to the git project checkout.
397 """Register a <copyfile> request. 397 git_worktree: str
398 398 # Relative path under |git_worktree| of file to read.
399 Args: 399 src: str
400 git_worktree: Absolute path to the git project checkout. 400 # Absolute path to the top of the repo client checkout.
401 src: Relative path under |git_worktree| of file to read. 401 topdir: str
402 topdir: Absolute path to the top of the repo client checkout. 402 # Relative path under |topdir| of file to write.
403 dest: Relative path under |topdir| of file to write. 403 dest: str
404 """
405 self.git_worktree = git_worktree
406 self.topdir = topdir
407 self.src = src
408 self.dest = dest
409 404
410 def _Copy(self): 405 def _Copy(self):
411 src = _SafeExpandPath(self.git_worktree, self.src) 406 src = _SafeExpandPath(self.git_worktree, self.src)
@@ -439,22 +434,17 @@ class _CopyFile:
439 logger.error("error: Cannot copy file %s to %s", src, dest) 434 logger.error("error: Cannot copy file %s to %s", src, dest)
440 435
441 436
442class _LinkFile: 437class _LinkFile(NamedTuple):
443 """Container for <linkfile> manifest element.""" 438 """Container for <linkfile> manifest element."""
444 439
445 def __init__(self, git_worktree, src, topdir, dest): 440 # Absolute path to the git project checkout.
446 """Register a <linkfile> request. 441 git_worktree: str
447 442 # Target of symlink relative to path under |git_worktree|.
448 Args: 443 src: str
449 git_worktree: Absolute path to the git project checkout. 444 # Absolute path to the top of the repo client checkout.
450 src: Target of symlink relative to path under |git_worktree|. 445 topdir: str
451 topdir: Absolute path to the top of the repo client checkout. 446 # Relative path under |topdir| of symlink to create.
452 dest: Relative path under |topdir| of symlink to create. 447 dest: str
453 """
454 self.git_worktree = git_worktree
455 self.topdir = topdir
456 self.src = src
457 self.dest = dest
458 448
459 def __linkIt(self, relSrc, absDest): 449 def __linkIt(self, relSrc, absDest):
460 # Link file if it does not exist or is out of date. 450 # Link file if it does not exist or is out of date.
@@ -633,8 +623,9 @@ class Project:
633 self.subprojects = [] 623 self.subprojects = []
634 624
635 self.snapshots = {} 625 self.snapshots = {}
636 self.copyfiles = [] 626 # Use dicts to dedupe while maintaining declared order.
637 self.linkfiles = [] 627 self.copyfiles = {}
628 self.linkfiles = {}
638 self.annotations = [] 629 self.annotations = []
639 self.dest_branch = dest_branch 630 self.dest_branch = dest_branch
640 631
@@ -1794,7 +1785,7 @@ class Project:
1794 Paths should have basic validation run on them before being queued. 1785 Paths should have basic validation run on them before being queued.
1795 Further checking will be handled when the actual copy happens. 1786 Further checking will be handled when the actual copy happens.
1796 """ 1787 """
1797 self.copyfiles.append(_CopyFile(self.worktree, src, topdir, dest)) 1788 self.copyfiles[_CopyFile(self.worktree, src, topdir, dest)] = True
1798 1789
1799 def AddLinkFile(self, src, dest, topdir): 1790 def AddLinkFile(self, src, dest, topdir):
1800 """Mark |dest| to create a symlink (relative to |topdir|) pointing to 1791 """Mark |dest| to create a symlink (relative to |topdir|) pointing to
@@ -1805,7 +1796,7 @@ class Project:
1805 Paths should have basic validation run on them before being queued. 1796 Paths should have basic validation run on them before being queued.
1806 Further checking will be handled when the actual link happens. 1797 Further checking will be handled when the actual link happens.
1807 """ 1798 """
1808 self.linkfiles.append(_LinkFile(self.worktree, src, topdir, dest)) 1799 self.linkfiles[_LinkFile(self.worktree, src, topdir, dest)] = True
1809 1800
1810 def AddAnnotation(self, name, value, keep): 1801 def AddAnnotation(self, name, value, keep):
1811 self.annotations.append(Annotation(name, value, keep)) 1802 self.annotations.append(Annotation(name, value, keep))