A console script that allows you to easily update multiple git repositories at once

script.py 5.4 KiB

9 anni fa
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright (C) 2011-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
  4. # Released under the terms of the MIT License. See LICENSE for details.
  5. from __future__ import print_function
  6. import argparse
  7. import os
  8. import sys
  9. from colorama import init as color_init, Fore, Style
  10. from . import __version__
  11. from .config import (get_default_config_path, get_bookmarks, add_bookmarks,
  12. delete_bookmarks, list_bookmarks, clean_bookmarks)
  13. from .update import update_bookmarks, update_directories, run_command
  14. def _decode(path):
  15. """Decode the given string using the system's filesystem encoding."""
  16. if sys.version_info.major > 2:
  17. return path
  18. return path.decode(sys.getfilesystemencoding())
  19. def main():
  20. """Parse arguments and then call the appropriate function(s)."""
  21. parser = argparse.ArgumentParser(
  22. description="Easily update multiple git repositories at once.",
  23. epilog="""
  24. Both relative and absolute paths are accepted by all arguments.
  25. Direct bug reports and feature requests to
  26. https://github.com/earwig/git-repo-updater.""",
  27. add_help=False)
  28. group_u = parser.add_argument_group("updating repositories")
  29. group_b = parser.add_argument_group("bookmarking")
  30. group_a = parser.add_argument_group("advanced")
  31. group_m = parser.add_argument_group("miscellaneous")
  32. group_u.add_argument(
  33. 'directories_to_update', nargs="*", metavar="path", type=_decode,
  34. help="""update all repositories in this directory (or the directory
  35. itself, if it is a repo)""")
  36. group_u.add_argument(
  37. '-u', '--update', action="store_true", help="""update all bookmarks
  38. (default behavior when called without arguments)""")
  39. group_u.add_argument(
  40. '-c', '--current-only', action="store_true", help="""only fetch the
  41. remote tracked by the current branch instead of all remotes""")
  42. group_u.add_argument(
  43. '-f', '--fetch-only', action="store_true",
  44. help="only fetch remotes, don't try to fast-forward any branches")
  45. group_u.add_argument(
  46. '-p', '--prune', action="store_true", help="""after fetching, delete
  47. remote-tracking branches that no longer exist on their remote""")
  48. group_b.add_argument(
  49. '-a', '--add', dest="bookmarks_to_add", nargs="+", metavar="path",
  50. type=_decode, help="add directory(s) as bookmarks")
  51. group_b.add_argument(
  52. '-d', '--delete', dest="bookmarks_to_del", nargs="+", metavar="path",
  53. type=_decode,
  54. help="delete bookmark(s) (leaves actual directories alone)")
  55. group_b.add_argument(
  56. '-l', '--list', dest="list_bookmarks", action="store_true",
  57. help="list current bookmarks")
  58. group_b.add_argument(
  59. '-n', '--clean', '--cleanup', dest="clean_bookmarks",
  60. action="store_true", help="delete any bookmarks that don't exist")
  61. group_b.add_argument(
  62. '-b', '--bookmark-file', nargs="?", metavar="path", type=_decode,
  63. help="use a specific bookmark config file (default: {0})".format(
  64. get_default_config_path()))
  65. group_a.add_argument(
  66. '-e', '--exec', '--batch', dest="command", metavar="command",
  67. help="run a shell command on all repos")
  68. group_m.add_argument(
  69. '-h', '--help', action="help", help="show this help message and exit")
  70. group_m.add_argument(
  71. '-v', '--version', action="version",
  72. version="gitup " + __version__)
  73. # TODO: deprecated arguments, for removal in v1.0:
  74. parser.add_argument(
  75. '-m', '--merge', action="store_true", help=argparse.SUPPRESS)
  76. parser.add_argument(
  77. '-r', '--rebase', action="store_true", help=argparse.SUPPRESS)
  78. color_init(autoreset=True)
  79. args = parser.parse_args()
  80. update_args = args.current_only, args.fetch_only, args.prune
  81. print(Style.BRIGHT + "gitup" + Style.RESET_ALL + ": the git-repo-updater")
  82. print()
  83. # TODO: remove in v1.0
  84. if args.merge or args.rebase:
  85. print(Style.BRIGHT + Fore.YELLOW + "Warning:", "--merge and --rebase "
  86. "are deprecated. Branches are only updated if they\ntrack an "
  87. "upstream branch and can be safely fast-forwarded. Use "
  88. "--fetch-only to\navoid updating any branches.\n")
  89. if args.bookmark_file:
  90. args.bookmark_file = os.path.expanduser(args.bookmark_file)
  91. acted = False
  92. if args.bookmarks_to_add:
  93. add_bookmarks(args.bookmarks_to_add, args.bookmark_file)
  94. acted = True
  95. if args.bookmarks_to_del:
  96. delete_bookmarks(args.bookmarks_to_del, args.bookmark_file)
  97. acted = True
  98. if args.list_bookmarks:
  99. list_bookmarks(args.bookmark_file)
  100. acted = True
  101. if args.clean_bookmarks:
  102. clean_bookmarks(args.bookmark_file)
  103. acted = True
  104. if args.command:
  105. if args.directories_to_update:
  106. run_command(args.directories_to_update, args.command)
  107. if args.update or not args.directories_to_update:
  108. run_command(get_bookmarks(args.bookmark_file), args.command)
  109. else:
  110. if args.directories_to_update:
  111. update_directories(args.directories_to_update, update_args)
  112. acted = True
  113. if args.update or not acted:
  114. update_bookmarks(get_bookmarks(args.bookmark_file), update_args)
  115. def run():
  116. """Thin wrapper for main() that catches KeyboardInterrupts."""
  117. try:
  118. main()
  119. except KeyboardInterrupt:
  120. print("Stopped by user.")