def clone_bare_recursive(repository, directory, branch=None): if branch: #only clone using branch on the top level repository #to get the wanted state of submodules cmd = clone_cmd % ('--branch %s' % (branch), repository, directory) else: cmd = clone_cmd % ("", repository, directory) if not oebakery.call(cmd): logger.error("bare clone of module %s failed", directory) return [directory] gitmodules = oebakery.call("git cat-file blob HEAD:.gitmodules", dir=directory, quiet=True) if not gitmodules: return submodules = oebakery.gitmodules.parse_dot_gitmodules(buffer=gitmodules) failed = [] for submodule in submodules.values(): path = submodule['path'] url = submodule['url'] if url != './' + path: # only clone relative submodules continue ret = clone_bare_recursive(os.path.join(repository, path), os.path.join(directory, path)) if ret: failed.extend(ret) return failed
def clone_bare_recursive(repository, directory, branch=None): if branch: #only clone using branch on the top level repository #to get the wanted state of submodules cmd = clone_cmd%('--branch %s'%(branch),repository, directory) else: cmd = clone_cmd%("",repository, directory) if not oebakery.call(cmd): logger.error("bare clone of module %s failed", directory) return [directory] gitmodules = oebakery.call( "git cat-file blob HEAD:.gitmodules", dir=directory, quiet=True) if not gitmodules: return submodules = oebakery.gitmodules.parse_dot_gitmodules(buffer=gitmodules) failed = [] for submodule in submodules.values(): path = submodule['path'] url = submodule['url'] if url != './' + path: # only clone relative submodules continue ret = clone_bare_recursive( os.path.join(repository, path), os.path.join(directory, path)) if ret: failed.extend(ret) return failed
def run(options, args, config): topdir = oebakery.set_topdir(os.path.curdir) if oebakery.call("git status", quiet=True): oebakery.fatal("Already initialized: %s" % (topdir)) if not oebakery.call("git init"): oebakery.fatal("Failed to initialize git") if not oebakery.call("git config push.default tracking"): oebakery.fatal("Failed to set push.default = tracking") oebakery.path.copy_local_conf_sample(config["CONFDIR"] or "conf") return ["update"]
def run(options, args, config): topdir = oebakery.set_topdir(os.path.curdir) if oebakery.call("git status", quiet=True): oebakery.fatal("Already initialized: %s"%(topdir)) if not oebakery.call("git init"): oebakery.fatal("Failed to initialize git") if not oebakery.call("git config push.default tracking"): oebakery.fatal("Failed to set push.default = tracking") oebakery.path.copy_local_conf_sample(config["CONFDIR"] or "conf") return ["update"]
def git_branch_status(path=None, options=None, nobranch=False): cmd = "git branch -v --no-abbrev" if options: cmd += " " + options branches = {} for line in oebakery.call(cmd, quiet=True, dir=path).split("\n"): if not line: continue asterix = line[0] if asterix == "*": current = True else: current = False line = line[2:] if line[:11] == "(no branch)": if not nobranch: continue name = "" line = line[11:] line.lstrip() else: (name, line) = line.split(None, 1) commitid, subject = line.split(None, 1) branches[name] = { "current": current, "commitid": commitid, "subject": subject, } return branches
def git_branch_status(path=None, options=None, nobranch=False): cmd = "git branch -v --no-abbrev" if options: cmd += " " + options branches = {} for line in oebakery.call(cmd, quiet=True, dir=path).split("\n"): if not line: continue asterix = line[0] if asterix == "*": current = True else: current = False line = line[2:] if line[:11] == "(no branch)": if not nobranch: continue name = "" line = line[11:] line.lstrip() else: (name, line) = line.split(None, 1) commitid, subject = line.split(None, 1) branches[name] = { "current" : current, "commitid" :commitid, "subject" : subject, } return branches
def git_remote_update(path=None): # older git versions return 1 on success, and newer versions 0 # so we will just ignore the return code for now oebakery.call("git remote update", dir=path) remotes = oebakery.call("git remote", dir=path, quiet=True) ok = True if remotes: for remote in remotes.split("\n"): if not remote or len(remote) == 0: continue if not oebakery.call("git remote prune %s" % (remote), dir=path): msg = "Failed to prune remote %s" % (remote) if path: msg += " in %s" % (path) logger.error(msg) ok = False return ok
def git_pull(path=None, branch=None): if path: name = " submodule %s" % (path) else: name = "" if not oebakery.call("git pull", dir=path): logger.error("Failed to pull %s" % (name)) return False return True
def git_pull(path=None, branch=None): if path: name = " submodule %s"%(path) else: name = "" if not oebakery.call("git pull", dir=path): logger.error("Failed to pull %s"%(name)) return False return True
def git_remote_update(path=None): # older git versions return 1 on success, and newer versions 0 # so we will just ignore the return code for now oebakery.call("git remote update", dir=path) remotes = oebakery.call("git remote", dir=path, quiet=True) ok = True if remotes: for remote in remotes.split("\n"): if not remote or len(remote) == 0: continue if not oebakery.call("git remote prune %s"%(remote), dir=path): msg = "Failed to prune remote %s"%(remote) if path: msg += " in %s"%(path) logger.error(msg) ok = False return ok
def clone_checkout(options): if options.branch: branch_arg = ' --branch %s'%(options.branch) else: branch_arg = '' if not oebakery.call('git clone --recursive %s%s %s'%( options.repository, branch_arg ,options.directory)): return "git clone failed" topdir = oebakery.set_topdir(options.directory) oebakery.chdir(options.directory) oebakery.path.copy_local_conf_sample("conf") if not oebakery.call('git config push.default tracking'): print 'Failed to set push.default = tracking' return ["update"]
def clone_checkout(options): if options.branch: branch_arg = ' --branch %s' % (options.branch) else: branch_arg = '' if not oebakery.call('git clone --recursive %s%s %s' % (options.repository, branch_arg, options.directory)): return "git clone failed" topdir = oebakery.set_topdir(options.directory) oebakery.chdir(options.directory) oebakery.path.copy_local_conf_sample("conf") if not oebakery.call('git config push.default tracking'): print 'Failed to set push.default = tracking' return ["update"]
def git_submodule_status(path): status = oebakery.call('git submodule status', quiet=True) if not status: return None for line in status.split('\n'): if len(line) == 0: continue if (path == line[1:].split()[1]): prefix = line[0] commitid = line[1:].split()[0] return (prefix, commitid) return None
def update_submodule(path, fetch_url, params): push_url = params.get("push", None) ok = True if (os.path.exists(path) and not oebakery.call("git submodule sync -- %s" % (path))): logger.error("Failed to synchronize git submodule") status = git_submodule_status(path) if status and status[0] == "-": cmd = "git submodule update --init --recursive" if not oebakery.call("%s %s" % (cmd, path)): logger.error("Failed to add submodule: %s", path) return False elif status is None: cmd = "git submodule add -f" if "branch" in params: branch = params["branch"] if branch != "master": cmd += " -b %s" % (params["branch"]) if not oebakery.call("%s -- %s %s" % (cmd, fetch_url, path)): logger.error("Failed to add submodule: %s", path) return False if not oebakery.call("git submodule update --init --recursive %s" % (path)): logger.error("Failed to initialize submodule: %s", path) return False # set push_default to 'tracking' if unset push_default = oebakery.call('git config --get push.default', dir=path, quiet=True) if (push_default == None): oebakery.call('git config push.default tracking', dir=path) # update origin fetch url if necessary current_url = oebakery.call('git config --get remote.origin.url', dir=path, quiet=True) if current_url: current_url = current_url.strip() if fetch_url != current_url: if fetch_url.startswith('./'): fetch_url_abs = os.path.join(manifest_url(), fetch_url[2:]) elif fetch_url.startswith('../'): fetch_url_abs = os.path.join(os.path.dirname(manifest_url()), fetch_url[3:]) else: fetch_url_abs = fetch_url if (fetch_url_abs != current_url and not oebakery.call( 'git config remote.origin.url %s' % (fetch_url), dir=path)): logger.error("Failed to set origin url %s for %s", fetch_url, path) ok = False # set push url as specified current_url = oebakery.call('git config --get remote.origin.pushurl', dir=path, quiet=True) if current_url: current_url = current_url.strip() if push_url and current_url != push_url: if not oebakery.call( 'git config remote.origin.pushurl %s' % (push_url), dir=path): logger.error("Failed to set origin push url %s for %s", push_url, path) ok = False if not oebakery.call('git remote update --prune origin', dir=path): logger.error("failed to update remote origin") ok = False # remove override of push url if not specified if not push_url and current_url: if not oebakery.call('git config --unset remote.origin.pushurl', dir=path): logger.error("Failed to unset origin push url for %s", path) ok = False # update remotes for (name, url) in params.get("remote", []): if not git_update_remote(name, url, path=path): logger.error("update of remote %s failed", name) ok = False # if "tag" in params: tag = params["tag"] if not oebakery.call("git checkout --detach refs/tags/%s" % (tag), dir=path): logger.error("Failed to checkout submodule %s tag %s", path, tag) return False elif "commit" in params: commit = params["commit"] if not oebakery.call("git checkout --detach %s" % (commit), dir=path): logger.error("Failed to checkout submodule %s commit %s", path, commit) return False elif "branch" in params: branch = params["branch"] branches = git_branch_status(path) if branch in branches: if not branches[branch]["current"]: if not oebakery.call("git checkout %s" % (branch), dir=path): logger.error("Failed to checkout submodule %s branch %s", path, branch) return False else: if not oebakery.call("git checkout -t -b %s %s" % (branch, "origin/%s" % (branch)), dir=path): logger.error("Failed to checkout%s branch %s", name, branch) return False current_remote = oebakery.call("git config --get branch.%s.remote" % (branch), dir=path, quiet=True) current_merge = oebakery.call("git config --get branch.%s.merge" % (branch), dir=path, quiet=True) if (current_remote is None or current_merge is None or current_remote.strip() != "origin" or current_merge.strip() != "refs/heads/%s" % (branch)): if not oebakery.call("git branch --set-upstream %s origin/%s" % (branch, branch), dir=path): ok = False else: if not oebakery.call("git submodule update --init --recursive %s" % (path)): logger.error("Failed to initialize submodule: %s", path) ok = False return ok
def git_update_remote(name, url, path=None): ok = True url_split = url.split(",") if len(url_split) < 1 or len(url_split) > 2: logger.error("Invalid remote url: %s", url) return False if len(url_split) == 2: push_url = url_split[1] else: push_url = None fetch_url = url_split[0] # get list of remotes and their urls remotes_list = oebakery.call('git remote -v', dir=path, quiet=True) if remotes_list == None: logger.error("Failed to get list of remotes") return False else: remotes_list = remotes_list.split('\n') # get fetch urls remotes_fetch = {} for remote in remotes_list: if '\t' in remote: (iter_name, iter_url) = string.split(remote, '\t', maxsplit=1) if iter_url[-8:] == ' (fetch)': remotes_fetch[iter_name] = iter_url[:-8] elif iter_url[-7:] == ' (push)': # don't take push url here, but use git config to know # if it is actually set, or just derived from fetch url pass else: # pre git-1.6.4 did only have fetch url's remotes_fetch[iter_name] = iter_url # get push urls remotes_push = {} for iter_name in remotes_fetch.keys(): iter_url = oebakery.call('git config --get remote.%s.pushurl' % iter_name, dir=path, quiet=True) if iter_url: remotes_push[iter_name] = iter_url.strip() # if remote is not found, add it and return if not remotes_fetch.has_key(name): if not oebakery.call('git remote add %s %s' % (name, fetch_url), dir=path): logger.error("Failed to add remote %s", name) return False # also add push url if specified if push_url: if not oebakery.call('git config remote.%s.pushurl %s' % (name, push_url), dir=path): logger.error("failed to set pushurl %s for %s", push_url, name) ok = False return ok # change (fetch) url if not matching if remotes_fetch[name] != fetch_url: if not oebakery.call('git config remote.%s.url %s' % (name, fetch_url), dir=path): logger.error("failed to set url %s for %s", name, fetch_url) ok = False # if push url is different url, change it if push_url: if not remotes_push.has_key(name) or remotes_push[name] != push_url: if not oebakery.call('git config remote.%s.pushurl %s' % (name, push_url), dir=path): logger.error("failed to set pushurl %s for %s", push_url, name) ok = False # if push url is currently set, but shouldn't be, remove it else: if remotes_push.has_key(name) and remotes_push[name] != fetch_url: if not oebakery.call( 'git config --unset remote.%s.pushurl' % (name), dir=path): logger.error("failed to unset pushurl for %s", name) ok = False return ok
def manifest_url(): global _manifest_url if _manifest_url is None: _manifest_url = oebakery.call( 'git config --get remote.origin.url', quiet=True).strip() return _manifest_url
def git_update_remote(name, url, path=None): ok = True url_split = url.split(",") if len(url_split) < 1 or len(url_split) > 2: logger.error("Invalid remote url: %s", url) return False if len(url_split) == 2: push_url = url_split[1] else: push_url = None fetch_url=url_split[0] # get list of remotes and their urls remotes_list = oebakery.call('git remote -v', dir=path, quiet=True) if remotes_list == None: logger.error("Failed to get list of remotes") return False else: remotes_list = remotes_list.split('\n') # get fetch urls remotes_fetch = {} for remote in remotes_list: if '\t' in remote: (iter_name, iter_url) = string.split(remote, '\t', maxsplit=1) if iter_url[-8:] == ' (fetch)': remotes_fetch[iter_name] = iter_url[:-8] elif iter_url[-7:] == ' (push)': # don't take push url here, but use git config to know # if it is actually set, or just derived from fetch url pass else: # pre git-1.6.4 did only have fetch url's remotes_fetch[iter_name] = iter_url # get push urls remotes_push = {} for iter_name in remotes_fetch.keys(): iter_url = oebakery.call('git config --get remote.%s.pushurl'%iter_name, dir=path, quiet=True) if iter_url: remotes_push[iter_name] = iter_url.strip() # if remote is not found, add it and return if not remotes_fetch.has_key(name): if not oebakery.call('git remote add %s %s'%(name, fetch_url), dir=path): logger.error("Failed to add remote %s", name) return False # also add push url if specified if push_url: if not oebakery.call( 'git config remote.%s.pushurl %s'%(name, push_url), dir=path): logger.error("failed to set pushurl %s for %s", push_url, name) ok = False return ok # change (fetch) url if not matching if remotes_fetch[name] != fetch_url: if not oebakery.call('git config remote.%s.url %s'%(name, fetch_url), dir=path): logger.error("failed to set url %s for %s", name, fetch_url) ok = False # if push url is different url, change it if push_url: if not remotes_push.has_key(name) or remotes_push[name] != push_url: if not oebakery.call( 'git config remote.%s.pushurl %s'%(name, push_url), dir=path): logger.error("failed to set pushurl %s for %s", push_url, name) ok = False # if push url is currently set, but shouldn't be, remove it else: if remotes_push.has_key(name) and remotes_push[name] != fetch_url: if not oebakery.call('git config --unset remote.%s.pushurl'%(name), dir=path): logger.error("failed to unset pushurl for %s", name) ok = False return ok
def manifest_url(): global _manifest_url if _manifest_url is None: _manifest_url = oebakery.call('git config --get remote.origin.url', quiet=True).strip() return _manifest_url
def update_submodule(path, fetch_url, params): push_url = params.get("push", None) ok = True if (os.path.exists(path) and not oebakery.call("git submodule sync -- %s"%(path))): logger.error("Failed to synchronize git submodule") status = git_submodule_status(path) if status and status[0] == "-": cmd = "git submodule update --init --recursive" if not oebakery.call("%s %s"%(cmd, path)): logger.error("Failed to add submodule: %s", path) return False elif status is None: cmd = "git submodule add -f" if "branch" in params: branch = params["branch"] if branch != "master": cmd += " -b %s"%(params["branch"]) if not oebakery.call("%s -- %s %s"%(cmd, fetch_url, path)): logger.error("Failed to add submodule: %s", path) return False if not oebakery.call( "git submodule update --init --recursive %s"%(path)): logger.error("Failed to initialize submodule: %s", path) return False # set push_default to 'tracking' if unset push_default = oebakery.call('git config --get push.default', dir=path, quiet=True) if (push_default == None): oebakery.call('git config push.default tracking', dir=path) # update origin fetch url if necessary current_url = oebakery.call('git config --get remote.origin.url', dir=path, quiet=True) if current_url: current_url = current_url.strip() if fetch_url != current_url: if fetch_url.startswith('./'): fetch_url_abs = os.path.join(manifest_url(), fetch_url[2:]) elif fetch_url.startswith('../'): fetch_url_abs = os.path.join( os.path.dirname(manifest_url()), fetch_url[3:]) else: fetch_url_abs = fetch_url if (fetch_url_abs != current_url and not oebakery.call('git config remote.origin.url %s'%(fetch_url), dir=path)): logger.error("Failed to set origin url %s for %s", fetch_url, path) ok = False # set push url as specified current_url = oebakery.call('git config --get remote.origin.pushurl', dir=path, quiet=True) if current_url: current_url = current_url.strip() if push_url and current_url != push_url: if not oebakery.call('git config remote.origin.pushurl %s'%(push_url), dir=path): logger.error("Failed to set origin push url %s for %s", push_url, path) ok = False if not oebakery.call('git remote update --prune origin', dir=path): logger.error("failed to update remote origin") ok = False # remove override of push url if not specified if not push_url and current_url: if not oebakery.call('git config --unset remote.origin.pushurl', dir=path): logger.error("Failed to unset origin push url for %s", path) ok = False # update remotes for (name, url) in params.get("remote", []): if not git_update_remote(name, url, path=path): logger.error("update of remote %s failed", name) ok = False # if "tag" in params: tag = params["tag"] if not oebakery.call("git checkout --detach refs/tags/%s"%(tag), dir=path): logger.error("Failed to checkout submodule %s tag %s", path, tag) return False elif "commit" in params: commit = params["commit"] if not oebakery.call("git checkout --detach %s"%(commit), dir=path): logger.error("Failed to checkout submodule %s commit %s", path, commit) return False elif "branch" in params: branch = params["branch"] branches = git_branch_status(path) if branch in branches: if not branches[branch]["current"]: if not oebakery.call("git checkout %s"%(branch), dir=path): logger.error("Failed to checkout submodule %s branch %s", path, branch) return False else: if not oebakery.call("git checkout -t -b %s %s"%( branch, "origin/%s"%(branch)), dir=path): logger.error("Failed to checkout%s branch %s", name, branch) return False current_remote = oebakery.call( "git config --get branch.%s.remote"%(branch), dir=path, quiet=True) current_merge = oebakery.call( "git config --get branch.%s.merge"%(branch), dir=path, quiet=True) if (current_remote is None or current_merge is None or current_remote.strip() != "origin" or current_merge.strip() != "refs/heads/%s"%(branch)): if not oebakery.call( "git branch --set-upstream %s origin/%s"%(branch, branch), dir=path): ok = False else: if not oebakery.call( "git submodule update --init --recursive %s"%(path)): logger.error("Failed to initialize submodule: %s", path) ok = False return ok