gitlog2changelog.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #!/usr/bin/env python3
  2. # Copyright 2008 Marcus D. Hanwell <marcus@cryos.org>
  3. # Minor changes for NUT by Charles Lepple
  4. # Distributed under the terms of the GNU General Public License v2 or later
  5. import string, re, os
  6. from textwrap import TextWrapper
  7. import sys
  8. rev_range = ''
  9. if len(sys.argv) > 1:
  10. base = sys.argv[1]
  11. rev_range = '%s..HEAD' % base
  12. # Execute git log with the desired command line options.
  13. fin = os.popen('git log --summary --stat --no-merges --date=short %s' % rev_range, 'r')
  14. # Create a ChangeLog file in the current directory.
  15. fout = open('ChangeLog', 'w')
  16. # Set up the loop variables in order to locate the blocks we want
  17. authorFound = False
  18. dateFound = False
  19. messageFound = False
  20. filesFound = False
  21. message = ""
  22. messageNL = False
  23. files = ""
  24. prevAuthorLine = ""
  25. wrapper = TextWrapper(initial_indent="\t", subsequent_indent="\t ")
  26. # The main part of the loop
  27. for line in fin:
  28. # The commit line marks the start of a new commit object.
  29. if line.startswith('commit'):
  30. # Start all over again...
  31. authorFound = False
  32. dateFound = False
  33. messageFound = False
  34. messageNL = False
  35. message = ""
  36. filesFound = False
  37. files = ""
  38. continue
  39. # Match the author line and extract the part we want
  40. # (Don't use startswith to allow Author override inside commit message.)
  41. elif 'Author:' in line:
  42. authorList = re.split(': ', line, 1)
  43. try:
  44. author = authorList[1]
  45. author = author[0:len(author)-1]
  46. authorFound = True
  47. except:
  48. print ("Could not parse authorList = '%s'" % (line))
  49. # Match the date line
  50. elif line.startswith('Date:'):
  51. dateList = re.split(': ', line, 1)
  52. try:
  53. date = dateList[1]
  54. date = date[0:len(date)-1]
  55. dateFound = True
  56. except:
  57. print ("Could not parse dateList = '%s'" % (line))
  58. # The Fossil-IDs are ignored:
  59. elif line.startswith(' Fossil-ID:') or line.startswith(' [[SVN:'):
  60. continue
  61. # The svn-id lines are ignored
  62. elif ' git-svn-id:' in line:
  63. continue
  64. # The sign off line is ignored too
  65. elif 'Signed-off-by' in line:
  66. continue
  67. # Extract the actual commit message for this commit
  68. elif authorFound & dateFound & messageFound == False:
  69. # Find the commit message if we can
  70. if len(line) == 1:
  71. if messageNL:
  72. messageFound = True
  73. else:
  74. messageNL = True
  75. elif len(line) == 4:
  76. messageFound = True
  77. else:
  78. if len(message) == 0:
  79. message = message + line.strip()
  80. else:
  81. message = message + " " + line.strip()
  82. # If this line is hit all of the files have been stored for this commit
  83. elif re.search('files? changed', line):
  84. filesFound = True
  85. continue
  86. # Collect the files for this commit. FIXME: Still need to add +/- to files
  87. elif authorFound & dateFound & messageFound:
  88. fileList = re.split(' \| ', line, 2)
  89. if len(fileList) > 1:
  90. if len(files) > 0:
  91. files = files + ", " + fileList[0].strip()
  92. else:
  93. files = fileList[0].strip()
  94. # All of the parts of the commit have been found - write out the entry
  95. if authorFound & dateFound & messageFound & filesFound:
  96. # First the author line, only outputted if it is the first for that
  97. # author on this day
  98. authorLine = date + " " + author
  99. if len(prevAuthorLine) == 0:
  100. fout.write(authorLine + "\n\n")
  101. elif authorLine == prevAuthorLine:
  102. pass
  103. else:
  104. fout.write("\n" + authorLine + "\n\n")
  105. # Assemble the actual commit message line(s) and limit the line length
  106. # to 80 characters.
  107. commitLine = "* " + files + ": " + message
  108. # Write out the commit line
  109. fout.write(wrapper.fill(commitLine) + "\n")
  110. #Now reset all the variables ready for a new commit block.
  111. authorFound = False
  112. dateFound = False
  113. messageFound = False
  114. messageNL = False
  115. message = ""
  116. filesFound = False
  117. files = ""
  118. prevAuthorLine = authorLine
  119. # Close the input and output lines now that we are finished.
  120. fin.close()
  121. fout.close()