lazygit_modify_commit_date.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #!/usr/bin/env python3
  2. from logging import NOTSET, basicConfig, debug
  3. from subprocess import check_output
  4. from sys import argv
  5. from re import sub, MULTILINE
  6. def run(args: list[str], env: dict):
  7. return check_output(args, env=env)
  8. if __name__ == "__main__":
  9. basicConfig(level=NOTSET)
  10. debug(f"Called with parameters {argv}")
  11. if argv[1] == "commit":
  12. _, _, form_commit, form_following, form_timestamp = tuple(argv)
  13. if form_following == "following":
  14. is_form_root = not check_output(
  15. ["git", "log", "-1", "--format=%P", form_commit]
  16. ).strip()
  17. rev_list_args = ["git", "rev-list", "HEAD"] if is_form_root else ["git", "rev-list", form_commit + "^..HEAD"]
  18. commits = (
  19. commit
  20. for commit in check_output(rev_list_args)
  21. .decode("utf-8")
  22. .split("\n")
  23. if len(commit) > 1
  24. )
  25. else:
  26. commits = [form_commit]
  27. for commit in commits:
  28. previous_data = [
  29. run(["git", "log", "-1", f'--pretty="%{attribute}"', commit], {})
  30. for attribute in ["an", "ae", "cn", "ce"]
  31. ]
  32. author_name, author_email, committer_name, committer_email = tuple(
  33. previous_data
  34. )
  35. env = {
  36. "GIT_SEQUENCE_EDITOR": f"/usr/bin/env python3 {__file__}",
  37. "GIT_COMMITTER_DATE": form_timestamp,
  38. "GIT_AUTHOR_NAME": author_name,
  39. "GIT_AUTHOR_EMAIL": author_email,
  40. "GIT_COMMITTER_NAME": committer_name,
  41. "GIT_COMMITTER_EMAIL": committer_email,
  42. }
  43. is_root = not run(
  44. ["git", "log", "-1", "--format=%P", commit], {}
  45. ).strip()
  46. run(
  47. [
  48. "git",
  49. "rebase",
  50. "--interactive",
  51. "--autostash",
  52. "--keep-empty",
  53. "--no-autosquash",
  54. "--rebase-merges",
  55. ]
  56. + (["--root"] if is_root else [f"{commit}~"]),
  57. env,
  58. )
  59. run(
  60. [
  61. "git",
  62. "commit",
  63. "--allow-empty",
  64. "--only",
  65. "--no-edit",
  66. "--amend",
  67. "--no-verify",
  68. f'--date="{form_timestamp}"',
  69. ],
  70. env,
  71. )
  72. run(
  73. [
  74. "git",
  75. "rebase",
  76. "--continue",
  77. ],
  78. env,
  79. )
  80. else:
  81. path = argv[-1]
  82. file = open(path, "r")
  83. content = sub("^pick ", "edit ", file.read(), 1, flags=MULTILINE)
  84. file.close()
  85. file = open(path, "w")
  86. file.write(content)
  87. file.close()