git-changelog 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #!/usr/bin/env python
  2. # git-changelog
  3. #
  4. # version 2.0, by John Wiegley
  5. #
  6. # The purpose of this code is to turn "git log" output into a complete
  7. # ChangeLog, for projects who wish to begin using a ChangeLog, but haven't
  8. # been.
  9. #
  10. # This version of git-changelog depends on GitPython:
  11. # git://gitorious.org/git-python/mainline.git
  12. import time
  13. import string
  14. import sys
  15. import re
  16. import os
  17. from git import * # GitPython
  18. from subprocess import *
  19. repo = Repo(os.getcwd())
  20. ref = 'origin/master..'
  21. path = ''
  22. # Usage: git changelog [COMMITISH] [-- [PATH]]
  23. saw_dashdash = False
  24. if len(sys.argv) > 1:
  25. for arg in sys.argv[1:]:
  26. if arg == "--":
  27. saw_dashdash = True
  28. elif saw_dashdash:
  29. path = arg
  30. else:
  31. ref = arg
  32. for commit in repo.iter_commits(ref, paths=path):
  33. hash_id = commit.sha
  34. author = commit.author
  35. date = commit.committed_date
  36. log_text = commit.message.split('\n')[0]
  37. log_text_remainder = commit.message.split('\n\n')[1:]
  38. while len(log_text_remainder) > 0 and not log_text_remainder[0]:
  39. log_text_remainder = log_text_remainder[1:]
  40. log_text_remainder = string.join(log_text_remainder, '\n\t')
  41. if log_text_remainder:
  42. log_text_remainder = '\n\t' + log_text_remainder
  43. diff = commit.diff(commit.parents[0])
  44. files = []
  45. for f in diff:
  46. if not f.a_blob:
  47. p = f.b_blob.path
  48. elif not f.b_blob:
  49. p = f.a_blob.path
  50. else:
  51. continue
  52. p2 = re.sub('^' + path + '/', '', p)
  53. if p != p2:
  54. files.append(p2)
  55. fp = Popen(["fmt", "-72"], shell = True, stdin = PIPE, stdout = PIPE)
  56. if files:
  57. fp.stdin.write("\t* %s: %s" % (string.join(files, ",\n\t"), log_text))
  58. else:
  59. fp.stdin.write("\t* %s" % log_text)
  60. fp.stdin.close()
  61. log_text = fp.stdout.read()
  62. del fp
  63. print "%s %s <%s>\n" % \
  64. (time.strftime("%Y-%m-%d", time.gmtime(date)),
  65. author.name, author.email)
  66. if path:
  67. log_text = re.sub(' ' + path + '/', ' ', log_text)
  68. log_text_remainder = re.sub(' ' + path + '/', ' ', log_text_remainder)
  69. # If the log_text_remainder already begins with a *, then use that as the
  70. # changelog text.
  71. if re.match('\s+\* ', log_text_remainder):
  72. if log_text_remainder[0] == '\n':
  73. print log_text_remainder[1:]
  74. else:
  75. print log_text_remainder
  76. else:
  77. print "%s%s" % (log_text, log_text_remainder)
  78. # git-changelog ends here