Implementation of manifest defined githooks

When working within a team or corporation it is often
useful/required to use predefined git templates. This
change teaches repo to use a per-remote git hook template
structure.

The implementation is done as a continuation of the
existing projecthook functionality. The terminology is
therefore defined as projecthooks.

The downloaded projecthooks are stored in the .repo
directory as a metaproject separating them from the users
project forest.

The projecthooks are downloaded and set up when doing a
repo init and updated for each new repo init.

When downloading a mirror the projecthooks gits are
not added to the bare forest since the intention is to
ensure that the latest are used (allows for company policy
enforcement).

The projecthooks are defined in the manifest file in the
remote element as a subnode, the name refers to the
project name on the server referred to in the remote.
<remote name="myremote ..>
   <projecthook name="myprojecthookgit" revision="myrevision"/>
</remote>

The hooks found in the projecthook revision supersede
the stock hooks found in repo. This removes the need for
updating the projecthook gits for repo stock hook changes.

Change-Id: I6796b7b0342c1f83c35f4b3e46782581b069a561
Signed-off-by: Patrik Ryd <patrik.ryd@stericsson.com>
Signed-off-by: Ian Kumlien <ian.kumlien@gmail.com>
This commit is contained in:
Jimmie Wester
2012-10-24 14:35:05 +02:00
committed by David Pursehouse
parent ee69084421
commit 38e4387f8e
4 changed files with 117 additions and 28 deletions

View File

@ -32,7 +32,7 @@ else:
from color import Coloring
from command import InteractiveCommand, MirrorSafeCommand
from error import ManifestParseError
from project import SyncBuffer
from project import SyncBuffer, MetaProject
from git_config import GitConfig
from git_command import git_require, MIN_GIT_VERSION
@ -374,6 +374,52 @@ to update the working directory files.
print(' rm -r %s/.repo' % self.manifest.topdir)
print('and try again.')
def _SyncProjectHooks(self, opt, repodir):
"""Downloads the defined hooks supplied in the projecthooks element
"""
# Always delete projecthooks and re-download for every new init.
projecthooksdir = os.path.join(repodir, 'projecthooks')
if os.path.exists(projecthooksdir):
shutil.rmtree(projecthooksdir)
for remotename in self.manifest.remotes:
r = self.manifest.remotes.get(remotename)
if r.projecthookName is not None and r.projecthookRevision is not None:
projecthookurl = r.resolvedFetchUrl.rstrip('/') + '/' + r.projecthookName
ph = MetaProject(manifest = self.manifest,
name = r.projecthookName,
gitdir = os.path.join(projecthooksdir,'%s/%s.git' % (remotename, r.projecthookName)),
worktree = os.path.join(projecthooksdir,'%s/%s' % (remotename, r.projecthookName)))
ph.revisionExpr = r.projecthookRevision
is_new = not ph.Exists
if is_new:
if not opt.quiet:
print('Get projecthook %s' % \
GitConfig.ForUser().UrlInsteadOf(projecthookurl), file=sys.stderr)
ph._InitGitDir(MirrorOverride=True)
phr = ph.GetRemote(remotename)
phr.name = 'origin'
phr.url = projecthookurl
phr.ResetFetch()
phr.Save()
if not ph.Sync_NetworkHalf(quiet=opt.quiet, is_new=is_new, clone_bundle=False):
print('fatal: cannot obtain projecthook %s' % phr.url, file=sys.stderr)
# Better delete the git dir if we created it; otherwise next
# time (when user fixes problems) we won't go through the "is_new" logic.
if is_new:
shutil.rmtree(ph.gitdir)
sys.exit(1)
syncbuf = SyncBuffer(ph.config)
ph.Sync_LocalHalf(syncbuf)
syncbuf.Finish()
def Execute(self, opt, args):
git_require(MIN_GIT_VERSION, fail=True)
@ -389,6 +435,7 @@ to update the working directory files.
self._SyncManifest(opt)
self._LinkManifest(opt.manifest_name)
self._SyncProjectHooks(opt, self.manifest.repodir)
if os.isatty(0) and os.isatty(1) and not self.manifest.IsMirror:
if opt.config_name or self._ShouldConfigureUser():