mirror of
https://github.com/atom/atom.git
synced 2026-01-23 22:08:08 -05:00
Show diff stat in status bar
Include the number of lines added and removed for new and modified files
This commit is contained in:
@@ -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;
|
||||
})();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user