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'])
Example #2
0
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'])
Example #3
0
 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'
Example #7
0
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 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)
Example #10
0
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
Example #13
0
    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
Example #14
0
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')