Ver el file completo diff de `x` commits del historial de un solo file (que está alojado en git)

Digamos que tengo un file en git llamado filex.code , y quiero ver el código completo de las últimas x versiones de ese file con cada sección modificada resaltada , todo en un solo lugar. Entonces, un historial de commit de x paned de filex.code , casi como si estuviera haciendo un diff de x paned, pero viendo versiones históricas en lugar de fusionarse desde diferentes twigs.

Cuanto mayor sea x , mejor. Crossplatform sería genial, pero cualquiera de los tres grandes funciona. Ser capaz de editar la última versión también sería genial, pero la visualización de solo lectura es suficiente.

Tenga en count que esto es diferente de un simple historial de confirmaciones a un file, por lo que la maravillosa gitk path/to/file gitk gitk path/to/file (o SourceTree o cualquier cliente visual git que le guste) no es lo que estoy buscando. git log -p también se acerca, y su salida incluye tentadoramente toda la información que quisiera, solo que todo está en un formatting de salida lineal, casi de "procedimiento" en lugar de uno bueno, relativamente no jerárquico, visual como tu favorito GUI'd de tres paneles con Mergetool's.

( Editar: Otra opción realmente genial que en última instancia aún experimenta las deficiencias de solo mostrar la última fuente de cada línea y una salida lineal es git blame , pero es genial).

Así que no estoy precisamente buscando establecer difftool tampoco, no creo. En lugar de diferir dos versiones conocidas de un file, quiero visualizar x iteraciones de ediciones históricas en un único file.

¿Pedir demasiado? ¿Es esta una situación WTFA (Escriba la aplicación "Fantástica" [usted mismo])?

Alternativa menor: ¿hay una herramienta de combinación de tres paños a la que pueda engañar para mostrar las últimas tres confirmaciones de un único file?

Este script abre las últimas N revisiones del file una al lado de la otra.

 #!/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() 

Notas:

  1. Vimdiff tiene una limitación para resaltar diffs en solo 4 (primeros) almacenamientos intermedios, pero en cuanto a mostrarlos lado a lado, se muestran todas las revisiones de files (por ejemplo, N = 20 funciona muy bien). Para evitar la advertencia para N> 4 use COMMAND = 'vim -O' para ver las versiones una al lado de la otra sin ninguna dificultad.

  2. El guión ha crecido demasiado para el estilo SO, pero ahora es bastante resistente a las balas, pero lo suficientemente simple para un ojo experimentado.