def_InitGitDir(self, mirror_git=None, force_sync=False, quiet=False): init_git_dir = not os.path.exists(self.gitdir) init_obj_dir = not os.path.exists(self.objdir) try: # Initialize the bare repository, which contains all of the objects. if init_obj_dir: os.makedirs(self.objdir) self.bare_objdir.init() ......
def__getattr__(self, name): """Allow arbitrary git commands using pythonic syntax. This allows you to do things like: git_obj.rev_parse('HEAD') Since we don't have a 'rev_parse' method defined, the __getattr__ will run. We'll replace the '_' with a '-' and try to run a git command. Any other positional arguments will be passed to the git command, and the following keyword arguments are supported: config: An optional dict of git config options to be passed with '-c'. Args: name: The name of the git command to call. Any '_' characters will be replaced with '-'. Returns: A callable object that will try to call git with the named command. """ ...... return runner
defSync_LocalHalf(self, syncbuf, force_sync=False, submodules=False): """Perform only the local IO portion of the sync process. Network access is not required. """ ...... self._InitWorkTree(force_sync=force_sync, submodules=submodules) all_refs = self.bare_ref.all self.CleanPublishedCache(all_refs) revid = self.GetRevisionId(all_refs) ...... head = self.work_git.GetHead() if head.startswith(R_HEADS): branch = head[len(R_HEADS):] try: head = all_refs[head] except KeyError: head = None else: branch = None
if branch isNoneor syncbuf.detach_head: # Currently on a detached HEAD. The user is assumed to # not have any local modifications worth worrying about. # ...... if head == revid: # No changes; don't do anything further. # Except if the head needs to be detached # ifnot syncbuf.detach_head: # The copy/linkfile config may have changed. self._CopyAndLinkFiles() return else: lost = self._revlist(not_rev(revid), HEAD) if lost: syncbuf.info(self, "discarding %d commits", len(lost)) try: self._Checkout(revid, quiet=True) ...... self._CopyAndLinkFiles() return ......
defLink(self, name): """Update the repo metadata to use a different manifest. """ self.Override(name)
# Old versions of repo would generate symlinks we need to clean up. if os.path.lexists(self.manifestFile): platform_utils.remove(self.manifestFile) # This file is interpreted as if it existed inside the manifest repo. # That allows us to use <include> with the relative file name. with open(self.manifestFile, 'w') as fp: fp.write("""<?xml version="1.0" encoding="UTF-8"?> <!-- DO NOT EDIT THIS FILE! It is generated by repo and changes will be discarded. If you want to use a different manifest, use `repo init -m <file>` instead. If you want to customize your checkout by overriding manifest settings, use the local_manifests/ directory instead. For more information on repo manifests, check out: https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md --> <manifest> <include name="%s" /> </manifest> """ % (name,))
早期的 Repo 版本中,Link 方法实现为创建一个指向 Manifest 仓库中的符号链接。在 2020-02-21 之后,其实现修改为创建填充内容文件的方式,将实际的 Manifest 文件 include 到文件中。一方面是可以在其中添加更友好的提示信息,来引导用户查看相关内容;另一方面,也是优化在 Windows 上使用 repo 工具的体验,因为在 Windows 下创建符号链接需要管理员权限。
classProject(object): ...... def__init__(self, manifest, name, remote, gitdir, objdir, worktree, relpath, revisionExpr, revisionId, rebase=True, groups=None, sync_c=False, sync_s=False, sync_tags=True, clone_depth=None, upstream=None, parent=None, use_git_worktrees=False, is_derived=False, dest_branch=None, optimized_fetch=False, retry_fetches=0, old_revision=None): """Init a Project object. Args: manifest: The XmlManifest object. name: The `name` attribute of manifest.xml's project element. remote: RemoteSpec object specifying its remote's properties. gitdir: Absolute path of git directory. objdir: Absolute path of directory to store git objects. worktree: Absolute path of git working tree. relpath: Relative path of git working tree to repo's top directory. revisionExpr: The `revision` attribute of manifest.xml's project element. revisionId: git commit id for checking out. rebase: The `rebase` attribute of manifest.xml's project element. groups: The `groups` attribute of manifest.xml's project element. sync_c: The `sync-c` attribute of manifest.xml's project element. sync_s: The `sync-s` attribute of manifest.xml's project element. sync_tags: The `sync-tags` attribute of manifest.xml's project element. upstream: The `upstream` attribute of manifest.xml's project element. parent: The parent Project object. use_git_worktrees: Whether to use `git worktree` for this project. is_derived: False if the project was explicitly defined in the manifest; True if the project is a discovered submodule. dest_branch: The branch to which to push changes for review by default. optimized_fetch: If True, when a project is set to a sha1 revision, only fetch from the remote if the sha1 is not present locally. retry_fetches: Retry remote fetches n times upon receiving transient error with exponential backoff and jitter. old_revision: saved git commit id for open GITC projects. """ ......