Show diff stat in status bar

Include the number of lines added and removed for
new and modified files
This commit is contained in:
Kevin Sawicki
2012-12-27 10:41:02 -08:00
parent 747b2b6bad
commit 219aaca0f5
6 changed files with 108 additions and 4 deletions

View File

@@ -7,6 +7,7 @@ var $git = {};
native function getStatus(path);
native function isIgnored(path);
native function checkoutHead(path);
native function getDiffStats(path);
function GitRepository(path) {
var repo = getRepository(path);
@@ -20,5 +21,6 @@ var $git = {};
GitRepository.prototype.getStatus = getStatus;
GitRepository.prototype.isIgnored = isIgnored;
GitRepository.prototype.checkoutHead = checkoutHead;
GitRepository.prototype.getDiffStats = getDiffStats;
this.GitRepository = GitRepository;
})();

View File

@@ -105,6 +105,80 @@ public:
}
}
CefRefPtr<CefV8Value> GetDiffStats(const char *path) {
if (!exists) {
return CefV8Value::CreateNull();
}
char *copiedPath = (char *)malloc(sizeof(char) * (strlen(path) + 1));
strcpy(copiedPath, path);
git_diff_options options;
memset(&options, 0, sizeof(options));
git_strarray paths;
paths.count = 1;
paths.strings = &copiedPath;
options.pathspec = paths;
options.context_lines = 1;
options.flags = GIT_DIFF_DISABLE_PATHSPEC_MATCH;
git_reference *head;
if (git_repository_head(&head, repo) != GIT_OK) {
return CefV8Value::CreateNull();
}
const git_oid* sha = git_reference_oid(head);
git_commit *commit;
int commitStatus = git_commit_lookup(&commit, repo, sha);
git_reference_free(head);
if (commitStatus != GIT_OK) {
return CefV8Value::CreateNull();
}
git_tree *tree;
int treeStatus = git_commit_tree(&tree, commit);
git_commit_free(commit);
if (treeStatus != GIT_OK) {
return CefV8Value::CreateNull();
}
git_diff_list *diffs;
int diffStatus = git_diff_workdir_to_tree(repo, &options, tree, &diffs);
if (diffStatus != GIT_OK) {
return CefV8Value::CreateNull();
}
git_diff_patch *patch;
int patchStatus = git_diff_get_patch(&patch, NULL, diffs, 0);
git_diff_list_free(diffs);
if (patchStatus != GIT_OK) {
return CefV8Value::CreateNull();
}
int added = 0;
int deleted = 0;
int hunks = git_diff_patch_num_hunks(patch);
for (int i = 0; i < hunks; i++) {
int lines = git_diff_patch_num_lines_in_hunk(patch, i);
for (int j = 0; j < lines; j++) {
char lineType[2];
lineType[1] = '\0';
if (git_diff_patch_get_line_in_hunk(lineType, NULL, NULL, NULL, NULL, patch, i, j) == GIT_OK) {
if (strcmp(lineType, "+") == 0) {
added++;
} else if(strcmp(lineType, "-") == 0) {
deleted++;
}
}
}
}
git_diff_patch_free(patch);
CefRefPtr<CefV8Value> result = CefV8Value::CreateObject(NULL);
result->SetValue("added", CefV8Value::CreateInt(added), V8_PROPERTY_ATTRIBUTE_NONE);
result->SetValue("deleted", CefV8Value::CreateInt(deleted), V8_PROPERTY_ATTRIBUTE_NONE);
return result;
}
IMPLEMENT_REFCOUNTING(GitRepository);
};
@@ -156,6 +230,12 @@ bool Git::Execute(const CefString& name,
return true;
}
if (name == "getDiffStats") {
GitRepository *userData = (GitRepository *)object->GetUserData().get();
retval = userData->GetDiffStats(arguments[0]->GetStringValue().ToString().c_str());
return true;
}
return false;
}

View File

@@ -63,3 +63,7 @@ class Git
checkoutHead: (path) ->
@repo.checkoutHead(@relativize(path))
getDiffStats: (path) ->
stats = @repo.getDiffStats(@relativize(path))
stats or {'added': 0, 'deleted': 0}

View File

@@ -166,3 +166,12 @@ describe "StatusBar", ->
fs.write(path, originalPathText)
$(window).trigger 'focus'
expect(statusBar.gitStatusIcon).not.toHaveClass('modified-status-icon')
it "displays the diff stat for modified files", ->
fs.write(path, "i've changed for the worse")
rootView.open(path)
expect(statusBar.gitStatusIcon).toHaveText('+1,-1')
it "displays the diff stat for new files", ->
rootView.open(newPath)
expect(statusBar.gitStatusIcon).toHaveText('+1')

View File

@@ -79,8 +79,18 @@ class StatusBar extends View
@gitStatusIcon.removeClass().addClass('git-status octicons')
if @buffer.getGit()?.isPathModified(path)
@gitStatusIcon.addClass('modified-status-icon')
else if @buffer.getGit()?.isPathNew(path)
stats = @buffer.getGit().getDiffStats(path)
if stats.added and stats.deleted
@gitStatusIcon.text("+#{stats.added},-#{stats.deleted}")
else if stats.added
@gitStatusIcon.text("+#{stats.added}")
else if stats.deleted
@gitStatusIcon.text("-#{stats.deleted}")
else
@gitStatusIcon.text('')
else if @buffer.getGit()?.isPathNew(path)
@gitStatusIcon.addClass('new-status-icon')
@gitStatusIcon.text("+#{@buffer.getLineCount()}")
updatePathText: ->
if path = @editor.getPath()

View File

@@ -17,7 +17,6 @@
}
.status-bar .branch-label {
padding-left: 5px;
vertical-align: baseline;
}
@@ -27,7 +26,7 @@
margin-top:-2px;
}
.status-bar .octicons {
.status-bar .octicons:before {
font-family: 'Octicons Regular';
font-size: 14px;
width: 14px;
@@ -36,6 +35,7 @@
-webkit-font-smoothing: antialiased;
display: inline-block;
vertical-align: middle;
margin-right: 5px;
}
.status-bar .branch-icon:before {
@@ -59,4 +59,3 @@
.status-bar .new-status-icon:before {
content: "\f26b";
}