Skip to content

FR: Generalized diffedit tool invocation #7817

@whatisaphone

Description

@whatisaphone

There are several FRs floating around for tweaked diffediting workflows:

I got to thinking, there might be a single abstraction that could unify them all. This is my attempt at writing down a generalization:

  • The user can define 2 or 3 panes for a diff/merge tool invocation
  • Each pane has a change ID for its initial contents
  • Each pane has a target, to which the contents will be applied after the tool closes:
    • discard – the dir is created readonly
    • modify:changeid – the dir contents will be used to edit this change
    • (insert-before/insert-after/destination):changeid – the dir contents will be used to create a new change at that position
  • An optional "finisher" can move changes as above, that weren't edited in a pane
    • (this is the least elegant part of the idea, sorry, but it allows matching the behavior of more existing commands)

With this low-level building block, users could build these custom workflows without needing hacks/wrappers. Here's how it might solve a few of those issues:

#7641:

# default jj split -r r
jj difftool \
      --left-contents=r-   --left-target=discard   \
     --right-contents=r   --right-target=modify:r  \
    --finish-contents=r  --finish-target=insertafter:r

# feature request
jj difftool \
      --left-contents=r    --left-target=discard   \
     --right-contents=r-  --right-target=modify:r  \
    --finish-contents=r  --finish-target=insertafter:r

#6218:

# default jj squash -i -f r -t t
jj difftool \
      --left-contents=t    --left-target=discard   \
     --right-contents=r   --right-target=modify:t

# feature request
jj difftool \
      --left-contents=r    --left-target=discard   \
     --right-contents=t   --right-target=modify:t

This would also enable some workflows that are currently not possible. One thing I miss from git is editing the workdir (@, left) at the same time as staging changes (to @- on the right). If this feature existed, that could be done like this:

jj difftool \
      --left-contents=@    --left-target=modify:@  \
     --right-contents=@-  --right-target=modify:@-

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions