![](/img/trans.png)
[英]How to view complete commits when tracking history of a single file in Git?
[英]View full file diff of `x` commits of a single file's history (that's hosted in git)
假設我在git中有一個名為filex.code
的文件,我希望看到該文件的最后x
版本的完整代碼 , 每個更改的部分都突出顯示 - 全部在一個地方。 因此,一個x
-paned犯下的歷史filex.code
,仿佛我正在做一個x
-paned差異,但觀察歷史版本而不是從不同的分支合並。
x
越大越好。 Crossplatform會很棒,但三巨頭中的任何一個都可以。 能夠編輯最新版本也很棒,但只讀可視化很多。
請注意,這與提交文件的簡單歷史記錄不同,因此其他精彩的gitk path/to/file
(或SourceTree或任何您喜歡的可視化git客戶端)並不是我想要的。 git log -p
也很接近,它的輸出很誘人地包含了我想要的所有信息,只是它是一個線性的,幾乎是“程序”的輸出格式,而不是像你最喜歡的一個好的,相對非分層的,視覺的三層GUI'd合並工具。
( 編輯:另一個非常酷的選項,最終仍然會遇到只顯示每一行的最新來源和線性輸出的缺點是git blame
,但它很酷。)
我也不是在考慮設置difftool ,我不這么認為。 我想要將歷史編輯的x
次迭代可視化為單個文件,而不是區分文件的兩個已知版本。
問太多了? 這是一個WTFA(寫出“神奇”App [你自己])的情況嗎?
較小的選擇:是否有一個三層合並工具,我可以欺騙顯示單個文件的最后三個提交?
此腳本並排打開文件的最后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()
筆記:
Vimdiff僅在4個(第一個)緩沖區中突出顯示差異的限制,但是並排顯示 - 顯示所有文件修訂(例如,N = 20非常好)。 為了避免N> 4的警告,請使用COMMAND = 'vim -O'
並排查看版本,而根本沒有任何差異。
腳本已經變得太大而不適合SO風格,但它現在非常防彈 - 但足夠簡單,經驗豐富的眼睛。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.