From 0b527f29faa2f2e2c09ee32bcdde0b605c57dc40 Mon Sep 17 00:00:00 2001 From: Luka Hietala Date: Tue, 18 Nov 2025 21:53:27 +0200 Subject: [PATCH] view blobs --- app.py | 7 +++++++ git/blob.py | 39 +++++++++++++++++++++++++++++++++++++++ git/tree.py | 1 + templates/blob.html | 11 +++++++++++ templates/commit.html | 2 +- templates/tree.html | 2 +- 6 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 git/blob.py create mode 100644 templates/blob.html diff --git a/app.py b/app.py index eac0345..290e17b 100644 --- a/app.py +++ b/app.py @@ -4,6 +4,7 @@ from git.repo import get_bare_repos from git.commit import get_commits, get_commit from git.ref import get_refs from git.tree import get_tree_items +from git.blob import get_blob app = Flask(__name__) @@ -43,5 +44,11 @@ def repo_tree_path(repo_name, path): tree_items = get_tree_items(f"{repo_path}/{repo_name}", ref, path) return render_template("tree.html", repo_name=repo_name, ref=ref, path=path, tree_items=tree_items) +@app.route("//blob/") +def repo_blob_path(repo_name, path): + ref = request.args.get('ref', 'HEAD') + blob = get_blob(f"{repo_path}/{repo_name}", ref, path) + return render_template("blob.html", repo_name=repo_name, ref=ref, path=path, blob=blob) + if __name__ == "__main__": app.run(debug=True) \ No newline at end of file diff --git a/git/blob.py b/git/blob.py new file mode 100644 index 0000000..96496a6 --- /dev/null +++ b/git/blob.py @@ -0,0 +1,39 @@ +import pygit2 as git + +# retrieves a blob content for given ref and path +def get_blob(repo_path, ref="HEAD", blob_path=""): + repo = git.Repository(repo_path) + obj = repo.revparse_single(ref) + if obj.type == git.GIT_OBJECT_COMMIT: + tree = obj.tree + elif obj.type == git.GIT_OBJECT_TREE: + tree = obj + else: + commit = obj.peel(git.GIT_OBJECT_COMMIT) + tree = commit.tree + + # traverse to the blob path + # TODO: improve the code, just quick and dirty + if blob_path: + parts = blob_path.rstrip('/').split('/') + for part in parts: + found = False + for entry in tree: + if entry.name == part: + if entry.type == git.GIT_OBJECT_BLOB: + blob = repo.get(entry.id) + return { + 'name': entry.name, + 'id': str(entry.id), + 'path': blob_path, + 'size': blob.size, + 'is_binary': blob.is_binary, + 'content': blob.data.decode('utf-8', errors='replace') + } + elif entry.type == git.GIT_OBJECT_TREE: + tree = repo.get(entry.id) + found = True + break + if not found: + return None # path not found + return None # blob not found diff --git a/git/tree.py b/git/tree.py index d17cc52..46f6522 100644 --- a/git/tree.py +++ b/git/tree.py @@ -35,6 +35,7 @@ def get_tree_items(repo_path, ref="HEAD", tree_path=""): item = { 'name': entry.name, 'type': 'tree' if entry.type == git.GIT_OBJECT_TREE else 'blob', + 'size': entry.size if entry.type == git.GIT_OBJECT_BLOB else None, 'id': str(entry.id), 'path': entry.name if not tree_path else f"{tree_path}/{entry.name}" } diff --git a/templates/blob.html b/templates/blob.html new file mode 100644 index 0000000..72352fc --- /dev/null +++ b/templates/blob.html @@ -0,0 +1,11 @@ +{% block content %} +

Blob: {{ blob.name }}

+

Blob hash: {{ blob.id }}

+

Size: {{ blob.size }} bytes

+

Content:

+{% if blob.is_binary %} +
Binary...
+{% else %} +
{{ blob.content }}
+{% endif %} +{% endblock %} \ No newline at end of file diff --git a/templates/commit.html b/templates/commit.html index 80c35d7..c95a0d8 100644 --- a/templates/commit.html +++ b/templates/commit.html @@ -4,7 +4,7 @@

Author: {{ commit.author.name }} <{{ commit.author.email }}>

Committer: {{ commit.committer.name }} <{{ commit.committer.email }}>

Date: {{ commit.date }}

-

Tree: {{ commit.tree_id }}

+

Tree: {{ commit.tree_id }}

View Tree

Diff Stats