Skip to content
Snippets Groups Projects
Commit a0bb9521 authored by Campbell Barton's avatar Campbell Barton
Browse files

split git log into own module

parent 8cc40bd4
No related branches found
No related tags found
No related merge requests found
...@@ -24,137 +24,8 @@ import os ...@@ -24,137 +24,8 @@ import os
import subprocess import subprocess
# ----------------------------------------------------------------------------- from git_log import GitCommit, GitCommitIter
# Generic git read-only classes for extracting info if 1 and __name__ == "__main__":
class GitCommit:
__slots__ = (
"sha1",
# to extract more info
"_git_dir",
# cached values
"_author",
"_date",
"_body",
"_files",
"_files_status",
)
def __init__(self, sha1, git_dir):
self.sha1 = sha1
self._git_dir = git_dir
self._author = \
self._date = \
self._body = \
self._files = \
self._files_status = \
None
def _log_format(self, format, args=()):
# sha1 = self.sha1.decode('ascii')
cmd = (
"git",
"--git-dir",
self._git_dir,
"log",
"-1", # only this rev
self.sha1,
"--format=" + format,
) + args
# print(" ".join(cmd))
p = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
)
return p.stdout.read()
@property
def author(self):
ret = self._author
if ret is None:
content = self._log_format("%an")[:-1]
ret = content.decode("utf8", errors="ignore")
self._author = ret
return ret
@property
def date(self):
ret = self._date
if ret is None:
import datetime
ret = datetime.datetime.fromtimestamp(int(self._log_format("%ct")))
self._date = ret
return ret
@property
def body(self):
ret = self._body
if ret is None:
content = self._log_format("%B")[:-1]
ret = content.decode("utf8", errors="ignore")
self._body = ret
return ret
@property
def files(self):
ret = self._files
if ret is None:
ret = [f for f in self._log_format("format:", args=("--name-only",)).split(b"\n") if f]
self._files = ret
return ret
@property
def files_status(self):
ret = self._files_status
if ret is None:
ret = [f.split(None, 1) for f in self._log_format("format:", args=("--name-status",)).split(b"\n") if f]
self._files_status = ret
return ret
class GitCommitIter:
__slots__ = (
"_path",
"_git_dir",
"_sha1_range",
"_process",
)
def __init__(self, path, sha1_range):
self._path = path
self._git_dir = os.path.join(path, ".git")
self._sha1_range = sha1_range
self._process = None
def __iter__(self):
cmd = (
"git",
"--git-dir",
self._git_dir,
"log",
self._sha1_range,
"--format=%H",
)
# print(" ".join(cmd))
self._process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
)
return self
def __next__(self):
sha1 = self._process.stdout.readline()[:-1]
if sha1:
return GitCommit(sha1, self._git_dir)
else:
raise StopIteration
if 0 and __name__ == "__main__":
for c in GitCommitIter("/src/blender", "HEAD~10..HEAD"): for c in GitCommitIter("/src/blender", "HEAD~10..HEAD"):
print(c.sha1, c.author, c.date) print(c.sha1, c.author, c.date)
print(c.body) print(c.body)
......
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# Simple module for inspecting git commits
import os
import subprocess
class GitCommit:
__slots__ = (
"sha1",
# to extract more info
"_git_dir",
# cached values
"_author",
"_date",
"_body",
"_files",
"_files_status",
)
def __init__(self, sha1, git_dir):
self.sha1 = sha1
self._git_dir = git_dir
self._author = \
self._date = \
self._body = \
self._files = \
self._files_status = \
None
def _log_format(self, format, args=()):
# sha1 = self.sha1.decode('ascii')
cmd = (
"git",
"--git-dir",
self._git_dir,
"log",
"-1", # only this rev
self.sha1,
"--format=" + format,
) + args
# print(" ".join(cmd))
p = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
)
return p.stdout.read()
@property
def author(self):
ret = self._author
if ret is None:
content = self._log_format("%an")[:-1]
ret = content.decode("utf8", errors="ignore")
self._author = ret
return ret
@property
def date(self):
ret = self._date
if ret is None:
import datetime
ret = datetime.datetime.fromtimestamp(int(self._log_format("%ct")))
self._date = ret
return ret
@property
def body(self):
ret = self._body
if ret is None:
content = self._log_format("%B")[:-1]
ret = content.decode("utf8", errors="ignore")
self._body = ret
return ret
@property
def files(self):
ret = self._files
if ret is None:
ret = [f for f in self._log_format("format:", args=("--name-only",)).split(b"\n") if f]
self._files = ret
return ret
@property
def files_status(self):
ret = self._files_status
if ret is None:
ret = [f.split(None, 1) for f in self._log_format("format:", args=("--name-status",)).split(b"\n") if f]
self._files_status = ret
return ret
class GitCommitIter:
__slots__ = (
"_path",
"_git_dir",
"_sha1_range",
"_process",
)
def __init__(self, path, sha1_range):
self._path = path
self._git_dir = os.path.join(path, ".git")
self._sha1_range = sha1_range
self._process = None
def __iter__(self):
cmd = (
"git",
"--git-dir",
self._git_dir,
"log",
self._sha1_range,
"--format=%H",
)
# print(" ".join(cmd))
self._process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
)
return self
def __next__(self):
sha1 = self._process.stdout.readline()[:-1]
if sha1:
return GitCommit(sha1, self._git_dir)
else:
raise StopIteration
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment