diff --git a/pelican/generators.py b/pelican/generators.py index 75b61df2..026d4207 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -23,7 +23,9 @@ from pelican.contents import ( Article, Page, Category, Static, is_valid_content ) from pelican.readers import read_file -from pelican.utils import copy, process_translations, mkdir_p, DateFormatter +from pelican.utils import ( + copy, process_translations, mkdir_p, DateFormatter, git_mtime +) from pelican import signals import pelican.utils @@ -407,6 +409,10 @@ class ArticlesGenerator(Generator): if self.settings['DEFAULT_DATE'] == 'fs': metadata['date'] = datetime.datetime.fromtimestamp( os.stat(f).st_ctime) + elif self.settings['DEFAULT_DATE'] == 'git-last-modified': + metadata['date'] = git_mtime(f, True) + elif self.settings['DEFAULT_DATE'] == 'git-creation': + metadata['date'] = git_mtime(f, False) else: metadata['date'] = datetime.datetime( *self.settings['DEFAULT_DATE']) diff --git a/pelican/utils.py b/pelican/utils.py index 4e7bdbd1..c335f5bd 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -11,6 +11,7 @@ import logging import errno import locale import fnmatch +import subprocess from collections import Hashable from functools import partial @@ -549,3 +550,30 @@ def split_all(path): break path = head return components + + +def git_mtime(filename, use_last_modification=True, git_binary="git"): + + """Determines the git modification time of a file and returns it as a + datetime.datetime object. + + If use_last_modification is True, then the date and time of the last + modification will be returned. Otherwise the date and time of the first + commit containing the file will be returned. + + The optional argument 'git_binary' can be used to specify the git binary to + use. + """ + + call = [git_binary, "log", "--pretty=format:%at ", filename] + repository= os.path.dirname(filename) + try: + output = subprocess.check_output(call, cwd=repository).decode('utf-8').splitlines() + except Exception as e: + print("ERROR: Could not get git time information for {0}: {1}".format(filename, str(e))) + return None + + dates = [ datetime.fromtimestamp(int(x)) for x in output ] + sorted_dates = sorted(dates) + + return sorted_dates[-1] if use_last_modification else sorted_dates[0]