Thursday, July 13, 2017

A Poor Use of GitPython

I'm working on a project that uses Git. It's written in Python. The initial implementation uses GitPython. GitPython provides abstractions for using Python with Git repositories.

My project uses git-log. I chose a layered approach using this function as a single point of access to the Git repository.

This function is the focal point for access to the git repository.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
def cmd(path, *args, **kwargs):
    """
    Generate a git log command using the the provided arguments. Empty git log
    lines are stripped by this function.

    Params:
        [in] path - location of repo
        [in] args - non-keyword arguments to provide to the git log command
        [in] kwargs - keyword arguments to provide to the git log command

    Returns: a list of lines returned from the git log command
    """
    repo = Repo(path)
    assert repo.bare == False
    result = list()
    for line in repo.git.log(*args, **kwargs).split('\n'):
        if len(line) == 0:
     continue
        result.append(line)
    return result

Layering separates the repository interface from the information in the repository. It isolates the GitPython interface from the rest of the project but introduces a different challenge.

Consider this function.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def commitLog(path, commitHash):
    """
    Return the log entry for a single commit hash.

    Params:
        [in] path - location of repo
        [in] commitHash - commit hash

    Returns: log entry for the specified commit hash
    """
    return ' '.join(cmd(path, '-n 1', commitHash)[3:])

My approach to layering moves the command-line options for git-log into the clients of cmd().

A better approach might have used GitPython's object model. Unfortunately the learning curve requires knowledge of git internals. Something I wanted to avoid in the interest of time. In my haste I didn't take advantage of GitPython's power.

The next revision of this project needs to revisit GitPython's object model to help traverse my repository. It will be interesting to see if this model supports obtaining information  provided by git log -n 1 and other porcelain options easily.

No comments:

Post a Comment