diffuse icon indicating copy to clipboard operation
diffuse copied to clipboard

Revision history

Open MightyCreak opened this issue 5 years ago • 3 comments

Feature

When doing a file comparison based on SCMs (e.g. git, svn, bzr, ...), it would be nice to be able to browse through the revisions/commits of the file.

Notes

  • I don't know how feasible this feature is, it would require some planning ahead in order to know which SCMs will be compatible with such feature
  • This feature was extracted from #60.

MightyCreak avatar Aug 12 '20 21:08 MightyCreak

Any update or work on this?

Looking for outside contributors?

maifeeulasad avatar Jul 01 '21 08:07 maifeeulasad

The -c option is for a specific commit. The -r option is for a specific revision. Perhaps we could make a chart to start with, of the different VCS and the command needed to get to different revisions of the same file. Looking through the code, here is what I see for the current functionality. It looks like there is already code for getting the previous revision. We might just need UI to trigger it.

Git

args = [ prefs.getString('git_bin'), 'show', '--pretty=format:', '--name-status', rev ] args = [ prefs.getString('git_bin'), 'status', '--porcelain', '-s', '--untracked-files=no', '--ignore-submodules=all' ]

return popenRead(self.root, [ prefs.getString('git_bin'), 'show', '%s:%s' % (rev, relpath(self.root, os.path.abspath(name)).replace(os.sep, '/')) ], prefs, 'git_bash')

SVN

def _getPreviousRevision(self, rev):
    if rev is None:
        return 'BASE'
    m = int(rev)
    if m > 1:
        return str(m - 1)
    if rev is None:
        args = [ vcs_bin, 'status', '-q' ]
    else:
        args = [ vcs_bin, 'diff', '--summarize', '-c', rev ]

for s in popenReadLines(self.root, [ vcs_bin, 'list', '-r', rev, '%s/%s' % (self._getURL(prefs), p.replace(os.sep, '/')) ], prefs, vcs_bash):

 def getRevision(self, prefs, name, rev):
     vcs_bin = prefs.getString('svn_bin')
     if rev in [ 'BASE', 'COMMITTED', 'PREV' ]:
         return popenRead(self.root, [ vcs_bin, 'cat', '%s@%s' % (safeRelativePath(self.root, name, prefs, 'svn_cygwin'), rev) ], prefs, 'svn_bash')
     return popenRead(self.root, [ vcs_bin, 'cat', '%s/%s@%s' % (self._getURL(prefs), relpath(self.root, os.path.abspath(name)).replace(os.sep, '/'), rev) ], prefs, 'svn_bash')

Bazaar

args = [ prefs.getString('bzr_bin'), 'log', '-v', '-r', rev ] args = [ prefs.getString('bzr_bin'), 'status', '-SV' ]

return popenRead(self.root, [ prefs.getString('bzr_bin'), 'cat', '--name-from-revision', '-r', rev, safeRelativePath(self.root, name, prefs, 'bzr_cygwin') ], prefs, 'bzr_bash')

Darcs

args.extend(['log', '--number', '-s'])
try:
  args.extend(['-n', str(int(rev))])
except ValueError:
  args.extend(['-h', rev]
args = [ prefs.getString('darcs_bin'), 'show', 'contents' ]
try:
   args.extend([ '-n', str(int(rev)) ])
except ValueError:
   args.extend([ '-h', rev ])
args.append(safeRelativePath(self.root, name, prefs, 'darcs_cygwin'))
return popenRead(self.root, args, prefs, 'darcs_bash')

CVS

args = [ prefs.getString('cvs_bin'), '-nq', 'update', '-R' ]

return popenRead(self.root, [ prefs.getString('cvs_bin'), '-Q', 'update', '-p', '-r', rev, safeRelativePath(self.root, name, prefs, 'cvs_cygwin') ], prefs, 'cvs_bash')

Mercurial

ss = popenReadLines(self.root, [ prefs.getString('hg_bin'), 'id', '-i', '-t' ], prefs, 'hg_bash') return self._getCommitTemplate(prefs, names, [ 'log', '--template', 'A\t{file_adds}\nM\t{file_mods}\nR\t{file_dels}\n', '-r', rev ], rev)

return popenRead(self.root, [ prefs.getString('hg_bin'), 'cat', '-r', rev, safeRelativePath(self.root, name, prefs, 'hg_cygwin') ], prefs, 'hg_bash')

Monotone

ss = popenReadLines(self.root, [ vcs_bin, 'automate', 'select', '-q', rev ], prefs, 'mtn_bash') args = [ prefs.getString('mtn_bin'), 'automate', 'inventory', '--no-ignored', '--no-unchanged', '--no-unknown' ]

return popenRead(self.root, [ prefs.getString('mtn_bin'), 'automate', 'get_file_of', '-q', '-r', rev, safeRelativePath(self.root, name, prefs, 'mtn_cygwin') ], prefs, 'mtn_bash')

RCS

args = [ prefs.getString('rcs_bin_rlog'), '-L', '-h', safeRelativePath(self.root, name, prefs, 'rcs_cygwin') ]
rev = ''
for line in popenReadLines(self.root, args, prefs, 'rcs_bash'):
    if line.startswith('head: '):
         rev = line[6:]

cmd = [ prefs.getString('rcs_bin_rlog'), '-L', '-h' ]

return popenRead(self.root, [ prefs.getString('rcs_bin_co'), '-p', '-q', '-r' + rev, safeRelativePath(self.root, name, prefs, 'rcs_cygwin') ], prefs, 'rcs_bash')

SVK

def _getPreviousRevision(self, rev):
    if rev is None:
        return 'HEAD'
    if rev.endswith('@'):
        return str(int(rev[:-1]) - 1) + '@'
    return str(int(rev) - 1)
return popenRead(self.root, [ prefs.getString('svk_bin'), 'cat', '-r', rev, '%s/%s' % (self._getURL(prefs), relpath(self.root, os.path.abspath(name)).replace(os.sep, '/')) ], prefs, 'svk_bash')

joyously avatar Jul 01 '21 17:07 joyously

Thanks @joyously for the code digging ! :wink:

Yep I think here the most difficult part would be to have a nice UX to present that.

One UI I know is the Perforce Time-lapse View: https://www.perforce.com/video-tutorials/vcs/using-time-lapse-view (there's a video to explain how it works)

I think that would be a good start. The idea would be to have a timeline component that would display all the commits of a file, then we would be able to change the begin and end brackets and the result would be the diff between the end commit and the start commit (e.g. git diff commit1..commit2). We could start with a simple cursor that would only show the difference between two successive commits.

MightyCreak avatar Jan 16 '22 22:01 MightyCreak