鉴于`单个文件的历史x`提交完整文件DIFF(在Git的托管)(View full file dif

2019-09-20 11:33发布

说我有Git中称为文件filex.code ,我要看到最后的完整的代码 x 每改变部分该文件的版本强调 -在同一个地方。 因此,一个x -paned犯下的历史filex.code ,仿佛我正在做一个x -paned差异,但观察历史版本而不是从不同的分支合并。

越大x越好。 跨平台将是巨大的,但是任何三幅巨头的作品。 能够编辑最新版本也将是巨大的,但可视化是许多只读的。

请注意,这是从不同的是简单的历史的提交的文件,因此否则美妙gitk path/to/file (或SourceTree或任何视觉git的客户,您的爱)是不是我要找的。 git log -p也接近,其输出诱人包括了所有我想要的信息,只是这一切都在一个线性的,几乎是“程序上的”输出格式,而不是一个良好的,相对不分层,视觉一个像你最喜欢的三窗格GUI'd合并工具的。

编辑:最终还是经验只显示每行的最新源和线性输出是另一个缺点非常酷的选项git blame ,但它很酷。)

所以我不正是在寻找建立difftool要么,我不认为。 而不是版本比较文件的两个已知版本,我想可视化x历史编辑的迭代到单个文件。

太奢侈了? 这是一个WTFA(写的“神奇”应用[自己])的情况呢?

次级的选择:是否有一个三窗格合并工具,我可以诱使显示单个文件的最后三个提交?

Answer 1:

该脚本打开文件并排侧的最后N个版本。

#!/usr/bin/env python
import os, sys, tempfile
from shutil import rmtree
from subprocess import call, Popen, PIPE
from optparse import OptionParser
from traceback import print_exc

COMMAND = 'vim -d'

def vcall(cmd, **kwargs):
    if options.verbose:
        print ' '.join(cmd)
    return call(' '.join(cmd) if sys.platform == 'darwin' else cmd, 
                **kwargs)

parser = OptionParser('usage: %s [-n <number of revisions>] filename' % 
                      sys.argv[0])
parser.add_option('-n', '--num', dest='N', type='int', 
                  help='number of revisions', default=3)
parser.add_option('-v', '--verbose', dest='verbose',
                  help='be verbose', default=False, action='store_true')
(options, args) = parser.parse_args()
if len(args) != 1:
    parser.error('incorrect number of arguments')
filename = args[0]

if vcall('git rev-parse'.split()) != 0:
    sys.exit(1)

try:
    cmd = 'git rev-list HEAD --'.split() + [filename]
    if options.verbose:
        print ' '.join(cmd)
    pipe = Popen(' '.join(cmd) if sys.platform == 'darwin' else cmd, 
                 stdout=PIPE).stdout
    revs = []
    for i, line in enumerate(pipe):
        if i == options.N:
            break
        revs.append(line.rstrip())
except:
    print_exc()

N = len(revs)
if N == 0:
    sys.exit('fatal: ambiguous argument %s: path not in the working tree' % 
             filename)
elif N < options.N:
    sys.stderr.write('%s has only %d revision%s' % 
                     (filename, N, 's' if N > 1 else ''))

tempdir = ''
try:
    tempdir = tempfile.mkdtemp()
    head, tail = os.path.split(filename)
    tempfiles = []
    for i in xrange(N):
        tempfiles.append(tail + ('.%d' % i if i else ''))
    for i, f in enumerate(tempfiles):
        with open(os.sep.join((tempdir, f)), 'w') as fout:
            vcall(['git', 'show', '%s:./%s' % (revs[i], filename)], stdout=fout)
    vcall(COMMAND.split() + list(reversed(tempfiles)), shell=True, cwd=tempdir)
except:
    print_exc()
finally:
    try:
        if tempdir and os.path.isdir(tempdir):
            rmtree(tempdir)
    except:
        print_exc()

笔记:

  1. Vimdiff可以具有仅4(第一)缓冲器突出diff文件的限制,而是作为用于示出并排侧 - 所有文件修订示(例如N = 20个作品大)。 为了避免对于N> 4使用警告COMMAND = 'vim -O'看版本侧由端没有任何的diff在所有。

  2. 该脚本已经成长为SO风格太大,但它是相当防弹现在 - 但足够有经验的眼睛很简单。



文章来源: View full file diff of `x` commits of a single file's history (that's hosted in git)