source-foundry / fdiff

An OpenType table diff tool for fonts. Based on the fontTools TTX format.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add support for cross git branch diffs

chrissimpkins opened this issue · comments

It would be helpful to be able to diff font files with the same file path locally across git branches rather than relying on remote pushes and comparisons with remote hosting service URL.

I came here to open an issue for what I think is similar, but I'm not sure what you had in mind so let me clarify.

Git has multiple ways of integrating with external diff tools.

The current way this can be done given the way fdiff accepts arguments is with a custom difftool. First in git config:

[difftools]
    prompt = false
[difftool "fdiff"]
    cmd = fdiff "$LOCAL" "$REMOTE

This allows usage such as git difftool -t fdiff branch1..HEAD -- otfs/*otf. That's nice, but I'd rather just use it like git diff all the time.

To do this it has to work as a git diff driver, which would be setup like this:

[diff "fdiff"]
    command = fdiff

Then in atttributes:

*.otf diff=fdiff

Now just doing git diff branch1..HEAD -- otfs/*otf should do the job. The trouble is when invoked this way, git passes 7 arguments just as in GIT_EXTERNAL_DIFF. These arguments are:

path old-file old-hex old-mode new-file new-hex new-mode

I suggest modifying fdiff to recognize a 7 argument invocation in specific and to map the second and fifth arguments to it's current 2 arguments (discarding the others). This would allow it to operate as a git driver.

Is that what you had in mind with this issue or should I open another?

I was thinking that fdiff might perform the cross-branch diff comparisons by invoking git but this approach could definitely work. My goal here was to support local cross-branch binary diffs. At the moment, to perform a cross-branch diff, you need to push to a remote that exposes the files through URL (e.g., GitHub) and add URL for the left and right side of the diff.

Is it possible to set the command so that it uses an fdiff flag to set the git style argument invocation?:

[diff "fdiff"]
    command = fdiff --git

I'd like to keep support for a simple fdiff [file 1] [file 2] comparison as the default if possible.

Invoking git would be much more complex as you would have to parse a whole bunch of unrelated things. It would also be brittle as git has a hunge number of possible scenarios and it doesn't handle them all the same. Setting up as a git driver should be relatively straight-forward because git normalizes everything for you and hands you the bits on a platter. It will be much more robust that way.

I'll mess around and see it it will take that first arg and then append its 7.

There should be no reason to ditch the simple two argument mode you have now, you just neet to catch the case where there are exactly 7 arguments and extract the two you need in addition to just accepting two as currently implemented.

Yes, you can use command = fdiff --git. The next 7 arguments after that are the ones you want, so positionally (1 being --git) the args you need are 3 for the old file and 6 for the new.

Just by the by since most people don't seem to know this, Git supports global and user attribute defaults (just like repo, user, and global configs), so you don't have to set attributes up in every repository. The default is ${XDG_HOME}/git/attributes, so anybody can setup their system to always diff font files with fdiff whenever they turn up in the list of files git is diffing normally once these args are supported.

I mentioned implementing this yourself would be complicated ... one of the complicated scenarios is handling when a single diff between two commit points actually has several different file types involved. Implementing it yourself you could filter through looking for fonts, but letting git handle it the diffs will be seamlessly mixed in with everything else.

Interested in preparing a PR for this support and/or the documentation that you included in #25 (comment)?