Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative diff output #263

Open
morgante opened this issue Apr 22, 2024 · 3 comments
Open

Alternative diff output #263

morgante opened this issue Apr 22, 2024 · 3 comments

Comments

@morgante
Copy link
Contributor

Some users like to customize their git diff output.

In theory, grit apply is very similar and we should be able to hook into a pluggable diff output format. Ex. ripgrep seems to work with delta here: https://dandavison.github.io/delta/grep.html

@noahbald
Copy link

noahbald commented Apr 27, 2024

@morgante Not sure I'll be able to help too much on this one as it might be a bit more heft than I can handle at this point. Here's what I've been able to find so far regarding this issue though.

From what I've found Delta works by parsing the output of a stream. If we choose to get things working with other pagers such as Delta then we need to (or at least ned to have the option to) output contents the same as git diff and rg --json does.

git diff filename.txt | delta

Starting with the output of diffs, we can compare our output to that of git.

diff --git a/package.json b/package.json
index 2b3133b..af4a1f8 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
 {
-  "name": "@getgrit/gritql",
+  "name": "DELETE_ME",
   "version": "0.2.2",
   "description": "Core GritQL engine and CLI",
   "author": "",

For readability we need at least the following

  • ---a/filename.txt and +++b/filename.txt for readable filenames
  • @@ -1,5 +1,5 @@ for the before/after line ranges
  • lines should be prepended with -, + or before the whitespace

Let's compare this with our current output

example.js
    -const myVar = 2;
    +let myVar = 2;
    

Processed 1 files and found 1 matches

It's fine to keep the message at the end of the diff. It doesn't start with -, +, or so it doesn't format it.


Now, taking a look at match outputs as a grep format, Delta expects an output formatted like rg --json -C 2 "my-query"

{ "type": "begin", "data": { "path": { "text": "package.json" } } },
{
  "type": "context",
  "data": {
    "path": { "text": "package.json" },
    "lines": { "text": "{\n" },
    "line_number": 1,
    "absolute_offset": 0,
    "submatches": []
  }
},
{
  "type": "match",
  "data": {
    "path": { "text": "package.json" },
    "lines": { "text": "  \"name\": \"DELETE_ME\",\n" },
    "line_number": 2,
    "absolute_offset": 2,
    "submatches": [
      { "match": { "text": "DELETE_ME" }, "start": 11, "end": 20 }
    ]
  }
},
// ...more match/context blocks
{
  "type": "end",
  "data": {
    "path": { "text": "grep-example.txt" },
    "binary_offset": null,
    "stats": {
      "elapsed": { "secs": 0, "nanos": 1656401, "human": "0.001656s" },
      "searches": 1,
      "searches_with_match": 1,
      "bytes_searched": 1260,
      "bytes_printed": 1736,
      "matched_lines": 1,
      "matches": 2
    }
  }
},
// ...more start/end blocks with match/context blocks between
{
  "data": {
    "elapsed_total": { "human": "2.397146s", "nanos": 397145746, "secs": 2 },
    "stats": {
      "bytes_printed": 2477,
      "bytes_searched": 1710,
      "elapsed": { "human": "0.003502s", "nanos": 3502102, "secs": 0 },
      "matched_lines": 2,
      "matches": 3,
      "searches": 2,
      "searches_with_match": 2
    }
  },
  "type": "summary"
}

From messing with this output, it seems the only thing we can omit is the following

  • "type": "summary" blocks

Approaches

There a many ways we could approach this, and we might want to discuss the most appropriate method to do this. We would need to update the formatter to match git diff/grep --json either when

  1. When any output is made;
  2. When an option to --output (eg --output pager) to format according to the needs of Delta;
  3. When grit's stdout is sent to a pipe, format according to the needs of Delta; or
  4. When a configuration option to use a pager such as delta. When given, pipe the output to the specified executable, in the format Delta expects

Caveats

  • Unfortunately, grit doesn't know how to handle diffs and matches being passed to it side-by-side. So the pager may have to be run multiple times as we switch from type to type. This will probably make most approaches listed non-feasible

@morgante
Copy link
Contributor Author

morgante commented Apr 27, 2024

Thanks for investigating this!

Overall, I think I like the option of starting with an --output=diff flag which will match git diff output. This should be fairly portable, and if I understand correctly, would allow piping into Delta easily.

Once that's implemented, we could consider an --pager flag to handle the piping ourselves.

Unfortunately, grit doesn't know how to handle diffs and matches being passed to it side-by-side. So the pager may have to be run multiple times as we switch from type to type.

Do you mean that delta doesn't support this? For initial implementation, I assume we would only really be interested in diffs.

@noahbald
Copy link

Yeah what I mean is that we can't mix diffs and grep outputs together. Each type would have to be processed by delta separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants