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

FR: make $left and $right environment variables expand to full file path to improve diffing integration in vscode and winmerge #3696

Open
wmjdgla opened this issue May 16, 2024 · 3 comments
Labels
polish🪒🐃 Make existing features more convenient and more consistent

Comments

@wmjdgla
Copy link

wmjdgla commented May 16, 2024

Per https://martinvonz.github.io/jj/v0.17.1/config/, when handling diffing operations (e.g. jj diff, jj split, jj squash -i), $left and $right are expanded to directories. This happens even when a single file is given as argument to the command. However, vscode's diffing option (-d) only knows how to handle file paths; passing directory paths to it results in (produced by jj diff -r <rev> test.txt):
jj-fr-vscode

The left and right directories are simply added to the workspace and no diff view is produced. Also, this overwrites the entire workspace despite passing --reuse-window to vscode. This is more of a vscode issue, but it can be avoided had we used the full file path instead.

For winmerge, jj diff -r <rev> test.txt results in:
jj-fr-winmerge

Double-clicking the file entry produces the diff view, but we could have accessed it directly had we used the full file path instead.

When multiple files are changed in a commit, expanding $left and $right to directories makes sense if users don't specify which file they want to target. But if they do, then it would be great to expand to the full file path so that they can directly access the file diff.

The TOML settings I used:

# Uncomment as desired
#ui.diff.tool = "vscode"
#ui.diff-editor = "vscode"

#ui.diff.tool = "winmerge"
#ui.diff-editor = "winmerge"

merge-tools.vscode.diff-args = ["--reuse-window", "-w", "-d", "$left", "$right"]
merge-tools.vscode.edit-args = ["--reuse-window", "-w", "-d", "$left", "$right"]
merge-tools.winmerge.edit-args = ["/e", "$left", "$right"]
merge-tools.winmerge.diff-args = ["/e", "$left", "$right"]

merge-tools.vscode.program = "C:/Users/User/AppData/Local/Programs/Microsoft VS Code/bin/code.cmd"
merge-tools.winmerge.program = "C:/Program Files/WinMerge/WinMergeU.exe"
@PhilipMetzger PhilipMetzger added polish🪒🐃 Make existing features more convenient and more consistent labels May 16, 2024
@yuja
Copy link
Collaborator

yuja commented May 17, 2024

Perhaps, we'll need some flag denoting whether the tool is capable of dir-diff (e.g. file-diff-args = [..], dir-diff-args = [] # disabled). We might also need gui = true (or type = stream|gui|tui.)

If jj gained copy tracking, user might want to spawn diff tool with "file" args even if it supports directory diff.

@ilyagr
Copy link
Collaborator

ilyagr commented May 17, 2024

There are also some related issues that come to mind.

We'd also want something similar for resolve. Currently, it always assumes that the tool is not capable of dir-diff (or should it be called dir-merge?), but some tools could do jj resolve with directories if we called them correctly (e.g. Beyond Compare and kdiff3, though I'm not sure how nice kdiff3's interface for this is).

Also, we could consider having a prompt if a tool can't handle dir-diff and multiple files are being compared. Same for jj resolve.

For something like jj split, the user might have to do diff editing more than once if the diff editor can't handle dirdiff. I guess it's OK: they'll get more than 2 commits, and then they can squash some of them.


As an aside, I checked and it seems code does not support code -d file1a file1b -d file2a file2b. If it ever does, we could consider yet more fancy argument passing options.

@wmjdgla
Copy link
Author

wmjdgla commented May 17, 2024

Using file-diff-args and dir-diff-args to differentiate handling of files and directories sounds like a good idea.

If the tool is incapable of dir-diff, then it can just invoke file-diff-args multiple times for each pair of files, which will spawn multiple windows/tabs of the tool. This way we'll be independent of whether the tool supports repeated diff options (e.g. code -d file1a file1b -d file2a file2b). This can also handle the case where users explicitly specify the target file(s) as arguments.

To guard against creating a huge number of windows/tabs (because too many files were changed), a configurable limit can be set - on exceeding the limit, jj can warn the user that it'll be opening X number of files and ask to confirm whether to proceed. If not configured, it'll just use a default value, say 10 files? For convenience, an additional option can be implemented to suppress this warning if desired.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
polish🪒🐃 Make existing features more convenient and more consistent
Projects
None yet
Development

No branches or pull requests

4 participants