Skip to content

Instantly share code, notes, and snippets.

@messa
Created November 18, 2009 16:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save messa/238017 to your computer and use it in GitHub Desktop.
Save messa/238017 to your computer and use it in GitHub Desktop.
SVN log with diffs
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Subversion log s diffy
Utilita pro jednoduché zobrazení historie vycheckoutovaného SVN (Subversion)
repozitáře, včetně zobrazení rozdílů (diffů) v jednotlivých revizích.
Něco jako 'git log -p --color'.
Použití: svnlog.py | less -R
Doporučení: udělejte si na toto nějaký pěkný symlink nebo alias.
"""
__author__ = "Petr Messner"
import re
import subprocess
import sys
# tento regulární výraz je podrobnější, než by k funkčnosti stačilo, ale ať
# máme jistotu, že log vypadá skutečně tak, jak ho předpokládáme
reHeaderLine = re.compile(r"^r([0-9]+) \| (.+) \| (20..-..-.. ..:..:.. \+.... \(.+?, .+? .+? 20..\)) \| ([0-9]+) lines?$")
def process_revision(pipe):
"""
Zpracování jednoho záznamu ve výpisu 'svn log'.
Ten výpis vypadá nějak takto:
------------------------------------------------------------------------
r39 | messa | 2010-05-16 14:58:38 +0200 (ne, 16 kvě 2010) | 1 line
nested forms
Všimněte si "1 lines" vpravo nahoře - udává počet řádek popisu.
Toto číslo vyparsujeme (regulárním výrazem) a pak už jen přečteme daný
počet řádků popisu pod tím.
Až to všechno zpracujeme, zavolá se svn diff -c <číslo revize>, tím se zobrazí
vlastní obsah (diff) daného commitu. Ještě se to prožene příkazem colordiff,
ať je to hezčí.
"""
line = pipe.readline()
if not line:
return True # True znamená konec logu
m = reHeaderLine.match(line.rstrip())
if not m:
raise Exception("Failed to parse header line %r" % line.rstrip())
rev = int(m.group(1))
author = m.group(2)
date = m.group(3)
lineCount = int(m.group(4))
line = pipe.readline().rstrip()
assert not line
msgLines = list()
for i in range(lineCount):
line = pipe.readline().rstrip()
assert not line.startswith(72 * "-")
msgLines.append(line)
line = pipe.readline().rstrip()
assert line == 72 * "-"
# vizuální oddělovač jednotlivých commitů; je to výrazné, aby byly "hranice"
# commitu jasně vidět i při rychlém scrollování
print "\\" * 78
print "/" * 78
print "r%s | %s | %s" % (rev, author, date)
print ""
print " " + "\n ".join(msgLines)
print ""
sys.stdout.flush()
p = subprocess.Popen("svn diff -c %s | colordiff" % rev, shell=True)
p.wait()
def main():
"""
Zavolání svn log a postupně volání funkce process_revision() na každou revizi
vypsanou v SVN logu.
"""
p = subprocess.Popen(["svn", "log"], stdout=subprocess.PIPE)
pipe = p.stdout
line = pipe.readline().rstrip()
assert line == 72 * "-"
while True:
if process_revision(pipe):
break
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment