Skip to content

Commit 617e74e

Browse files
committed
Merge pull request #448 from nodegit/ol-status-with-delta
Status.byIndex and StatusEntry
2 parents f0b29f5 + 4947ecf commit 617e74e

File tree

9 files changed

+198
-9
lines changed

9 files changed

+198
-9
lines changed

generate/input/descriptor.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,7 +1553,7 @@
15531553
],
15541554
"functions": {
15551555
"git_status_byindex": {
1556-
"ignore": true
1556+
"isAsync": false
15571557
},
15581558
"git_status_foreach": {
15591559
"isAsync": true,
@@ -1575,7 +1575,7 @@
15751575
"status_list": {
15761576
"functions": {
15771577
"git_status_list_new": {
1578-
"isAsync": false,
1578+
"isAsync": true,
15791579
"args": {
15801580
"opts": {
15811581
"isOptional": true

generate/input/libgit2-supplement.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,25 @@
187187
]
188188
}
189189
],
190+
[
191+
"git_status_entry",
192+
{
193+
"fields": [
194+
{
195+
"type": "git_status_t",
196+
"name": "status"
197+
},
198+
{
199+
"type": "git_diff_delta *",
200+
"name": "head_to_index"
201+
},
202+
{
203+
"type": "git_diff_delta *",
204+
"name": "index_to_workdir"
205+
}
206+
]
207+
}
208+
],
190209
[
191210
"git_diff_perfdata",
192211
{

generate/templates/partials/fields.cc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,19 @@
77
{% if field | isFixedLengthString %}
88
char* {{ field.name }} = (char *)ObjectWrap::Unwrap<{{ cppClassName }}>(args.This())->GetValue()->{{ field.name }};
99
{% else %}
10-
{{ field.cType }} {% if not field.cppClassName|isV8Value %}*{% endif %}{{ field.name }} =
11-
{% if not field.cppClassName|isV8Value %}&{% endif %}ObjectWrap::Unwrap<{{ cppClassName }}>(args.This())->GetValue()->{{ field.name }};
10+
{{ field.cType }}
11+
{% if not field.cppClassName|isV8Value %}
12+
{% if not field.cType|isPointer %}
13+
*
14+
{% endif %}
15+
{% endif %}
16+
{{ field.name }} =
17+
{% if not field.cppClassName|isV8Value %}
18+
{% if not field.cType|isPointer %}
19+
&
20+
{% endif %}
21+
{% endif %}
22+
ObjectWrap::Unwrap<{{ cppClassName }}>(args.This())->GetValue()->{{ field.name }};
1223
{% endif %}
1324

1425
{% partial convertToV8 field %}

lib/repository.js

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ var Promise = require("nodegit-promise");
1010
var normalizeOptions = require("./util/normalize_options");
1111
var Status = require("./status");
1212
var StatusFile = require("./status_file");
13+
var StatusList = require("./status_list");
1314

1415
var TreeBuilder = NodeGit.Treebuilder;
1516
var Repository = NodeGit.Repository;
@@ -727,17 +728,17 @@ Repository.initExt = function(repo_path, opts) {
727728
* Get the status of a repo to it's working directory
728729
*
729730
* @param {obj} opts
730-
* @return {Object} Promise object.
731+
* @return {Array<StatusFile>}
731732
*/
732733
Repository.prototype.getStatus = function(opts) {
733734
var statuses = [];
734735
var statusCallback = function(path, status) {
735-
statuses.push(new StatusFile(path, status));
736+
statuses.push(new StatusFile({path: path, status: status}));
736737
};
737738

738739
if (!opts) {
739740
opts = {
740-
flags: Status.OPT.INCLUDE_UNTRACKED +
741+
flags: Status.OPT.INCLUDE_UNTRACKED |
741742
Status.OPT.RECURSE_UNTRACKED_DIRS
742743
};
743744
}
@@ -747,4 +748,34 @@ Repository.prototype.getStatus = function(opts) {
747748
});
748749
};
749750

751+
/**
752+
* Get extended statuses of a repo to it's working directory. Status entries
753+
* have `status`, `headToIndex` delta, and `indexToWorkdir` deltas
754+
*
755+
* @param {obj} opts
756+
* @return {Array<StatusEntry>}
757+
*/
758+
Repository.prototype.getStatusExt = function(opts) {
759+
var statuses = [];
760+
761+
if (!opts) {
762+
opts = {
763+
flags: Status.OPT.INCLUDE_UNTRACKED |
764+
Status.OPT.RECURSE_UNTRACKED_DIRS |
765+
Status.OPT.RENAMES_INDEX_TO_WORKDIR |
766+
Status.OPT.RENAMES_HEAD_TO_INDEX |
767+
Status.OPT.RENAMES_FROM_REWRITES
768+
};
769+
}
770+
771+
return StatusList.create(this, opts).then(function(list) {
772+
for (var i = 0; i < list.entrycount(); i++) {
773+
var entry = Status.byIndex(list, i);
774+
statuses.push(new StatusFile({entry: entry}));
775+
}
776+
777+
return statuses;
778+
});
779+
};
780+
750781
module.exports = Repository;

lib/status_file.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,19 @@ var NodeGit = require("../");
22

33
var Status = NodeGit.Status;
44

5-
var StatusFile = function(path, status) {
5+
var StatusFile = function(args) {
6+
var path = args.path;
7+
var status = args.status;
8+
var entry = args.entry;
9+
10+
if (entry) {
11+
status = entry.status();
12+
if (entry.indexToWorkdir()) {
13+
path = entry.indexToWorkdir().newFile().path();
14+
} else {
15+
path = entry.headToIndex().newFile().path();
16+
}
17+
}
618

719
var codes = Status.STATUS;
820

@@ -20,6 +32,7 @@ var StatusFile = function(path, status) {
2032

2133
var data = {
2234
path: path,
35+
entry: entry,
2336
statusBit: status,
2437
statuses: getStatus()
2538
};
@@ -31,6 +44,20 @@ var StatusFile = function(path, status) {
3144
statusBit: function() {
3245
return data.statusBit;
3346
},
47+
headToIndex: function() {
48+
if (data.entry) {
49+
return entry.headToIndex();
50+
} else {
51+
return undefined;
52+
}
53+
},
54+
indexToWorkdir: function() {
55+
if (data.entry) {
56+
return entry.indexToWorkdir();
57+
} else {
58+
return undefined;
59+
}
60+
},
3461
path: function() {
3562
return data.path;
3663
},

lib/status_list.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
var NodeGit = require("../");
2+
var normalizeOptions = require("./util/normalize_options");
3+
4+
var StatusList = NodeGit.StatusList;
5+
6+
// Override StatusList.create to normalize opts
7+
var create = StatusList.create;
8+
StatusList.create = function(repo, opts) {
9+
opts = normalizeOptions(opts, NodeGit.StatusOptions);
10+
return create(repo, opts);
11+
};
12+
13+
module.exports = StatusList;

test/tests/repository.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,30 @@ describe("Repository", function() {
110110
});
111111
});
112112
});
113+
114+
it("gets extended statuses", function() {
115+
var fileName = "my-new-file-that-shouldnt-exist.file";
116+
var fileContent = "new file from repository test";
117+
var repo = this.repository;
118+
var filePath = path.join(repo.workdir(), fileName);
119+
120+
return fse.writeFile(filePath, fileContent)
121+
.then(function() {
122+
return repo.getStatusExt().then(function(statuses) {
123+
assert.equal(statuses.length, 1);
124+
assert.equal(statuses[0].path(), fileName);
125+
assert.equal(statuses[0].indexToWorkdir().newFile().path(), fileName);
126+
assert.ok(statuses[0].isNew());
127+
});
128+
})
129+
.then(function() {
130+
return fse.remove(filePath);
131+
})
132+
.catch(function (e) {
133+
return fse.remove(filePath)
134+
.then(function() {
135+
return Promise.reject(e);
136+
});
137+
});
138+
});
113139
});

test/tests/status_file.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe("StatusFile", function() {
1010
var statusCode = Status.STATUS.WT_NEW;
1111

1212
before(function() {
13-
this.status = new StatusFile(pathName, statusCode);
13+
this.status = new StatusFile({path: pathName, status: statusCode});
1414
});
1515

1616
it("passes the path to the working function", function() {

test/tests/status_list.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
var assert = require("assert");
2+
var path = require("path");
3+
var promisify = require("promisify-node");
4+
var Promise = require("nodegit-promise");
5+
var fse = promisify(require("fs-extra"));
6+
var local = path.join.bind(path, __dirname);
7+
var exec = promisify(function(command, opts, callback) {
8+
return require("child_process").exec(command, opts, callback);
9+
});
10+
11+
describe("StatusList", function() {
12+
var Status = require(local("../../lib/status"));
13+
var StatusList = require(local("../../lib/status_list"));
14+
var Repository = require(local("../../lib/repository"));
15+
16+
var reposPath = local("../repos/workdir/.git");
17+
18+
before(function() {
19+
var test = this;
20+
return Repository.open(reposPath)
21+
.then(function(repository) {
22+
test.repository = repository;
23+
});
24+
});
25+
26+
it("gets status with deltas", function() {
27+
var fileName = "my-new-file-that-shouldnt-exist.file";
28+
var fileContent = "new file from status tests";
29+
var repo = this.repository;
30+
var filePath = path.join(repo.workdir(), fileName);
31+
return exec("git clean -xdf", {cwd: local("../repos/workdir")})
32+
.then(function() {
33+
return fse.writeFile(filePath, fileContent);
34+
})
35+
.then(function() {
36+
var opts = {
37+
flags: Status.OPT.INCLUDE_UNTRACKED +
38+
Status.OPT.RECURSE_UNTRACKED_DIRS
39+
};
40+
41+
return StatusList.create(repo, opts);
42+
})
43+
.then(function(list) {
44+
assert.equal(list.entrycount(), 1);
45+
46+
for (var i = 0; i < list.entrycount(); i++) {
47+
var entry = Status.byIndex(list, i);
48+
assert.equal(entry.indexToWorkdir().newFile().path(), fileName);
49+
}
50+
})
51+
.then(function() {
52+
return fse.remove(filePath);
53+
})
54+
.catch(function(e) {
55+
return fse.remove(filePath)
56+
.then(function() {
57+
return Promise.reject(e);
58+
});
59+
60+
});
61+
});
62+
});

0 commit comments

Comments
 (0)