Completed
Push — develop ( 81dc84...93812c )
by Jace
01:59
created

gdm.update()   A

Complexity

Conditions 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3
Metric Value
dl 0
loc 15
ccs 10
cts 10
cp 1
rs 9.4286
cc 3
crap 3
1
"""Utilities to call Git commands."""
2
3 1
import os
4 1
import logging
5
6 1
from . import common
7 1
from .shell import call
8
9
10 1
log = logging.getLogger(__name__)
11
12
13 1
def git(*args, **kwargs):
0 ignored issues
show
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
14 1
    return call('git', *args, **kwargs)
15
16
17 1
def clone(repo, path, *, cache=None):
18
    """Clone a new Git repository."""
19 1
    cache = cache or os.path.expanduser("~/.gitcache")
20
21 1
    name = repo.split('/')[-1]
22 1
    if name.endswith(".git"):
23 1
        name = name[:-4]
24
25 1
    reference = os.path.join(cache, name + ".reference")
26 1
    if not os.path.isdir(reference):
27 1
        git('clone', '--mirror', repo, reference)
28
29 1
    git('clone', '--reference', reference, repo, path)
30
31
32 1
def fetch(repo, rev=None):
33
    """Fetch the latest changes from the remote repository."""
34 1
    git('remote', 'rm', 'origin', _show=False, _ignore=True)
35 1
    git('remote', 'add', 'origin', repo)
36 1
    args = ['fetch', '--tags', '--force', '--prune', 'origin']
37 1
    if rev:
38 1
        if len(rev) == 40:
39 1
            pass  # fetch only works with a SHA if already present locally
40 1
        elif '@' in rev:
41 1
            pass  # fetch doesn't work with rev-parse
42
        else:
43 1
            args.append(rev)
44 1
    git(*args)
0 ignored issues
show
Coding Style introduced by
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
45
46
47 1
def changes(include_untracked=False, display_status=True, _show=False):
48
    """Determine if there are changes in the working tree."""
49 1
    status = False
50
51 1
    try:
52
        # refresh changes
53 1
        git('update-index', '-q', '--refresh', _show=False)
54
55
        # check for uncommitted changes
56 1
        git('diff-index', '--quiet', 'HEAD', _show=_show)
57
58
        # check for untracked files
59 1
        output = git('ls-files', '--others', '--exclude-standard',
60
                     _show=_show, _capture=True)
61
62 1
    except common.CallException:
63 1
        status = True
64
65
    else:
66 1
        status = bool(output.splitlines()) and include_untracked
67
68 1
    if status and display_status:
69 1
        for line in git('status', _show=True, _capture=True).splitlines():
70 1
            common.show(line)
71
72 1
    return status
73
74
75 1
def update(rev, *, clean=True, fetch=False):  # pylint: disable=redefined-outer-name
76
    """Update the working tree to the specified revision."""
77 1
    hide = {'_show': False, '_ignore': True}
78
79 1
    git('stash', **hide)
0 ignored issues
show
Coding Style introduced by
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
80 1
    if clean:
81 1
        git('clean', '--force', '-d', '-x', _show=False)
82
83 1
    rev = _get_sha_from_rev(rev)
84 1
    git('checkout', '--force', rev)
85 1
    git('branch', '--set-upstream-to', 'origin/' + rev, **hide)
0 ignored issues
show
Coding Style introduced by
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
86
87 1
    if fetch:
88
        # if `rev` was a branch it might be tracking something older
89 1
        git('pull', '--ff-only', '--no-rebase', **hide)
0 ignored issues
show
Coding Style introduced by
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
90
91
92 1
def get_url():
93
    """Get the current repository's URL."""
94 1
    return git('config', '--get', 'remote.origin.url',
95
               _show=False, _capture=True)
96
97
98 1
def get_hash(_show=False):
99
    """Get the current working tree's hash."""
100 1
    return git('rev-parse', 'HEAD', _show=_show, _capture=True)
101
102
103 1
def get_tag():
104
    """Get the current working tree's tag (if on a tag)."""
105 1
    return git('describe', '--tags', '--exact-match',
106
               _show=False, _ignore=True, _capture=True)
107
108
109 1
def get_branch():
110
    """Get the current working tree's branch."""
111 1
    return git('rev-parse', '--abbrev-ref', 'HEAD',
112
               _show=False, _capture=True)
113
114
115 1
def _get_sha_from_rev(rev):
116
    """Get a rev-parse string's hash."""
117 1
    if '@{' in rev:  # TODO: use regex for this
118 1
        parts = rev.split('@')
119 1
        branch = parts[0]
120 1
        date = parts[1].strip("{}")
121 1
        git('checkout', '--force', branch, _show=False)
122 1
        rev = git('rev-list', '-n', '1', '--before={!r}'.format(date),
123
                  branch, _show=False, _capture=True)
124
    return rev
125