Add config option for git-fetch refs hack
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Thu, 18 Sep 2014 13:04:12 +0000 (16:04 +0300)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Thu, 18 Sep 2014 13:04:12 +0000 (16:04 +0300)
New config file option 'repo-cache-refs-hack' for enabling the refs hack
in repocache. The option is disabled, by default.

Enabling the hack makes it possible to fetch/clone remote repositories
that have branches (refs/heads/*) that point to tag objects. This may
encountered with Gerrit repositories - "pure" Git repositories managed
by Git tools shouldn't have such branches as Git sanity checking
prevents them (which is the reason this hack is needed).

Change-Id: I5e0203d4f0f93c18c2f70c76ef9c8b6ff536fd67
Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
config/git-buildpackage
obs_service_gbp/command.py
obs_service_gbp_utils/__init__.py
tests/test_obs_service_gbp.py

index 840f9bb20322fa153c90972391b54afb6b78dd93..b912f7e3069407bdb7ee418e3d8e58630acd32b0 100644 (file)
 ##directly.
 #gbp-user = gbpservice
 #gbp-group = gbpservice
+
+## Git-fetch refs hack
+## Allows fetching/cloning remote repositories that have refs/heads/* pointing
+## to a tag object. Gerrit allows branches pointing to tag objects. However,
+## git disallows this which causes fetch to fail in repocache if such branches
+## exist in the remote repository. This setting activates a hack to workaround
+## the problem with such remote repositories.
+#repo-cache-refs-hack = yes
index cc14c4fc908c8c58f456792253afb97b63e51a98..a7ad9c7adfadba49f599933bb27e42efc645de97 100644 (file)
@@ -29,8 +29,8 @@ from gbp.scripts.buildpackage import main as gbp_deb
 from gbp.scripts.buildpackage_rpm import main as gbp_rpm
 
 from obs_service_gbp import LOGGER, gbplog
-from obs_service_gbp_utils import GbpServiceError, GbpChildBTError, fork_call
-from obs_service_gbp_utils import sanitize_uid_gid, write_treeish_meta
+from obs_service_gbp_utils import (GbpServiceError, GbpChildBTError, fork_call,
+            sanitize_uid_gid, write_treeish_meta, str_to_bool)
 from gbp_repocache import CachedRepo, CachedRepoError
 import gbp_repocache
 
@@ -77,7 +77,8 @@ def read_config(filenames):
     defaults = {'repo-cache-dir': '/var/cache/obs/git-buildpackage-repos/',
                 'gbp-tmp-dir': '/tmp/obs-service-gbp/',
                 'gbp-user': None,
-                'gbp-group': None}
+                'gbp-group': None,
+                'repo-cache-refs-hack': 'no'}
 
     filenames = [os.path.expanduser(fname) for fname in filenames]
     LOGGER.debug('Trying %s config files: %s', len(filenames), filenames)
@@ -202,8 +203,10 @@ def main(argv=None):
     config = read_config(args.config)
 
     # Create / update cached repository
+    refs_hack = str_to_bool(config['repo-cache-refs-hack'])
     try:
-        repo = CachedRepo(config['repo-cache-dir'], args.url)
+        repo = CachedRepo(config['repo-cache-dir'], args.url,
+                          refs_hack=refs_hack)
         args.revision = repo.update_working_copy(args.revision)
     except CachedRepoError as err:
         LOGGER.error('RepoCache: %s', str(err))
index 532911d12fc0fb83c002eaf7f2e107b097a1d9b1..a25b61f8a729713499d74a472e104606fa186c6d 100644 (file)
@@ -172,3 +172,22 @@ def write_treeish_meta(repo, treeish, outdir, filename):
     except IOError as err:
         raise GbpServiceError("Failed to write '%s': %s" % (filename, err))
 
+
+def str_to_bool(string, default=False):
+    """Convert (config value) string to boolean. Returns default if unable to
+       determine.
+
+    >>> str_to_bool('true')
+    True
+    >>> str_to_bool('0')
+    False
+    >>> str_to_bool('foo', True)
+    True
+    """
+    value = string.strip().lower()
+    if value in ['1', 'yes', 'on', 'true', 'enabled']:
+        return True
+    elif value in ['0', 'no', 'off', 'false', 'disabled']:
+        return False
+    else:
+        return default
index ba8439847aaee0c1b5232e47a4d0c7e37b0077b2..17ba0cc7f78397c9226265976f8a1b03ed9c3cbd 100644 (file)
@@ -18,6 +18,7 @@
 # MA 02110-1301, USA.
 """Tests for the git-buildpackage OBS source service"""
 
+import glob
 import grp
 import json
 import mock
@@ -197,3 +198,18 @@ class TestService(UnitTestsBase):
         # Return env
         del os.environ['OBS_GIT_BUILDPACKAGE_GBP_USER']
 
+    def test_refs_hack_config(self):
+        """Test enabling the repocache refs hack through config"""
+        # Try with hack disabled (default)
+        eq_(service(['--url', self.orig_repo.path, '--revision=rpm']), 0)
+        refs = glob.glob(self.cachedir + '/*/*/.git/refs')
+        eq_(len(refs), 1)
+        ok_(not os.path.islink(refs[0]))
+
+        # Enable hack -> refs should be a symlink
+        os.environ['OBS_GIT_BUILDPACKAGE_REPO_CACHE_REFS_HACK'] = 'yes'
+        eq_(service(['--url', self.orig_repo.path, '--revision=rpm']), 0)
+        ok_(os.path.islink(refs[0]))
+
+        # Restore env
+        del os.environ['OBS_GIT_BUILDPACKAGE_REPO_CACHE_REFS_HACK']