diffsitter
diffsitter copied to clipboard
provide context in the form of unchanged lines or AST nodes
Is your feature request related to a problem? Please describe.
When using diffsitter as tool for git diff
, line numbers don't make it immediately obvious where the change occurred.
Describe the solution you'd like
It would be nice if some surrounding context (3 lines before, 3 lines after) could be given, similar to how regular git diff
and diff -C3
do it.
Describe alternatives you've considered
An alternative would be to allow machine-readable types of output (eg. json
) for me or anyone else to write a new front-end around the logic of diffsitter.
Additional context If it's not as obvious what counts as a line in AST-land, I would also be happy if I could get 10 AST nodes before and 10 AST nodes after the change (or some other configurable amount).
I think this, and providing the output in a more diff
/ git diff
'standard unified output' sort of a format would make these tool a LOT more useful for my needs.
As currently is, the output format is so newline/whitespace heavy and different from existing diff patterns that it's sort of painful to use (particularly over large files)
For example, using this repo (Ref), and this git config:
# https://github.com/afnanenayet/diffsitter
[difftool "diffsitter"]
cmd = diffsitter "$LOCAL" "$REMOTE"
# https://github.com/afnanenayet/diffsitter
[difftool "diffsitter-debug"]
cmd = diffsitter --debug "$LOCAL" "$REMOTE"
Here is the first 100 lines of output from a diff with diffsitter
:
diffsitter
⇒ git difftool --tool diffsitter-debug 10d79cb6ed1dcefc36de84f4ce36a76ed3037d09~1 10d79cb6ed1dcefc36de84f4ce36a76ed3037d09 -- unpacked/_next/static/chunks/webpack.js > webpack.js-diffsitter.diff
2024-01-31T03:32:29.788Z DEBUG diffsitter > Checking if /var/folders/j4/kxtq1cjs1l98xfqncjbsbx1c0000gn/T//git-blob-kOCeQp/webpack.js can be parsed
2024-01-31T03:32:29.788Z INFO libdiffsitter::parse > Deduced language "typescript" from extension "js" provided from user mappings
2024-01-31T03:32:29.788Z INFO libdiffsitter::parse > Using tree-sitter parser for language typescript
2024-01-31T03:32:29.788Z INFO libdiffsitter::parse > Succeeded loading grammar for typescript
2024-01-31T03:32:29.788Z DEBUG diffsitter > Checking if /var/folders/j4/kxtq1cjs1l98xfqncjbsbx1c0000gn/T//git-blob-NsH9wd/webpack.js can be parsed
2024-01-31T03:32:29.788Z INFO libdiffsitter::parse > Deduced language "typescript" from extension "js" provided from user mappings
2024-01-31T03:32:29.788Z INFO libdiffsitter::parse > Using tree-sitter parser for language typescript
2024-01-31T03:32:29.788Z INFO libdiffsitter::parse > Succeeded loading grammar for typescript
2024-01-31T03:32:29.788Z DEBUG diffsitter > Extensions for both input files are supported
2024-01-31T03:32:29.789Z DEBUG libdiffsitter > Reading /var/folders/j4/kxtq1cjs1l98xfqncjbsbx1c0000gn/T//git-blob-kOCeQp/webpack.js to string
2024-01-31T03:32:29.789Z INFO libdiffsitter > Will deduce filetype from file extension
2024-01-31T03:32:29.789Z INFO libdiffsitter::parse > Deduced language "typescript" from extension "js" provided from user mappings
2024-01-31T03:32:29.789Z INFO libdiffsitter::parse > Using tree-sitter parser for language typescript
2024-01-31T03:32:29.789Z INFO libdiffsitter::parse > Succeeded loading grammar for typescript
2024-01-31T03:32:29.789Z DEBUG libdiffsitter::parse > Constructed parser
2024-01-31T03:32:29.795Z DEBUG libdiffsitter::parse > Parsed AST
2024-01-31T03:32:29.795Z INFO TimerFinished > parse::parse_file(), Elapsed=6.671597ms
2024-01-31T03:32:29.795Z DEBUG libdiffsitter > Reading /var/folders/j4/kxtq1cjs1l98xfqncjbsbx1c0000gn/T//git-blob-NsH9wd/webpack.js to string
2024-01-31T03:32:29.795Z INFO libdiffsitter > Will deduce filetype from file extension
2024-01-31T03:32:29.795Z INFO libdiffsitter::parse > Deduced language "typescript" from extension "js" provided from user mappings
2024-01-31T03:32:29.795Z INFO libdiffsitter::parse > Using tree-sitter parser for language typescript
2024-01-31T03:32:29.795Z INFO libdiffsitter::parse > Succeeded loading grammar for typescript
2024-01-31T03:32:29.795Z DEBUG libdiffsitter::parse > Constructed parser
2024-01-31T03:32:29.798Z DEBUG libdiffsitter::parse > Parsed AST
2024-01-31T03:32:29.798Z INFO TimerFinished > parse::parse_file(), Elapsed=3.05771ms
2024-01-31T03:32:29.800Z INFO TimerFinished > ast::from_ts_tree(), Elapsed=1.473472ms
2024-01-31T03:32:29.801Z INFO TimerFinished > ast::process(), Elapsed=2.954186ms
2024-01-31T03:32:29.803Z INFO TimerFinished > ast::from_ts_tree(), Elapsed=1.841499ms
2024-01-31T03:32:29.805Z INFO TimerFinished > ast::process(), Elapsed=3.629676ms
2024-01-31T03:32:29.897Z INFO TimerFinished > diff::compute_edit_script(), Elapsed=92.026392ms
2024-01-31T03:32:29.897Z INFO libdiffsitter::render::unified > Using stack style horizontal for title
// ..snip..
/var/folders/j4/kxtq1cjs1l98xfqncjbsbx1c0000gn/T//git-blob-kOCeQp/webpack.js -> /var/folders/j4/kxtq1cjs1l98xfqncjbsbx1c0000gn/T//git-blob-NsH9wd/webpack.js
============================================================================================================================================================
7:
--
- f,
8 - 17:
-------
+ o,
+ f,
+ i,
+ d,
+ u,
+ b,
+ s = {},
+ l = {};
+ function p(e) {
+ var t = l[e];
11 - 14:
--------
- i = {},
- u = {};
- function b(e) {
- var t = u[e];
16:
---
- var n = (u[e] = { id: e, loaded: !1, exports: {} }),
19:
---
+ var n = (l[e] = { id: e, loaded: !1, exports: {} }),
22:
---
+ s[e].call(n.exports, n, n.exports, p), (r = !1);
19:
---
- i[e].call(n.exports, n, n.exports, b), (r = !1);
21:
---
- r && delete u[e];
24:
---
+ r && delete l[e];
28 - 29:
--------
+ (p.m = s),
+ (p.amdD = function () {
25 - 26:
--------
- (b.m = i),
- (b.amdD = function () {
32:
---
+ (p.amdO = {}),
29:
---
- (b.amdO = {}),
34:
---
+ (p.O = function (t, n, r, c) {
31:
---
- (b.O = function (t, n, r, c) {
34 - 35:
--------
- for (var f = e.length; f > 0 && e[f - 1][2] > c; f--) e[f] = e[f - 1];
- e[f] = [n, r, c];
37 - 38:
--------
+ for (var a = e.length; a > 0 && e[a - 1][2] > c; a--) e[a] = e[a - 1];
+ e[a] = [n, r, c];
41:
---
+ for (var o = 1 / 0, a = 0; a < e.length; a++) {
38:
---
- for (var a = 1 / 0, f = 0; f < e.length; f++) {
43 - 45:
--------
+ var n = e[a][0], r = e[a][1], c = e[a][2], f = !0, i = 0;
+ i < n.length;
+ i++
// ..snip (lines 101-867)..
Compare that to diffing the same file with a normal git diff
:
git diff
⇒ git diff 10d79cb6ed1dcefc36de84f4ce36a76ed3037d09~1 10d79cb6ed1dcefc36de84f4ce36a76ed3037d09 -- unpacked/_next/static/chunks/webpack.js > webpack.js-git.diff
diff --git a/unpacked/_next/static/chunks/webpack.js b/unpacked/_next/static/chunks/webpack.js
index bd3fc07..bffcb59 100644
--- a/unpacked/_next/static/chunks/webpack.js
+++ b/unpacked/_next/static/chunks/webpack.js
@@ -5,58 +5,61 @@
n,
r,
c,
- f,
a,
o,
+ f,
+ i,
d,
- i = {},
- u = {};
- function b(e) {
- var t = u[e];
+ u,
+ b,
+ s = {},
+ l = {};
+ function p(e) {
+ var t = l[e];
if (void 0 !== t) return t.exports;
- var n = (u[e] = { id: e, loaded: !1, exports: {} }),
+ var n = (l[e] = { id: e, loaded: !1, exports: {} }),
r = !0;
try {
- i[e].call(n.exports, n, n.exports, b), (r = !1);
+ s[e].call(n.exports, n, n.exports, p), (r = !1);
} finally {
- r && delete u[e];
+ r && delete l[e];
}
return (n.loaded = !0), n.exports;
}
- (b.m = i),
- (b.amdD = function () {
+ (p.m = s),
+ (p.amdD = function () {
throw Error("define cannot be used indirect");
}),
- (b.amdO = {}),
+ (p.amdO = {}),
(e = []),
- (b.O = function (t, n, r, c) {
+ (p.O = function (t, n, r, c) {
if (n) {
c = c || 0;
- for (var f = e.length; f > 0 && e[f - 1][2] > c; f--) e[f] = e[f - 1];
- e[f] = [n, r, c];
+ for (var a = e.length; a > 0 && e[a - 1][2] > c; a--) e[a] = e[a - 1];
+ e[a] = [n, r, c];
return;
}
- for (var a = 1 / 0, f = 0; f < e.length; f++) {
+ for (var o = 1 / 0, a = 0; a < e.length; a++) {
for (
- var n = e[f][0], r = e[f][1], c = e[f][2], o = !0, d = 0;
- d < n.length;
- d++
+ var n = e[a][0], r = e[a][1], c = e[a][2], f = !0, i = 0;
+ i < n.length;
+ i++
)
- a >= c &&
- Object.keys(b.O).every(function (e) {
- return b.O[e](n[d]);
+ o >= c &&
+ Object.keys(p.O).every(function (e) {
+ return p.O[e](n[i]);
})
- ? n.splice(d--, 1)
- : ((o = !1), c < a && (a = c));
- if (o) {
- e.splice(f--, 1);
- var i = r();
- void 0 !== i && (t = i);
+ ? n.splice(i--, 1)
+ : ((f = !1), c < o && (o = c));
+ if (f) {
+ e.splice(a--, 1);
+ var d = r();
+ void 0 !== d && (t = d);
}
}
return t;
}),
- (b.n = function (e) {
+ (p.n = function (e) {
var t =
e && e.__esModule
? function () {
@@ -65,7 +68,7 @@
: function () {
return e;
};
- return b.d(t, { a: t }), t;
+ return p.d(t, { a: t }), t;
// ..snip (lines 101-603)..
Contrasting the two diffs, not only is the git diff
far more useful with the extra context/format; but it's ~264
lines shorter as well.
For a single line of diff change, diffsitter
currently produces ~8
lines of output:
21:
---
- r && delete u[e];
24:
---
+ r && delete l[e];
Compared to git diff
s 2
(3
if you include a chunk header, more if you start including extra lines of context, but that then becomes an unfair comparison):
- r && delete u[e];
+ r && delete l[e];