add.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/env python3
  2. import tempfile
  3. import pathlib
  4. import shutil
  5. import sys
  6. import re
  7. import common
  8. def print_usage_and_exit():
  9. print("Usage 1: <path> <repo url> <branch> [subdir]")
  10. print("Usage 2: <path> <repo url>/tree/<branch>[/subdir]")
  11. sys.exit(1)
  12. if __name__ == "__main__":
  13. common.check_workdir_state()
  14. if len(sys.argv) < 3 or not sys.argv[1] or not sys.argv[2]:
  15. print_usage_and_exit()
  16. if len(sys.argv) == 3 and "/tree/" not in sys.argv[2]:
  17. print_usage_and_exit()
  18. path = sys.argv[1]
  19. repo = sys.argv[2].strip("/")
  20. if len(sys.argv) == 3:
  21. res = re.match(r"(https?://[^/]+/[^/]+/[^/]+)/tree/([^/]+)/?(.*)", repo)
  22. if not res:
  23. print(f"Could not parse repo URL: {repo}")
  24. sys.exit(1)
  25. repo = res.group(1)
  26. branch = res.group(2)
  27. subdir = res.group(3).strip("/")
  28. else:
  29. branch = sys.argv[3]
  30. if len(sys.argv) > 4:
  31. subdir = sys.argv[4].strip("/")
  32. else:
  33. subdir = ""
  34. gitsubtree = common.REPO_ROOT / path / ".gitsubtree"
  35. prevremotedir = None
  36. if gitsubtree.is_file():
  37. print("Subtree already exists, adding new remote to it.")
  38. prevremotedir = pathlib.Path(tempfile.mkdtemp(prefix="gitsubtree"))
  39. # To use 2 remotes for subtree we need to remove current one, add new one, then merge
  40. shutil.move(path, prevremotedir / path)
  41. common.git("add", path)
  42. common.git("commit", "-m", f"Add new remote for {path}")
  43. if subdir == "":
  44. subdir = "/"
  45. common.git(
  46. "subtree",
  47. "add",
  48. "-P",
  49. path,
  50. repo,
  51. branch,
  52. "-m",
  53. f"Add {path} from {repo}",
  54. )
  55. commit = None
  56. else:
  57. commit = common.subdir_split_helper(path, repo, branch, subdir, "add")
  58. if prevremotedir:
  59. shutil.rmtree(path)
  60. shutil.move(prevremotedir / path, path)
  61. prevremotedir.rmdir()
  62. line = f"{repo} {branch} {subdir}" + (f" {commit}" if commit else "")
  63. if gitsubtree.is_file():
  64. # Add new remote at the top
  65. lines = gitsubtree.read_text().splitlines()
  66. lines.insert(0, line)
  67. else:
  68. lines = [line]
  69. gitsubtree.write_text("\n".join(lines) + "\n")
  70. common.git("add", str(gitsubtree.relative_to(common.REPO_ROOT)))
  71. common.git("commit", "--amend", "--no-edit")
  72. if prevremotedir:
  73. prevremotedir = None
  74. print(
  75. "Added new remote for existing subtree, you must resolve conflicts manually..."
  76. )