diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2010-11-25 09:56:36 +0100 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2010-11-25 09:56:36 +0100 |
commit | d810f2700f54146063ca2cb6bb1cf03c36744a2c (patch) | |
tree | c0a5e9f1ab1057e6318dcf6ee3af25cdb344de23 | |
parent | 2c12fef1b1971ba7a50e7e5c497caf51e0f68479 (diff) | |
download | gitpython-d810f2700f54146063ca2cb6bb1cf03c36744a2c.tar.gz |
Integrated progress updates into all submodule.update methods.
Submodule.update now supports dry_run as well, which is still to be implemented in all cases
-rw-r--r-- | objects/submodule/base.py | 38 | ||||
-rw-r--r-- | objects/submodule/root.py | 65 |
2 files changed, 86 insertions, 17 deletions
diff --git a/objects/submodule/base.py b/objects/submodule/base.py index 85350e66..c47e2bfc 100644 --- a/objects/submodule/base.py +++ b/objects/submodule/base.py @@ -37,10 +37,17 @@ __all__ = ["Submodule", "UpdateProgress"] class UpdateProgress(RemoteProgress): """Class providing detailed progress information to the caller who should derive from it and implement the ``update(...)`` message""" - ADD, REMOVE, UPDATE = [1 << x for x in range(RemoteProgress._num_op_codes, RemoteProgress._num_op_codes+3)] + CLONE, FETCH, UPDWKTREE = [1 << x for x in range(RemoteProgress._num_op_codes, RemoteProgress._num_op_codes+3)] + _num_op_codes = RemoteProgress._num_op_codes + 3 __slots__ = tuple() + +BEGIN = UpdateProgress.BEGIN +END = UpdateProgress.END +CLONE = UpdateProgress.CLONE +FETCH = UpdateProgress.FETCH +UPDWKTREE = UpdateProgress.UPDWKTREE # IndexObject comes via util module, its a 'hacky' fix thanks to pythons import @@ -296,7 +303,8 @@ class Submodule(util.IndexObject, Iterable, Traversable): return sm - def update(self, recursive=False, init=True, to_latest_revision=False, progress=None): + def update(self, recursive=False, init=True, to_latest_revision=False, progress=None, + dry_run=False): """Update the repository of this submodule to point to the checkout we point at with the binsha of this instance. @@ -309,6 +317,8 @@ class Submodule(util.IndexObject, Iterable, Traversable): if the remote repository had a master branch, or of the 'branch' option was specified for this submodule and the branch existed remotely :param progress: UpdateProgress instance or None of no progress should be shown + :param dry_run: if True, the operation will only be simulated, but not performed. + All performed operations are read-only :note: does nothing in bare repositories :note: method is definitely not atomic if recurisve is True :return: self""" @@ -324,8 +334,22 @@ class Submodule(util.IndexObject, Iterable, Traversable): ##################################### try: mrepo = self.module() - for remote in mrepo.remotes: - remote.fetch() + rmts = mrepo.remotes + len_rmts = len(rmts) + for i, remote in enumerate(rmts): + op = FETCH + if i == 0: + op |= BEGIN + #END handle start + + progress.update(op, i, len_rmts, "Fetching remote %s" % remote) + #=============================== + remote.fetch(progress=progress) + #=============================== + if i == len_rmts-1: + op |= END + #END handle end + progress.update(op, i, len_rmts, "Done fetching remote %s" % remote) #END fetch new data except InvalidGitRepositoryError: if not init: @@ -345,7 +369,9 @@ class Submodule(util.IndexObject, Iterable, Traversable): # don't check it out at first - nonetheless it will create a local # branch according to the remote-HEAD if possible + progress.update(BEGIN|CLONE, 0, 1, "Cloning %s to %s" % (self.url, module_path)) mrepo = git.Repo.clone_from(self.url, module_path, n=True) + progress.update(END|CLONE, 0, 1, "Done cloning to %s" % module_path) # see whether we have a valid branch to checkout try: @@ -396,6 +422,7 @@ class Submodule(util.IndexObject, Iterable, Traversable): # update the working tree if mrepo.head.commit.binsha != binsha: + progress.update(BEGIN|UPDWKTREE, 0, 1, "Updating working tree at %s" % self.path) if is_detached: # NOTE: for now we force, the user is no supposed to change detached # submodules anyway. Maybe at some point this becomes an option, to @@ -408,13 +435,14 @@ class Submodule(util.IndexObject, Iterable, Traversable): # branch - this should be prevented when setting the branch option mrepo.head.reset(hexsha, index=True, working_tree=True) # END handle checkout + progress.update(END|UPDWKTREE, 0, 1, "Done updating working tree at %s" % self.path) # END update to new commit only if needed # HANDLE RECURSION ################## if recursive: for submodule in self.iter_items(self.module()): - submodule.update(recursive, init, to_latest_revision) + submodule.update(recursive, init, to_latest_revision, progress=progress) # END handle recursive update # END for each submodule diff --git a/objects/submodule/root.py b/objects/submodule/root.py index b0dba08b..49fb1417 100644 --- a/objects/submodule/root.py +++ b/objects/submodule/root.py @@ -10,6 +10,20 @@ import sys __all__ = ["RootModule"] +class RootUpdateProgress(UpdateProgress): + """Utility class which adds more opcodes to the UpdateProgress""" + REMOVE, PATHCHANGE, BRANCHCHANGE, URLCHANGE = [1 << x for x in range(UpdateProgress._num_op_codes, UpdateProgress._num_op_codes+4)] + _num_op_codes = UpdateProgress._num_op_codes+4 + + __slots__ = tuple() + +BEGIN = RootUpdateProgress.BEGIN +END = RootUpdateProgress.END +REMOVE = RootUpdateProgress.REMOVE +BRANCHCHANGE = RootUpdateProgress.BRANCHCHANGE +URLCHANGE = RootUpdateProgress.URLCHANGE +PATHCHANGE = RootUpdateProgress.PATHCHANGE + class RootModule(Submodule): """A (virtual) Root of all submodules in the given repository. It can be used to more easily traverse all submodules of the master repository""" @@ -59,7 +73,7 @@ class RootModule(Submodule): :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 - :param progress: UpdateProgress instance or None if no progress should be sent + :param progress: RootUpdateProgress instance or None if no progress should be sent :param dry_run: if True, operations will not actually be performed. Progress messages will change accordingly to indicate the WOULD DO state of the operation.""" if self.repo.bare: @@ -67,13 +81,13 @@ class RootModule(Submodule): # END handle bare if progress is None: - progress = UpdateProgress() + progress = RootUpdateProgress() #END assure progress is set repo = self.repo - # HANDLE COMMITS - ################## + # SETUP BASE COMMIT + ################### cur_commit = repo.head.commit if previous_commit is None: try: @@ -97,29 +111,50 @@ class RootModule(Submodule): # HANDLE REMOVALS ################### - for rsm in (spsms - ssms): + rrsm = (spsms - ssms) + len_rrsm = len(rrsm) + for i, rsm in enumerate(rrsm): + op = REMOVE + if i == 0: + op |= BEGIN + #END handle begin + # fake it into thinking its at the current commit to allow deletion # of previous module. Trigger the cache to be updated before that - #rsm.url + progress.update(op, i, len_rrsm, "Removing submodule %s at %s" % (rsm.name, rsm.abspath)) rsm._parent_commit = repo.head.commit rsm.remove(configuration=False, module=True, force=force_remove) + + if i == len_rrsm-1: + op |= END + #END handle end + progress.update(op, i, len_rrsm, "Done removing submodule %s" % rsm.name) # END for each removed submodule # HANDLE PATH RENAMES ##################### # url changes + branch changes - for csm in (spsms & ssms): + csms = (spsms & ssms) + len_csms = len(csms) + for i, csm in enumerate(csms): psm = psms[csm.name] sm = sms[csm.name] + #PATH CHANGES + ############## if sm.path != psm.path and psm.module_exists(): + progress.update(BEGIN|PATHCHANGE, i, len_csms, "Moving submodule's %s repository from %s to %s" % (sm.name, psm.abspath, sm.abspath)) # move the module to the new path psm.move(sm.path, module=True, configuration=False) + progress.update(END|PATHCHANGE, i, len_csms, "Done moving repository of submodule %s" % sm.name) # END handle path changes if sm.module_exists(): - # handle url change + # HANDLE URL CHANGE + ################### if sm.url != psm.url: + progress.update(BEGIN|URLCHANGE, i, len_csms, "Changing url of submodule %s from %s to %s" % (sm.name, psm.url, sm.url)) + # Add the new remote, remove the old one # This way, if the url just changes, the commits will not # have to be re-retrieved @@ -130,7 +165,6 @@ class RootModule(Submodule): # don't do anything if we already have the url we search in place if len([r for r in rmts if r.url == sm.url]) == 0: - assert nn not in [r.name for r in rmts] smr = smm.create_remote(nn, sm.url) smr.fetch(progress=progress) @@ -202,12 +236,16 @@ class RootModule(Submodule): #NOTE: All checkout is performed by the base implementation of update + progress.update(END|URLCHANGE, i, len_csms, "Done adjusting url of submodule %s" % (sm.name)) # END skip remote handling if new url already exists in module # END handle url + # HANDLE PATH CHANGES + ##################### if sm.branch_path != psm.branch_path: # finally, create a new tracking branch which tracks the # new remote branch + progress.update(BEGIN|BRANCHCHANGE, i, len_csms, "Changing branch of submodule %s from %s to %s" % (sm.name, psm.branch_path, sm.branch_path)) smm = sm.module() smmr = smm.remotes try: @@ -234,6 +272,7 @@ class RootModule(Submodule): #NOTE: All checkout is done in the base implementation of update + progress.update(END|BRANCHCHANGE, i, len_csms, "Done changing branch of submodule %s" % sm.name) #END handle branch #END handle # END for each common submodule @@ -242,15 +281,17 @@ class RootModule(Submodule): ###################################### for sm in sms: # update the submodule using the default method - sm.update(recursive=False, init=init, to_latest_revision=to_latest_revision, progress=progress) + sm.update(recursive=False, init=init, to_latest_revision=to_latest_revision, + progress=progress, dry_run=dry_run) # update recursively depth first - question is which inconsitent # state will be better in case it fails somewhere. Defective branch # or defective depth. The RootSubmodule type will never process itself, # which was done in the previous expression if recursive: - type(self)(sm.module()).update(recursive=True, force_remove=force_remove, - init=init, to_latest_revision=to_latest_revision) + type(self)(sm.module()).update( recursive=True, force_remove=force_remove, + init=init, to_latest_revision=to_latest_revision, + progress=progress, dry_run=dry_run) #END handle recursive # END for each submodule to update |