From 0b5ca2535885812d110b7868ea6ef18a47ca7c5f Mon Sep 17 00:00:00 2001 From: Tom Scogland Date: Sat, 13 Jun 2015 15:23:32 -0700 Subject: [PATCH 1/2] Fix for repos with many tags Ensures all tags are ready before checkout, using `--branch` if possible and an extra pull if that is not available. Also adds `--depth 1` to create shallow clones if the git version is sufficient. Fixes #64. --- lib/spack/spack/fetch_strategy.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py index e46ec74e09..3e6f59d9b8 100644 --- a/lib/spack/spack/fetch_strategy.py +++ b/lib/spack/spack/fetch_strategy.py @@ -417,12 +417,18 @@ def fetch(self): # If we want a particular branch ask for it. if self.branch: args.extend(['--branch', self.branch]) + elif self.tag and self.git_version >= ver('1.8.5.2'): + args.extend(['--branch', self.tag]) # Try to be efficient if we're using a new enough git. # This checks out only one branch's history if self.git_version > ver('1.7.10'): args.append('--single-branch') + # Yet more efficiency, only download a 1-commit deep tree + if self.git_version >= ver('1.7.1'): + args.extend(['--depth','1']) + args.append(self.url) self.git(*args) self.stage.chdir_to_source() @@ -430,7 +436,8 @@ def fetch(self): # For tags, be conservative and check them out AFTER # cloning. Later git versions can do this with clone # --branch, but older ones fail. - if self.tag: + if self.tag and self.git_version < ver('1.8.5.2'): + self.git('pull', '--tags') self.git('checkout', self.tag) From cfb883646f91165c9d839c819519e0c6cea31f47 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Sat, 13 Jun 2015 17:52:00 -0700 Subject: [PATCH 2/2] Fix for `git pull --tags` when using git 1.7.1 - Added `ignore_errors` option to `Executable.__call__` - Can avoid raising errors on *specific* error return values. --- lib/spack/spack/fetch_strategy.py | 5 ++++- lib/spack/spack/util/executable.py | 8 +++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py index 3e6f59d9b8..0ba0251caa 100644 --- a/lib/spack/spack/fetch_strategy.py +++ b/lib/spack/spack/fetch_strategy.py @@ -437,7 +437,10 @@ def fetch(self): # cloning. Later git versions can do this with clone # --branch, but older ones fail. if self.tag and self.git_version < ver('1.8.5.2'): - self.git('pull', '--tags') + # pull --tags returns a "special" error code of 1 in + # older versions that we have to ignore. + # see: https://github.com/git/git/commit/19d122b + self.git('pull', '--tags', ignore_errors=1) self.git('checkout', self.tag) diff --git a/lib/spack/spack/util/executable.py b/lib/spack/spack/util/executable.py index 1dcda0d87f..67e8cddd98 100644 --- a/lib/spack/spack/util/executable.py +++ b/lib/spack/spack/util/executable.py @@ -57,8 +57,13 @@ def __call__(self, *args, **kwargs): """Run the executable with subprocess.check_output, return output.""" return_output = kwargs.get("return_output", False) fail_on_error = kwargs.get("fail_on_error", True) + ignore_errors = kwargs.get("ignore_errors", ()) error = kwargs.get("error", sys.stderr) + # if they just want to ignore one error code, make it a tuple. + if isinstance(ignore_errors, int): + ignore_errors = (ignore_errors,) + quoted_args = [arg for arg in args if re.search(r'^"|^\'|"$|\'$', arg)] if quoted_args: tty.warn("Quotes in command arguments can confuse scripts like configure.", @@ -85,7 +90,8 @@ def __call__(self, *args, **kwargs): out, err = proc.communicate() self.returncode = proc.returncode - if fail_on_error and proc.returncode != 0: + rc = proc.returncode + if fail_on_error and rc != 0 and (rc not in ignore_errors): raise ProcessError("Command exited with status %d:" % proc.returncode, cmd_line) if return_output: