diff --git a/c_src/git_nif.c b/c_src/git_nif.c
index 5cc949b..2af4e43 100644
--- a/c_src/git_nif.c
+++ b/c_src/git_nif.c
@@ -109,6 +109,10 @@ static ERL_NIF_TERM create_nif (ErlNifEnv *env, int argc,
res = enif_make_atom(env, "repo_dir_missing");
goto error;
}
+ if (strstr(repo_dir, "..")) {
+ res = enif_make_atom(env, "repo_dir");
+ goto error;
+ }
if (git_repository_init(&r, repo_dir, 1)) {
res = enif_make_atom(env, "git_repository_init");
goto error;
@@ -125,6 +129,110 @@ static ERL_NIF_TERM create_nif (ErlNifEnv *env, int argc,
return res;
}
+static ERL_NIF_TERM diff_nif (ErlNifEnv *env, int argc,
+ const ERL_NIF_TERM argv[])
+{
+ git_buf buf = {NULL, 0, 0};
+ git_commit *commit[2] = {NULL, NULL};
+ git_diff *diff = NULL;
+ char *from = NULL;
+ git_object *obj = NULL;
+ ERL_NIF_TERM ok;
+ git_patch *patch = NULL;
+ git_repository *r = NULL;
+ char *repo_dir = NULL;
+ ERL_NIF_TERM res;
+ char *to = NULL;
+ git_tree *tree[2] = {NULL, NULL};
+ if (argc != 3 || !argv || !argv[0] || !argv[1] ||
+ !argv[2]) {
+ res = enif_make_atom(env, "badarg");
+ goto error;
+ }
+ repo_dir = enif_term_to_string(env, argv[0]);
+ if (!repo_dir || !repo_dir[0]) {
+ res = enif_make_atom(env, "repo_dir_missing");
+ goto error;
+ }
+ if (strstr(repo_dir, "..")) {
+ res = enif_make_atom(env, "repo_dir");
+ goto error;
+ }
+ from = enif_term_to_string(env, argv[1]);
+ if (!from || !from[0]) {
+ res = enif_make_atom(env, "from_missing");
+ goto error;
+ }
+ to = enif_term_to_string(env, argv[2]);
+ if (!to || !to[0]) {
+ res = enif_make_atom(env, "to_missing");
+ goto error;
+ }
+ if (git_repository_open_bare(&r, repo_dir)) {
+ res = enif_make_atom(env, "git_repository_open_bare");
+ goto error;
+ }
+ printf("from\n");
+ if (git_revparse_single(&obj, r, from)) {
+ res = enif_make_atom(env, "from__git_revparse_single");
+ goto error;
+ }
+ if (git_commit_lookup(commit, r, git_object_id(obj))) {
+ res = enif_make_atom(env, "from__git_commit_lookup");
+ goto error;
+ }
+ if (git_commit_tree(tree, commit[0])) {
+ res = enif_make_atom(env, "from__git_commit_tree");
+ goto error;
+ }
+ printf("to\n");
+ if (git_revparse_single(&obj, r, to)) {
+ res = enif_make_atom(env, "to__git_revparse_single");
+ goto error;
+ }
+ if (git_commit_lookup(commit + 1, r, git_object_id(obj))) {
+ res = enif_make_atom(env, "to__git_commit_lookup");
+ goto error;
+ }
+ if (git_commit_tree(tree + 1, commit[1])) {
+ res = enif_make_atom(env, "to__git_commit_tree");
+ goto error;
+ }
+ printf("diff\n");
+ if (git_diff_tree_to_tree(&diff, r, tree[0], tree[1], NULL)) {
+ res = enif_make_atom(env, "git_diff_tree_to_tree");
+ goto error;
+ }
+ printf("patch\n");
+ if (git_patch_from_diff(&patch, diff, 0)) {
+ res = enif_make_atom(env, "git_patch_from_diff");
+ goto error;
+ }
+ printf("buf\n");
+ if (git_patch_to_buf(&buf, patch)) {
+ res = enif_make_atom(env, "git_patch_to_buf");
+ goto error;
+ }
+ printf("res\n");
+ res = enif_string_to_term(env, buf.ptr);
+ ok = enif_make_atom(env, "ok");
+ res = enif_make_tuple2(env, ok, res);
+ goto ok;
+ error:
+ res = enif_make_tuple2(env, enif_make_atom(env, "error"), res);
+ enif_fprintf(stderr, "%T\n", res);
+ ok:
+ git_buf_dispose(&buf);
+ git_commit_free(commit[0]);
+ git_commit_free(commit[1]);
+ git_patch_free(patch);
+ git_repository_free(r);
+ free(repo_dir);
+ free(from);
+ free(to);
+ return res;
+}
+
static ERL_NIF_TERM enif_string_to_term (ErlNifEnv *env,
const char *str)
{
@@ -220,6 +328,10 @@ static ERL_NIF_TERM files_nif (ErlNifEnv *env, int argc,
res = enif_make_atom(env, "repo_dir_missing");
goto error;
}
+ if (strstr(repo_dir, "..")) {
+ res = enif_make_atom(env, "repo_dir");
+ goto error;
+ }
tree_name = enif_term_to_string(env, argv[1]);
if (!tree_name || !tree_name[0]) {
res = enif_make_atom(env, "tree_name_missing");
@@ -509,6 +621,10 @@ static ERL_NIF_TERM log_nif (ErlNifEnv *env, int argc,
res = enif_make_atom(env, "repo_dir_missing");
goto error;
}
+ if (strstr(repo_dir, "..")) {
+ res = enif_make_atom(env, "repo_dir");
+ goto error;
+ }
branch_name = enif_term_to_string(env, argv[1]);
if (!branch_name || !branch_name[0]) {
res = enif_make_atom(env, "branch_name_missing");
@@ -624,6 +740,10 @@ static ERL_NIF_TERM tags_nif (ErlNifEnv *env, int argc,
res = enif_make_atom(env, "repo_dir_missing");
goto error;
}
+ if (strstr(repo_dir, "..")) {
+ res = enif_make_atom(env, "repo_dir");
+ goto error;
+ }
if (git_repository_open_bare(&r, repo_dir)) {
res = enif_make_atom(env, "git_repository_open_bare");
goto error;
@@ -668,6 +788,7 @@ static ErlNifFunc funcs[] = {
{"branches_nif", 1, branches_nif, 0},
{"content_nif", 2, content_nif, 0},
{"create_nif", 1, create_nif, 0},
+ {"diff_nif", 3, diff_nif, 0},
{"files_nif", 3, files_nif, 0},
{"log_nif", 5, log_nif, 0},
{"tags_nif", 1, tags_nif, 0}
diff --git a/lib/kmxgit/git.ex b/lib/kmxgit/git.ex
index 2281239..24092c7 100644
--- a/lib/kmxgit/git.ex
+++ b/lib/kmxgit/git.ex
@@ -43,6 +43,15 @@ defmodule Kmxgit.Git do
exit(:nif_not_loaded)
end
+ def diff(repo, from, to) do
+ dir = git_dir(repo)
+ diff_nif(dir, from, to)
+ end
+
+ def diff_nif(_repo, _from, _to) do
+ exit(:nif_not_loaded)
+ end
+
def files(repo, tree, path, parent \\ ".") do
dir = git_dir(repo)
case files_nif(dir, tree, path) do
diff --git a/lib/kmxgit_web/controllers/repository_controller.ex b/lib/kmxgit_web/controllers/repository_controller.ex
index d277a03..85f359d 100644
--- a/lib/kmxgit_web/controllers/repository_controller.ex
+++ b/lib/kmxgit_web/controllers/repository_controller.ex
@@ -397,7 +397,7 @@ defmodule KmxgitWeb.RepositoryController do
|> git_put_log1(repo, tree, path)
|> git_put_commit(repo, conn, op, tree, path)
#IO.inspect(git)
- diff = case GitManager.diff(Repository.full_slug(repo), "#{git.log1.hash}~1", git.log1.hash) do
+ diff = case Git.diff(Repository.full_slug(repo), "#{git.log1.hash}~1", git.log1.hash) do
{:ok, diff} -> diff
_ -> nil
end
@@ -414,7 +414,7 @@ defmodule KmxgitWeb.RepositoryController do
|> render("commit.html")
end
defp show_op(conn, :diff, %{from: from, org: org, path: path, repo: repo, to: to}) do
- case GitManager.diff(Repository.full_slug(repo), from, to) do
+ case Git.diff(Repository.full_slug(repo), from, to) do
{:ok, diff} ->
#diff_html = Pygmentize.html(diff, "diff.patch")
diff_line_numbers = line_numbers(diff)
diff --git a/lib/kmxgit_web/templates/repository/commit.html.heex b/lib/kmxgit_web/templates/repository/commit.html.heex
index 0b97275..4911b6d 100644
--- a/lib/kmxgit_web/templates/repository/commit.html.heex
+++ b/lib/kmxgit_web/templates/repository/commit.html.heex
@@ -17,7 +17,7 @@
</h2>
<div>
<%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, email: @commit.author_email, size: 48, title: @commit.author, class: "commit-avatar") %>
- <%= @commit.date |> String.replace("T", " ") |> String.replace("+", " +") %>
+ <%= NaiveDateTime.add(~N[1970-01-01 00:00:00], @commit.date) %>
<p>
<%= @commit.message %>
</p>
@@ -27,7 +27,7 @@
<div class="content_text">
<div class="line_numbers">
<pre><%= for ln <- @diff_line_numbers do %><%= link ln, id: ln, to: "##{ln}" %>
- <% end %></pre>
+<% end %></pre>
</div>
<pre><code class="language-diff"><%= @diff %></code></pre>
</div>