diff options
author | Chris St. Pierre <chris.a.st.pierre@gmail.com> | 2012-11-15 17:03:23 -0500 |
---|---|---|
committer | Chris St. Pierre <chris.a.st.pierre@gmail.com> | 2012-11-16 09:57:53 -0500 |
commit | 12684bada59c9ddc08165dad757682514b54634c (patch) | |
tree | 17fcba524c1ce6f157a3c93e3a9a77b5d1fa9d6f | |
parent | a6a29aa01744cc893741ddf558f415b7c705d3f6 (diff) | |
download | bcfg2-12684bada59c9ddc08165dad757682514b54634c.tar.gz bcfg2-12684bada59c9ddc08165dad757682514b54634c.tar.bz2 bcfg2-12684bada59c9ddc08165dad757682514b54634c.zip |
Git: Added ability to update to a specific tree-ish
-rw-r--r-- | doc/server/plugins/version/git.txt | 35 | ||||
-rw-r--r-- | src/lib/Bcfg2/Server/Plugins/Git.py | 51 |
2 files changed, 73 insertions, 13 deletions
diff --git a/doc/server/plugins/version/git.txt b/doc/server/plugins/version/git.txt index b3c469d6c..3f7ab9d9b 100644 --- a/doc/server/plugins/version/git.txt +++ b/doc/server/plugins/version/git.txt @@ -20,9 +20,38 @@ it will include the current repository revision in the reports/statistics. Additionally, if the ``GitPython`` library is installed, the Git -plugin exposes an additional XML-RPC method call, ``Git.Update``, -which updates the working copy to the latest version in the remote -origin. +plugin exposes an additional XML-RPC method call, ``Git.Update``. +With no arguments, ``Git.Update`` updates the working copy to the +latest version in the remote tracking branch. If the current working +copy doesn't have a remote tracking branch, then nothing is done. + +``Git.Update`` can also be given a single argument, the name of a git +tree-ish (branch, tag, ref, commit, etc.) to check out. When this is +done, the new working is updated as well. + +For example:: + + bcfg2-admin xcmd Git.Update master + +This checks out the ``master`` branch and updates it to the latest +data from the remote ``master`` (if applicable). If you then run:: + + bcfg2-admin xcmd Git.Update + +This updates to the latest remote data without changing branches. +Then:: + + bcfg2-admin xcmd Git.Update dd0bb776c + +This checks out the specified commit. Subsequently:: + + bcfg2-admin xcmd Git.Update + +This does nothing, because the working copy is now in "detached HEAD" +state, and there can be no remote tracking branch to update from. + +To put it another way, once you tell ``Git.Update`` which tree-ish to +checkout, it stays on that tree-ish until you tell it otherwise. Enabling the Git plugin ======================= diff --git a/src/lib/Bcfg2/Server/Plugins/Git.py b/src/lib/Bcfg2/Server/Plugins/Git.py index 61d581009..8cc63a46f 100644 --- a/src/lib/Bcfg2/Server/Plugins/Git.py +++ b/src/lib/Bcfg2/Server/Plugins/Git.py @@ -52,17 +52,48 @@ class Git(Bcfg2.Server.Plugin.Version): self.logger.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) - def Update(self): + def Update(self, ref=None): """ Git.Update() => True|False Update the working copy against the upstream repository """ + self.logger.info("Git: Git.Update(ref='%s')" % ref) + self.debug_log("Git: Performing garbage collection on repo at %s" % + self.vcs_root) try: - self.repo.git.pull("--rebase") - self.logger.info("Git repo at %s updated to %s" % - (self.vcs_root, self.get_revision())) - return True - except: # pylint: disable=W0702 - err = sys.exc_info()[1] - msg = "Failed to pull from git repository: %s" % err - self.logger.error(msg) - raise Bcfg2.Server.Plugin.PluginExecutionError(msg) + self.repo.git.gc('--auto') + except git.GitCommandError: + self.logger.warning("Git: Failed to perform garbage collection: %s" + % sys.exc_info()[1]) + + if ref: + self.debug_log("Git: Checking out %s" % ref) + try: + self.repo.git.checkout('-f', ref) + except git.GitCommandError: + err = sys.exc_info()[1] + msg = "Git: Failed to checkout %s: %s" % (ref, err) + self.logger.error(msg) + raise Bcfg2.Server.Plugin.PluginExecutionError(msg) + + # determine if we should try to pull to get the latest commit + # on this head + tracking = None + if not self.repo.head.is_detached: + self.debug_log("Git: Determining if %s is a tracking branch" % + self.repo.head.ref.name) + tracking = self.repo.head.ref.tracking_branch() + + if tracking is not None: + self.debug_log("Git: %s is a tracking branch, pulling from %s" % + (self.repo.head.ref.name, tracking)) + try: + self.repo.git.pull("--rebase") + except: # pylint: disable=W0702 + err = sys.exc_info()[1] + msg = "Git: Failed to pull from upstream: %s" % err + self.logger.error(msg) + raise Bcfg2.Server.Plugin.PluginExecutionError(msg) + + self.logger.info("Git: Repo at %s updated to %s" % + (self.vcs_root, self.get_revision())) + return True |