1b58ed89057d1acec3c187022ad92e6d51e49bd8
[update-copyright.git] / update_copyright / vcs / git.py
1 # Copyright (C) 2012 W. Trevor King
2 #
3 # This file is part of update-copyright.
4 #
5 # update-copyright is free software: you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License as
7 # published by the Free Software Foundation, either version 3 of the
8 # License, or (at your option) any later version.
9 #
10 # update-copyright is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with update-copyright.  If not, see
17 # <http://www.gnu.org/licenses/>.
18
19 from . import VCSBackend as _VCSBackend
20 from . import utils as _utils
21
22
23 class GitBackend (_VCSBackend):
24     name = 'Git'
25
26     def __init__(self, **kwargs):
27         super(GitBackend, self).__init__(**kwargs)
28         self._version = self._git_cmd('--version').split(' ')[-1]
29         if self._version.startswith('1.5.'):
30             # Author name <author email>
31             self._author_format = '--pretty=format:%an <%ae>'
32             self._year_format = ['--pretty=format:%ai']  # Author date
33             # YYYY-MM-DD HH:MM:SS Z
34             # Earlier versions of Git don't seem to recognize --date=short
35         else:
36             self._author_format = '--pretty=format:%aN <%aE>'
37             self._year_format = ['--pretty=format:%ad',  # Author date
38                                  '--date=short']         # YYYY-MM-DD
39
40     def _git_cmd(self, *args):
41         status,stdout,stderr = _utils.invoke(
42             ['git'] + list(args), cwd=self._root, unicode_output=True)
43         return stdout.rstrip('\n')
44
45     def _dates(self, filename=None):
46         args = ['log'] + self._year_format
47         if filename is not None:
48             args.extend(['--follow'] + [filename])
49         output = self._git_cmd(*args)
50         if self._version.startswith('1.5.'):
51             output = '\n'.join([x.split()[0] for x in output.splitlines()])
52         return output.splitlines()
53
54     def _years(self, filename=None):
55         dates = self._dates(filename=filename)
56         years = set(int(date.split('-', 1)[0]) for date in dates)
57         return years
58
59     def _authors(self, filename=None):
60         args = ['log', self._author_format]
61         if filename is not None:
62             args.extend(['--follow', filename])
63         output = self._git_cmd(*args)
64         authors = set(output.splitlines())
65         return authors
66
67     def is_versioned(self, filename):
68         output = self._git_cmd('log', '--follow', filename)
69         if len(output) == 0:
70             return False
71         return True