#! /usr/bin/env python3.3
"""Functions for operating on a .gitattributes file."""
import p4gf_config
import p4gf_const
from p4gf_p4file import P4File
import p4gf_pygit2
import p4gf_util
def generate_initial_lfs_attrs(ctx):
"""Generate 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 branch: the Branch to contain this file.
:return: contents of .gitattributes file
"""
# Check if we have an initial-tracking setting or not.
initial_tracking = ctx.repo_config.get(p4gf_config.SECTION_PERFORCE_TO_GIT,
p4gf_config.KEY_GIT_LFS_INITIAL_TRACK)
if not initial_tracking:
return None
attr_form = '{0} filter=lfs diff=lfs merge=lfs -crlf'
attrs = []
for ext in initial_tracking.splitlines():
stripped = ext.strip()
if stripped:
attrs.append(attr_form.format(stripped))
if not attrs:
return None
return ('\n'.join(attrs) + '\n').encode('utf-8')
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 add_attributes_to_repo(initial_tracking, repo):
"""Generate a .gitattributes file for LFS and add to the repository.
:param initial_tracking: value for git-lfs-initial-track setting.
:param repo: pygit2.Repository instance.
:return: SHA1 of newly created blob.
"""
oid = repo.create_blob(initial_tracking)
return p4gf_pygit2.oid_to_sha1(oid)