MightyCreak / diffuse

Diffuse is a graphical tool for comparing and merging text files. It can retrieve files for comparison from Bazaar, CVS, Darcs, Git, Mercurial, Monotone, RCS, Subversion, and SVK repositories.
http://mightycreak.github.io/diffuse/
GNU General Public License v2.0
268 stars 45 forks source link

feature request: full diff between two commits #190

Open Ansa211 opened 1 year ago

Ansa211 commented 1 year ago

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
joyously commented 1 year ago

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

Ansa211 commented 1 year ago

Closing: a duplicate of #15 .

Ansa211 commented 1 year ago

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.

joyously commented 1 year ago

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).

Ansa211 commented 1 year ago

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 commented 1 year ago

reopening because #15 was closed without addressing this FR

nschaeff commented 1 year ago

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 commented 1 year ago

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)
Ansa211 commented 1 year ago

@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.

krlmlr commented 1 year ago

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?

nschaeff commented 1 year ago

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