diffuse icon indicating copy to clipboard operation
diffuse copied to clipboard

feature request: full diff between two commits

Open Ansa211 opened this issue 2 years ago • 11 comments

Currently, we have three options for working with version controlled files:

  ( -m | --modified )              Create a new tab for each modified file
  ( -c | --commit ) <rev>          File revisions <rev-1> and <rev>
  ( -r | --revision ) <rev>        File revision <rev>

As far as I can tell, these are actually used as

diffuse -m                                  // for working-copy changes, in git also for staged uncommited changes
diffuse -c <rev>                            // compare two consecutive revisions
diffuse -r <rev> <file> <file>              // compare selected revision to working copy of a given file
diffuse -r <rev1> <file> -r <rev2> <file>   // compare two revisions of a given file

I am looking for an option to compare the full state of the repository between two revisions, so something like -c or -m, but with two revision parameters, or something like -r, but without the <file> parameters:

diffuse -r <rev>    // open al files that differ between <rev> and working copy
diffuse -C <rev1> <rev2>  // like -c, but revisions don't have to be consecutive

Ansa211 avatar Jan 24 '23 14:01 Ansa211

Doesn't diffuse work with single files, not multiple files? Also, see #63 and #15.

joyously avatar Jan 24 '23 16:01 joyously

Closing: a duplicate of #15 .

Ansa211 avatar Jan 24 '23 16:01 Ansa211

Doesn't diffuse work with single files, not multiple files? Also, see #63 and #15.

Well, no, the -m and -c options open multiple files simultaneously.

Ansa211 avatar Jan 24 '23 16:01 Ansa211

By multiple, I meant like a folder or all the files in a commit. I think it only deals with a single view of comparison, although that can involve several files (2-way, 3-way, more).

joyously avatar Jan 24 '23 17:01 joyously

I most often invoke diffuse with -m, which opens each file with unstaged and/or uncommitted changes in a separate tab. No additional arguments are required, just the switch!

Similarly, diffuse -c <rev> without further arguments opens a separate tab for each file affected by the commit <rev>.

Thus, the treatment of individual commits and of uncommitted/unstaged changes is very satisfactory indeed! And because those options already exist, I suspect extending them to comparison of non-consecutive commits should not be difficult (at least for some VCSs; as @MightyCreak pointed out in one of the other issues, the problem is in implementing a new switch for all 7 or 8 supported VCSs including the less common ones).


If you'd like to be picky, you could point out that diffuse still can not fully reflect all possible changes that a version control system could track (e.g. changed rights and ownership of files, or additions/deletions of empty folders). Git merge commits are possibly also a problem (-c <merge commit> does not open anything for me, instead of the expected 3-fold comparison of the two original branches on either side and the result of merging them in the middle).

Ansa211 avatar Jan 24 '23 22:01 Ansa211

reopening because #15 was closed without addressing this FR

Ansa211 avatar May 22 '23 10:05 Ansa211

Here is a patch that provides full diff between two commits for git. It is used like :

diffuse -c commit1..commit2    # shows the full diff between git commit1 and commit2
--- a/src/diffuse/vcs/git.py
+++ b/src/diffuse/vcs/git.py
@@ -39,7 +39,10 @@ class Git(VcsInterface):
         for name in names:
             isabs |= os.path.isabs(name)
         # run command
-        prev = rev + '^'
+        if '..' in rev:
+            prev, rev = rev.split('..')
+        else:
+            prev = rev + '^'
         fs = FolderSet(names)
         modified = {}
         for s in utils.popenReadLines(self.root, args, prefs, 'git_bash'):

nschaeff avatar Jun 01 '23 19:06 nschaeff

Same thing for mercurial (a bit more tricky, hopefully it does not break anything!)

--- a/src/diffuse/vcs/hg.py
+++ b/src/diffuse/vcs/hg.py
@@ -66,6 +66,12 @@ class Hg(VcsInterface):
             args.append(utils.safeRelativePath(self.root, name, prefs, 'hg_cygwin'))
         # run command
         prev = self._getPreviousRevision(prefs, rev)
+        if rev is not None:
+            if '..' in rev:
+                prev, rev = rev.split('..')
+                args.extend(['-r',prev,'-r',rev])
+            else:
+                args.extend(['-r',rev])
         fs = FolderSet(names)
         modified = {}
         for s in utils.popenReadLines(self.root, args, prefs, 'hg_bash'):
@@ -92,7 +98,7 @@ class Hg(VcsInterface):
         return self._getCommitTemplate(
             prefs,
             names,
-            ['log', '--template', 'A\t{file_adds}\nM\t{file_mods}\nR\t{file_dels}\n', '-r', rev],
+            ['log', '--template', 'A\t{file_adds}\nM\t{file_mods}\nR\t{file_dels}\n'],
             rev)

nschaeff avatar Jun 01 '23 20:06 nschaeff

@nschaeff Works like a charm. Thanks so much!

For anyone running diffuse from flatpak, I've been able to apply the patch by manually editing the file /var/lib/flatpak/app/io.github.mightycreak.Diffuse/x86_64/stable/feb78314b6377384a33435a6c9cf2a7a04e7d907ba5ce7eeb2656f221b6fdf83/files/share/diffuse/diffuse/vcs/git.py without having to recompile anything.

EDIT: I've been able to update diffuse by running flatpak update io.github.mightycreak.Diffuse (from 0.8.1 to 0.8.2) and the edit in the file even persisted. I suppose an update that would touch one of the manually edited files might break down, though.

Ansa211 avatar Jul 03 '23 08:07 Ansa211

This looks good to me. Git also uses the triple dot ... to separate revisions, with slightly different semantics. I wonder if we could leave the parsing of revision lists to Git.

Either way, the proposed patches look good. Who can help with a pull request?

krlmlr avatar Aug 05 '23 17:08 krlmlr

There is already one: https://github.com/MightyCreak/diffuse/pull/212

nschaeff avatar Aug 21 '23 12:08 nschaeff