gitlog2changelog.py 4.3 KB

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