From f97653aa06cf84bcf160be3786b6fce49ef52961 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 15 Nov 2010 18:42:44 +0100 Subject: Repo: added submodule query and iteration methods similar to the ones provided for Remotes, including test --- lib/git/repo/base.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'lib/git/repo/base.py') diff --git a/lib/git/repo/base.py b/lib/git/repo/base.py index 790b1283..3a395af0 100644 --- a/lib/git/repo/base.py +++ b/lib/git/repo/base.py @@ -6,7 +6,6 @@ from git.exc import InvalidGitRepositoryError, NoSuchPathError from git.cmd import Git -from git.objects import Actor from git.refs import * from git.index import IndexFile from git.objects import * @@ -222,6 +221,27 @@ class Repo(object): """:return: Remote with the specified name :raise ValueError: if no remote with such a name exists""" return Remote(self, name) + + @property + def submodules(self): + """:return: git.IterableList(Submodule, ...) of direct submodules""" + return self.list_submodules(recursive=False) + + def submodule(self, name): + """:return: Submodule with the given name + :raise ValueError: If no such submodule exists""" + try: + return self.submodules[name] + except IndexError: + raise ValueError("Didn't find submodule named %r" % name) + # END exception handling + + def list_submodules(self, recursive=False): + """A list if Submodule objects available in this repository + :param recursive: If True, submodules of submodules (and so forth) will be + returned as well as part of a depth-first traversal + :return: ``git.IterableList(Submodule, ...)""" + return RootModule(self).list_traverse(ignore_self=1, depth = recursive and -1 or 1) @property def tags(self): -- cgit v1.2.1 From 624556eae1c292a1dc283d9dca1557e28abe8ee3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 15 Nov 2010 19:03:53 +0100 Subject: Optimized test-decorators, by completely removing with_bare_rw_repo, which was mainly copy-paste from with_rw_repo, what a shame --- lib/git/repo/base.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'lib/git/repo/base.py') diff --git a/lib/git/repo/base.py b/lib/git/repo/base.py index 3a395af0..0355b062 100644 --- a/lib/git/repo/base.py +++ b/lib/git/repo/base.py @@ -225,7 +225,7 @@ class Repo(object): @property def submodules(self): """:return: git.IterableList(Submodule, ...) of direct submodules""" - return self.list_submodules(recursive=False) + return Submodule.list_items(self) def submodule(self, name): """:return: Submodule with the given name @@ -236,12 +236,11 @@ class Repo(object): raise ValueError("Didn't find submodule named %r" % name) # END exception handling - def list_submodules(self, recursive=False): - """A list if Submodule objects available in this repository - :param recursive: If True, submodules of submodules (and so forth) will be - returned as well as part of a depth-first traversal - :return: ``git.IterableList(Submodule, ...)""" - return RootModule(self).list_traverse(ignore_self=1, depth = recursive and -1 or 1) + def iter_submodules(self, *args, **kwargs): + """An iterator yielding Submodule instances, see Traversable interface + for a description of args and kwargs + :return: Iterator""" + return RootModule(self).traverse(*args, **kwargs) @property def tags(self): -- cgit v1.2.1 From e84d05f4bbf7090a9802e9cd198d1c383974cb12 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 17 Nov 2010 11:17:05 +0100 Subject: Repo: scetched out submodule_update --- lib/git/repo/base.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) (limited to 'lib/git/repo/base.py') diff --git a/lib/git/repo/base.py b/lib/git/repo/base.py index 0355b062..d1a41f3a 100644 --- a/lib/git/repo/base.py +++ b/lib/git/repo/base.py @@ -222,6 +222,8 @@ class Repo(object): :raise ValueError: if no remote with such a name exists""" return Remote(self, name) + #{ Submodules + @property def submodules(self): """:return: git.IterableList(Submodule, ...) of direct submodules""" @@ -240,7 +242,66 @@ class Repo(object): """An iterator yielding Submodule instances, see Traversable interface for a description of args and kwargs :return: Iterator""" - return RootModule(self).traverse(*args, **kwargs) + return RootModule(self).traverse(*args, **kwargs) + + def submodule_update(self, previous_commit=None, force_remove=False, to_latest_revision=False): + """Update the submodules of this repository to the current HEAD commit. + This method behaves smartly by determining changes of the path of a submodules + repository, next to changes to the to-be-checked-out commit or the branch to be + checked out. This works if the submodules ID does not change. + Additionally it will detect addition and removal of submodules, which will be handled + gracefully. + + :param previous_commit: If set to a commit'ish, the commit we should use + as the previous commit the HEAD pointed to before it was set to the commit it points to now. + If None, it defaults to ORIG_HEAD otherwise, or the parent of the current + commit if it is not given + :param force_remove: If submodules have been deleted, they will be forcibly removed. + Otherwise the update may fail if a submodule's repository cannot be deleted as + changes have been made to it (see Submodule.update() for more information) + :param to_latest_revision: If True, instead of checking out the revision pointed to + by this submodule's sha, the checked out tracking branch will be merged with the + newest remote branch fetched from the repository's origin""" + if self.bare: + raise InvalidGitRepositoryError("Cannot update submodules in bare repositories") + # END handle bare + + # HANDLE COMMITS + ################## + cur_commit = self.head.commit + if previous_commit is None: + symref = SymbolicReference(self, SymbolicReference.to_full_path('ORIG_HEAD')) + try: + previous_commit = symref.commit + except Exception: + pcommits = cur_commit.parents + if pcommits: + previous_commit = pcommits[0] + else: + # in this special case, we just diff against ourselve, which + # means exactly no change + previous_commit = cur_commit + # END handle initial commit + # END no ORIG_HEAD + else: + previous_commit = self.commit(previous_commit) # obtain commit object + # END handle previous commit + + sms = self.submodules() + + # HANDLE REMOVALS + + # HANDLE PATH RENAMES + + # FINALLY UPDATE ALL ACTUAL SUBMODULES + ########################################## + if previous_commit == cur_commit: + for sm in sms: + sm.update(recursive=True, init=True, to_latest_revision=to_latest_revision) + # END for each submodule to update + # END handle commits are equal + + #}END submodules @property def tags(self): -- cgit v1.2.1 From 7cc4d748a132377ffe63534e9777d7541a3253c5 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 17 Nov 2010 21:33:33 +0100 Subject: repo: Added create_submodule method which fits into the tradition of offering a create_* method for most important entities. Moved implementation of smart update method to the RootModule implementation, where it may do special things without requiring an interface for everything --- lib/git/repo/base.py | 71 +++++++++++----------------------------------------- 1 file changed, 14 insertions(+), 57 deletions(-) (limited to 'lib/git/repo/base.py') diff --git a/lib/git/repo/base.py b/lib/git/repo/base.py index d1a41f3a..aa00d028 100644 --- a/lib/git/repo/base.py +++ b/lib/git/repo/base.py @@ -226,7 +226,8 @@ class Repo(object): @property def submodules(self): - """:return: git.IterableList(Submodule, ...) of direct submodules""" + """:return: git.IterableList(Submodule, ...) of direct submodules + available from the current head""" return Submodule.list_items(self) def submodule(self, name): @@ -238,68 +239,24 @@ class Repo(object): raise ValueError("Didn't find submodule named %r" % name) # END exception handling + def create_submodule(self, *args, **kwargs): + """Create a new submodule + :note: See the documentation of Submodule.add for a description of the + applicable parameters + :return: created submodules""" + return Submodule.add(self, *args, **kwargs) + def iter_submodules(self, *args, **kwargs): """An iterator yielding Submodule instances, see Traversable interface for a description of args and kwargs :return: Iterator""" return RootModule(self).traverse(*args, **kwargs) - def submodule_update(self, previous_commit=None, force_remove=False, to_latest_revision=False): - """Update the submodules of this repository to the current HEAD commit. - This method behaves smartly by determining changes of the path of a submodules - repository, next to changes to the to-be-checked-out commit or the branch to be - checked out. This works if the submodules ID does not change. - Additionally it will detect addition and removal of submodules, which will be handled - gracefully. - - :param previous_commit: If set to a commit'ish, the commit we should use - as the previous commit the HEAD pointed to before it was set to the commit it points to now. - If None, it defaults to ORIG_HEAD otherwise, or the parent of the current - commit if it is not given - :param force_remove: If submodules have been deleted, they will be forcibly removed. - Otherwise the update may fail if a submodule's repository cannot be deleted as - changes have been made to it (see Submodule.update() for more information) - :param to_latest_revision: If True, instead of checking out the revision pointed to - by this submodule's sha, the checked out tracking branch will be merged with the - newest remote branch fetched from the repository's origin""" - if self.bare: - raise InvalidGitRepositoryError("Cannot update submodules in bare repositories") - # END handle bare - - # HANDLE COMMITS - ################## - cur_commit = self.head.commit - if previous_commit is None: - symref = SymbolicReference(self, SymbolicReference.to_full_path('ORIG_HEAD')) - try: - previous_commit = symref.commit - except Exception: - pcommits = cur_commit.parents - if pcommits: - previous_commit = pcommits[0] - else: - # in this special case, we just diff against ourselve, which - # means exactly no change - previous_commit = cur_commit - # END handle initial commit - # END no ORIG_HEAD - else: - previous_commit = self.commit(previous_commit) # obtain commit object - # END handle previous commit - - sms = self.submodules() - - # HANDLE REMOVALS - - # HANDLE PATH RENAMES - - # FINALLY UPDATE ALL ACTUAL SUBMODULES - ########################################## - if previous_commit == cur_commit: - for sm in sms: - sm.update(recursive=True, init=True, to_latest_revision=to_latest_revision) - # END for each submodule to update - # END handle commits are equal + def submodule_update(self, *args, **kwargs): + """Update the submodules, keeping the repository consistent as it will + take the previous state into consideration. For more information, please + see the documentation of RootModule.update""" + return RootModule(self).update(*args, **kwargs) #}END submodules -- cgit v1.2.1