2012-07-30 8 views
4

내가 filex.code라는 자식에서 파일을 말해봐, 내가 그 마지막 x 버전의 전체 코드을보고 싶어 단일 파일의 역사를 커밋 로 변경된 각 섹션이 바뀌 었습니다. - 한 곳에서 모두 강조 표시되었습니다. 따라서 x - 패널 된 커밋 내역은 x - paned diff이지만 거의 다른 지점에서 병합하는 것이 아니라 이전 버전을보고있는 것처럼 filex.code입니다.보기 전체 파일은 diff (즉,이 자식에서 호스팅)

x 일수록 좋습니다. Crossplatform은 훌륭하지만 Big 3 작품 중 하나입니다. 최신 버전을 편집 할 수 있다는 것도 좋지만 읽기 전용 시각화는 충분합니다.

이것은 파일에 대한 커밋의 simple history과 다른 점을 유의하십시오. 그렇지 않으면 매우 멋진 gitk path/to/file (또는 SourceTree 또는 내가 좋아하는 시각적 인 자식 클라이언트)은 제가 찾고있는 것이 아닙니다. git log -p도 가까워지고 그 출력에는 내가 원하는 모든 정보가 포함되어 있습니다. 좋아하는 세 개의 팬으로 구성된 상대적으로 비 계층적이고 시각적 인 형식이 아닌 선형적인 거의 절차적인 출력 형식을 사용합니다. GUI가 만든 도구.

(편집 : 궁극적으로 여전히 각 라인의 최신 소스를 보여주는의 단점을 경험하는 또 다른 정말 멋진 옵션 & 선형 출력 git blame이지만, 괜찮아.)

그래서 내가 정확하게 찾는 게 아니에요 setting up difftool 중 하나라고 생각하지 않습니다. 두 개의 알려진 버전의 파일을 비교하는 대신, x 한 파일에 대한 내역 편집의 반복을 시각화하고 싶습니다.

너무 많이 부탁하나요? WTFA입니까 ("환상적인"App [yourself]라고 쓰십시오) 상황입니까?

대체 방법 : 단일 파일의 마지막 3 가지 커밋을 표시하는 트릭을 할 수있는 3 인용 멀젯 툴이 있습니까?

답변

3

이 스크립트는 파일의 마지막 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 (제 1) 버퍼의 차이점을 강조 표시의 제한이 있지만 나란히 나타내는 바와 같이 - 모든 파일의 버전이 표시된다 (예를 들어 N = 20 위대). N> 4에 대한 경고를 피하려면 COMMAND = 'vim -O'을 사용하여 diff를 전혀 보지 않고 버전을 나란히 볼 수 있습니다.

  2. 스크립트가 SO 스타일에 비해 너무 커졌지만 지금은 경험이 부족한 사람에게는 충분히 간단합니다.

+0

고정. 지금 일해야한다. –

+0

OS X 10.7.4의 주식 python에서 작동하도록 수정 된 편집물을 넣었습니다. cwd가 작동했지만 vimdiff를 호출하지 않았습니다. 왜 안되는지. 어떤 이유로 든 편집이 거절 된 경우 코드 [here] (http://rufwork.com/files/python/diffige.py). 감사. ** 정말 좋은 물건들. 댓글을 정리하려고합니다. – ruffin

+0

한 문자열을 통해 목록 대신'call'에 인수를 전달하는 방법은 다음과 같습니다. "args에 문자열이 지정되면 실행될 프로그램의 이름이나 경로로 사용되며 프로그램이 실행중인 경우에만 작동합니다 아무 인자도 주어지지 않았다. " OS X 구현이 다소 비표준 인 것처럼 보입니다. –