From 6e751be2ff206bdc3b75d1f7387948d200ba0f00 Mon Sep 17 00:00:00 2001 From: Sup Yut Sum Date: Tue, 18 Nov 2014 21:24:19 +0800 Subject: [PATCH] Show diff stat using libgit2 Signed-off-by: Sup Yut Sum --- src/Git/Git.cpp | 29 ++++++++++++++++++++++++++--- src/Utils/SmartLibgit2Ref.h | 15 +++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/Git/Git.cpp b/src/Git/Git.cpp index ee296e4d0..4285fe676 100644 --- a/src/Git/Git.cpp +++ b/src/Git/Git.cpp @@ -2703,6 +2703,13 @@ CString CGit::GetUnifiedDiffCmd(const CTGitPath& path, const git_revnum_t& rev1, return cmd; } +static void UnifiedDiffStatToFile(const git_buf* text, void* payload) +{ + ATLASSERT(payload && text); + fwrite(text->ptr, 1, text->size, (FILE *)payload); + fwrite("\n", 1, 1, (FILE *)payload); +} + static int UnifiedDiffToFile(const git_diff_delta * /* delta */, const git_diff_hunk * /* hunk */, const git_diff_line * line, void *payload) { ATLASSERT(payload && line); @@ -2741,7 +2748,7 @@ static int resolve_to_tree(git_repository *repo, const char *identifier, git_tre } /* use libgit2 get unified diff */ -static int GetUnifiedDiffLibGit2(const CTGitPath& path, const git_revnum_t& revOld, const git_revnum_t& revNew, git_diff_line_cb callback, void *data, bool /* bMerge */) +static int GetUnifiedDiffLibGit2(const CTGitPath& path, const git_revnum_t& revOld, const git_revnum_t& revNew, std::function statCallback, git_diff_line_cb callback, void *data, bool /* bMerge */) { CStringA tree1 = CUnicodeUtils::GetMulti(revNew, CP_UTF8); CStringA tree2 = CUnicodeUtils::GetMulti(revOld, CP_UTF8); @@ -2813,6 +2820,14 @@ static int GetUnifiedDiffLibGit2(const CTGitPath& path, const git_revnum_t& revO return -1; } + CAutoDiffStats stats; + if (git_diff_get_stats(stats.GetPointer(), diff)) + return -1; + CAutoBuf statBuf; + if (git_diff_stats_to_buf(statBuf, stats, GIT_DIFF_STATS_FULL, 0)) + return -1; + statCallback(statBuf, data); + for (size_t i = 0; i < git_diff_num_deltas(diff); ++i) { CAutoPatch patch; @@ -2836,7 +2851,7 @@ int CGit::GetUnifiedDiff(const CTGitPath& path, const git_revnum_t& rev1, const _tfopen_s(&file, patchfile, _T("w")); if (file == nullptr) return -1; - int ret = GetUnifiedDiffLibGit2(path, rev1, rev2, UnifiedDiffToFile, file, bMerge); + int ret = GetUnifiedDiffLibGit2(path, rev1, rev2, UnifiedDiffStatToFile, UnifiedDiffToFile, file, bMerge); fclose(file); return ret; } @@ -2848,6 +2863,14 @@ int CGit::GetUnifiedDiff(const CTGitPath& path, const git_revnum_t& rev1, const } } +static void UnifiedDiffStatToStringA(const git_buf* text, void* payload) +{ + ATLASSERT(payload && text); + CStringA *str = (CStringA*) payload; + str->Append(text->ptr, (int)text->size); + str->AppendChar('\n'); +} + static int UnifiedDiffToStringA(const git_diff_delta * /*delta*/, const git_diff_hunk * /*hunk*/, const git_diff_line *line, void *payload) { ATLASSERT(payload && line); @@ -2861,7 +2884,7 @@ static int UnifiedDiffToStringA(const git_diff_delta * /*delta*/, const git_diff int CGit::GetUnifiedDiff(const CTGitPath& path, const git_revnum_t& rev1, const git_revnum_t& rev2, CStringA * buffer, bool bMerge, bool bCombine, int diffContext) { if (UsingLibGit2(GIT_CMD_DIFF)) - return GetUnifiedDiffLibGit2(path, rev1, rev2, UnifiedDiffToStringA, buffer, bMerge); + return GetUnifiedDiffLibGit2(path, rev1, rev2, UnifiedDiffStatToStringA, UnifiedDiffToStringA, buffer, bMerge); else { CString cmd; diff --git a/src/Utils/SmartLibgit2Ref.h b/src/Utils/SmartLibgit2Ref.h index daf6a359e..90c2408cc 100644 --- a/src/Utils/SmartLibgit2Ref.h +++ b/src/Utils/SmartLibgit2Ref.h @@ -353,6 +353,21 @@ protected: } }; +class CAutoDiffStats : public CSmartLibgit2Ref +{ +public: + ~CAutoDiffStats() + { + CleanUp(); + } + +protected: + virtual void FreeRef() + { + git_diff_stats_free(m_Ref); + } +}; + class CAutoIndex : public CSmartLibgit2Ref { public: -- 2.11.4.GIT