def _delete_cache(args, p4, metrics): """Delete all of the Git Fusion cached objects.""" if not args.no_obliterate: print_verbose(args, _('Obliterating object cache...')) r = p4.run('obliterate', '-y', '//{}/objects/...'.format(p4gf_const.P4GF_DEPOT)) results = p4gf_util.first_dict_with_key(r, 'revisionRecDeleted') if results: metrics.files += int(results['revisionRecDeleted'])
def create_using_change(p4, change): """p4 change -o nnn.""" result = p4.run('change', '-o', str(change)) cl = P4Changelist() vardict = p4gf_util.first_dict_with_key(result, 'Change') cl.change = int(vardict["Change"]) cl.description = vardict["Description"] cl.user = vardict["User"] cl.time = vardict["Date"] # string "2012/01/31 23:59:59" return cl
def create_using_change(p4, change): '''p4 change -o nnn''' result = p4.run('change', '-o', str(change)) cl = P4Changelist() vardict = p4gf_util.first_dict_with_key(result, 'Change') cl.change = int(vardict["Change"]) cl.description = vardict["Description"] cl.user = vardict["User"] cl.time = vardict["Date"] # string "2012/01/31 23:59:59" return cl
def maybe_create_lfs_attrs(ctx, changelist, p4file_list, branch): """Create the initial .gitattributes file for an LFS-enabled repo. Does nothing if the git-lfs-initial-track configurable is not set. :param ctx: Git Fusion context. :param changelist: the P4Changelist. :param p4file_list: list of P4File. :param branch: the Branch to contain this file. :return: modified p4file_list """ # Check if we have an initial-tracking setting or not. initial_tracking = generate_initial_lfs_attrs(ctx) if not initial_tracking: return p4file_list # Check if a .gitattributes file already exists or not. with ctx.switched_to_branch(branch): depot_path = ctx.gwt_to_depot_path(p4gf_const.GITATTRIBUTES) if not depot_path: return p4file_list for p4file in p4file_list: if p4file.depot_path == depot_path: # A .gitattributes already exists, nothing to do. return p4file_list # If a .gitattributes file ever existed in Perforce but was deleted by # the time we got to this changelist, honor that deletion. Do not insert. r = ctx.p4run('files', "{}@{}".format(depot_path, changelist.change)) if p4gf_util.first_dict_with_key(r, "depotFile"): return p4file_list # "Print" the attributes file into the repository. sha1 = add_attributes_to_repo(initial_tracking, ctx.repo) if sha1 is None: return p4file_list # Save the SHA1 in the gitmirror list of pending blobs to cache. ctx.mirror.add_blob(sha1) # Construct a P4File and add to the list of files for this change. vardict = { 'depotFile': depot_path, 'action': 'add', 'rev': 1, 'type': 'text', 'change': changelist.change } p4file = P4File.create_from_print(vardict) p4file.sha1 = sha1 p4file_list.append(p4file) return p4file_list
def _complete_changelist(self): """Verify that the selected changelist is a 'complete'.""" result = self.ctx.p4run('describe', '-s', self.change_num) vardict = p4gf_util.first_dict_with_key(result, 'change') if not vardict or 'desc' not in vardict: LOG.warning("change %s does not exist", self.change_num) return False di = p4gf_desc_info.DescInfo.from_text(vardict['desc']) if not di or p4gf_const.P4GF_DESC_KEY_PUSH_STATE not in di: return True return di[p4gf_const.P4GF_DESC_KEY_PUSH_STATE] == 'complete'
def create_default_perm(p4, perm=DEFAULT_PERM): """Create the 'stick all users into this pull/push permission group' default counter. If counter already exists with non-zero value, leave it unchanged. """ counter = p4gf_util.first_dict_with_key( p4.run('counter', '-u', p4gf_const.P4GF_COUNTER_PERMISSION_GROUP_DEFAULT), 'value') if counter != None and counter != 0: # Somebody already set it. return p4.run('counter', '-u', p4gf_const.P4GF_COUNTER_PERMISSION_GROUP_DEFAULT, perm)
def copy_submodule(ctx, repo_name, subtxt, local_path, change_num, user_3tuple): """Copy from Perforce to Git the submodule changes. Arguments: ctx -- parent repo context. repo_name -- name of submodule repo. subtxt -- context for submodule repo. local_path -- path within parent repo where submodule will go. user_3tuple -- (p4user, email, fullname) for Git Fusion user Returns the new SHA1 of the parent repo and an error string, or None if successful. """ cwd = os.getcwd() if subtxt.view_repo is None: subtxt.get_view_repo() os.chdir(subtxt.view_dirs.GIT_WORK_TREE) LOG.debug('copy_submodule() copying changes for {}'.format(repo_name)) p4gf_copy_p2g.copy_p2g_ctx(subtxt) # if available, use the requested change to get the corresponding SHA1 of the submodule commit_ot = None changes = subtxt.p4run( ['changes', '-m1', subtxt.client_view_path(change_num)]) if changes: real_dict = p4gf_util.first_dict_with_key(changes, 'change') if real_dict: real_change = real_dict['change'] commit_ot = p4gf_object_type.ObjectType.commit_for_change( subtxt, real_change, None) if commit_ot: sub_sha1 = commit_ot.sha1 LOG.debug2('copy_submodule() using commit {}'.format(sub_sha1)) else: # otherwise use the latest commit sub_sha1 = subtxt.view_repo.head.hex LOG.debug2('copy_submodule() using HEAD: {}'.format(sub_sha1)) os.chdir(cwd) url = _submodule_url(subtxt) if local_path.endswith('...'): local_path = local_path[:-3] local_path = local_path.rstrip('/') LOG.debug('adding submodule {} to {} as {}'.format(local_path, repo_name, user_3tuple[0])) p4gf_git.add_submodule(ctx.view_repo, repo_name, local_path, sub_sha1, url, user_3tuple)
def can_cleanup_change(p4, change): '''Determine whether the Reviews may be cleaned from a non-longer pending changelist''' try: int(change) except ValueError: return False result = p4.run('describe', '-s', str(change)) vardict = p4gf_util.first_dict_with_key(result, 'change') if not vardict: LOG.debug("can_cleanup_change: change {0} does not exist : return True".format(change)) return True LOG.debug("can_cleanup_change describe on {0}: status={1} shelved={2} depotFile={3}".format( change, vardict['status'], 'shelved' in vardict, 'depotFile' in vardict)) if 'code' in vardict and vardict['code'] == 'error' and 'data' in vardict: if re.search('no such changelist', vardict['data']): return True else: raise RuntimeError(_("Git Fusion: error in describe for change '{0}': '{1}'") .format(change, vardict)) submitted = False pending = False no_files = True shelved = 'shelved' in vardict if 'status' in vardict: pending = vardict['status'] == 'pending' submitted = vardict['status'] == 'submitted' if not shelved and pending: if 'depotFile' in vardict: no_files = False else: no_files = len(p4_files_at_change(p4, change)) == 0 if pending and shelved: return False if pending and no_files: return True if submitted: return True return False
def _calc_repair(ctx, ot): """ Return repair tuple for a single commit/changelist, or None if no repair needed. """ LOG.debug('_calc_repair() {}'.format(ot)) fmt = '{sha1:7.7} @{change_num:<5} {msg}' describe = p4gf_util.first_dict_with_key( ctx.p4run('describe', ot.change_num), 'desc') if not describe: LOG.warning("Unable to find changelist {change_num}" " for Git commit {sha1:7.7}. Skipping.".format( sha1=ot.sha1, change_num=ot.change_num)) return old_desc = describe['desc'] di = DescInfo.from_text(old_desc) if not di: # Changelists that originate in Perforce neither need # nor get Git Fusion DescInfo blocks. LOG.info( fmt.format(sha1=ot.sha1, change_num=ot.change_num, msg="Skipping: no desc info")) return copy.copy(di) _repair_parents(ot, di) new_desc = di.to_text() if new_desc.strip() == old_desc.strip(): LOG.info( fmt.format(sha1=ot.sha1, change_num=ot.change_num, msg="Skipping: already correct, no repair required")) return None # else: # LOG.debug("OLD @{}:\n{}".format(ot.change_num, old_desc)) # LOG.debug("NEW @{}:\n{}".format(ot.change_num, new_desc)) LOG.info( fmt.format(sha1=ot.sha1, change_num=ot.change_num, msg="Repair needed")) return Repair(change_num=int(ot.change_num), old_desc=old_desc, new_desc=new_desc)
def create_using_describe(p4, change, depot_root): """create a P4Changelist by running p4 describe""" result = p4.run("describe", "-s", str(change)) cl = P4Changelist() vardict = p4gf_util.first_dict_with_key(result, "change") cl.change = vardict["change"] cl.description = vardict["desc"] cl.user = vardict["user"] cl.time = vardict["time"] for i in range(len(vardict["depotFile"])): p4file = P4File.create_from_describe(vardict, i) # filter out files not under our root right now if not p4file.depot_path.startswith(depot_root): continue cl.files.append(p4file) return cl
def create_using_describe(p4, change, depot_root): """create a P4Changelist by running p4 describe""" result = p4.run("describe", "-s", str(change)) cl = P4Changelist() vardict = p4gf_util.first_dict_with_key(result, 'change') cl.change = vardict["change"] cl.description = vardict["desc"] cl.user = vardict["user"] cl.time = vardict["time"] for i in range(len(vardict["depotFile"])): p4file = P4File.create_from_describe(vardict, i) # filter out files not under our root right now if not p4file.depot_path.startswith(depot_root): continue cl.files.append(p4file) return cl
def copy_submodule(ctx, repo_name, subtxt, local_path, change_num, user_3tuple): """Copy from Perforce to Git the submodule changes. Arguments: ctx -- parent repo context. repo_name -- name of submodule repo. subtxt -- context for submodule repo. local_path -- path within parent repo where submodule will go. user_3tuple -- (p4user, email, fullname) for Git Fusion user Returns the new SHA1 of the parent repo and an error string, or None if successful. """ cwd = os.getcwd() if subtxt.view_repo is None: subtxt.get_view_repo() os.chdir(subtxt.view_dirs.GIT_WORK_TREE) LOG.debug('copy_submodule() copying changes for {}'.format(repo_name)) p4gf_copy_p2g.copy_p2g_ctx(subtxt) # if available, use the requested change to get the corresponding SHA1 of the submodule commit_ot = None changes = subtxt.p4run(['changes', '-m1', subtxt.client_view_path(change_num)]) if changes: real_dict = p4gf_util.first_dict_with_key(changes, 'change') if real_dict: real_change = real_dict['change'] commit_ot = p4gf_object_type.ObjectType.commit_for_change(subtxt, real_change, None) if commit_ot: sub_sha1 = commit_ot.sha1 LOG.debug2('copy_submodule() using commit {}'.format(sub_sha1)) else: # otherwise use the latest commit sub_sha1 = subtxt.view_repo.head.hex LOG.debug2('copy_submodule() using HEAD: {}'.format(sub_sha1)) os.chdir(cwd) url = _submodule_url(subtxt) if local_path.endswith('...'): local_path = local_path[:-3] local_path = local_path.rstrip('/') LOG.debug('adding submodule {} to {} as {}'.format(local_path, repo_name, user_3tuple[0])) p4gf_git.add_submodule(ctx.view_repo, repo_name, local_path, sub_sha1, url, user_3tuple)
def _update_changelist_description(ctx, change_num, description): """Set on echangelist's description.""" fmt = '@{change_num:<5} {msg}' change = p4gf_util.first_dict_with_key( ctx.p4run('change', '-o', str(change_num)), 'Description') old_desc = change['Description'] if not old_desc: LOG.warning( fmt.format(change_num=change_num, msg="Skipping: cannot find changelist.")) return LOG.debug("_update_changelist_description() @{cn}".format(cn=change_num)) if old_desc.strip() == description.strip(): LOG.info(fmt.format(change_num=change_num, msg="Skipping. No change.")) return LOG.info(fmt.format(change_num=change_num, msg="Updating")) change['Description'] = description ctx.p4.save_change(change, '-f')