|
@@ -29,11 +29,9 @@ a way to test Dulwich.
|
|
|
"""
|
|
|
|
|
|
import argparse
|
|
|
-import optparse
|
|
|
import os
|
|
|
import signal
|
|
|
import sys
|
|
|
-from getopt import getopt
|
|
|
from pathlib import Path
|
|
|
from typing import TYPE_CHECKING, ClassVar, Optional
|
|
|
|
|
@@ -47,8 +45,7 @@ from .pack import Pack, sha_to_hex
|
|
|
from .repo import Repo
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
- from .objects import ObjectID
|
|
|
- from .refs import Ref
|
|
|
+ pass
|
|
|
|
|
|
|
|
|
def signal_int(signal, frame) -> None:
|
|
@@ -88,27 +85,37 @@ class cmd_archive(Command):
|
|
|
write_error=sys.stderr.write,
|
|
|
)
|
|
|
else:
|
|
|
+ # Use buffer if available (for binary output), otherwise use stdout
|
|
|
+ outstream = getattr(sys.stdout, "buffer", sys.stdout)
|
|
|
porcelain.archive(
|
|
|
- ".", args.committish, outstream=sys.stdout.buffer, errstream=sys.stderr
|
|
|
+ ".", args.committish, outstream=outstream, errstream=sys.stderr
|
|
|
)
|
|
|
|
|
|
|
|
|
class cmd_add(Command):
|
|
|
def run(self, argv) -> None:
|
|
|
parser = argparse.ArgumentParser()
|
|
|
- parser.add_argument("path", type=Path, nargs="+")
|
|
|
+ parser.add_argument("path", nargs="+")
|
|
|
args = parser.parse_args(argv)
|
|
|
|
|
|
- porcelain.add(".", paths=args.path)
|
|
|
+ # Convert '.' to None to add all files
|
|
|
+ paths = args.path
|
|
|
+ if len(paths) == 1 and paths[0] == ".":
|
|
|
+ paths = None
|
|
|
+
|
|
|
+ porcelain.add(".", paths=paths)
|
|
|
|
|
|
|
|
|
class cmd_rm(Command):
|
|
|
def run(self, argv) -> None:
|
|
|
parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument(
|
|
|
+ "--cached", action="store_true", help="Remove from index only"
|
|
|
+ )
|
|
|
parser.add_argument("path", type=Path, nargs="+")
|
|
|
args = parser.parse_args(argv)
|
|
|
|
|
|
- porcelain.rm(".", paths=args.path)
|
|
|
+ porcelain.remove(".", paths=args.path, cached=args.cached)
|
|
|
|
|
|
|
|
|
class cmd_fetch_pack(Command):
|
|
@@ -124,9 +131,7 @@ class cmd_fetch_pack(Command):
|
|
|
determine_wants = r.object_store.determine_wants_all
|
|
|
else:
|
|
|
|
|
|
- def determine_wants(
|
|
|
- refs: dict[Ref, ObjectID], depth: Optional[int] = None
|
|
|
- ) -> list[ObjectID]:
|
|
|
+ def determine_wants(refs, depth: Optional[int] = None):
|
|
|
return [y.encode("utf-8") for y in args.refs if y not in r.object_store]
|
|
|
|
|
|
client.fetch(path, r, determine_wants)
|
|
@@ -134,9 +139,10 @@ class cmd_fetch_pack(Command):
|
|
|
|
|
|
class cmd_fetch(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", [])
|
|
|
- dict(opts)
|
|
|
- client, path = get_transport_and_path(args.pop(0))
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("location", help="Remote location to fetch from")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+ client, path = get_transport_and_path(args.location)
|
|
|
r = Repo(".")
|
|
|
|
|
|
def progress(msg: bytes) -> None:
|
|
@@ -159,47 +165,49 @@ class cmd_for_each_ref(Command):
|
|
|
|
|
|
class cmd_fsck(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", [])
|
|
|
- dict(opts)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.parse_args(args)
|
|
|
for obj, msg in porcelain.fsck("."):
|
|
|
print(f"{obj}: {msg}")
|
|
|
|
|
|
|
|
|
class cmd_log(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- parser.add_option(
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument(
|
|
|
"--reverse",
|
|
|
- dest="reverse",
|
|
|
action="store_true",
|
|
|
help="Reverse order in which entries are printed",
|
|
|
)
|
|
|
- parser.add_option(
|
|
|
+ parser.add_argument(
|
|
|
"--name-status",
|
|
|
- dest="name_status",
|
|
|
action="store_true",
|
|
|
help="Print name/status for each changed file",
|
|
|
)
|
|
|
- options, args = parser.parse_args(args)
|
|
|
+ parser.add_argument("paths", nargs="*", help="Paths to show log for")
|
|
|
+ args = parser.parse_args(args)
|
|
|
|
|
|
porcelain.log(
|
|
|
".",
|
|
|
- paths=args,
|
|
|
- reverse=options.reverse,
|
|
|
- name_status=options.name_status,
|
|
|
+ paths=args.paths,
|
|
|
+ reverse=args.reverse,
|
|
|
+ name_status=args.name_status,
|
|
|
outstream=sys.stdout,
|
|
|
)
|
|
|
|
|
|
|
|
|
class cmd_diff(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", [])
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument(
|
|
|
+ "commit", nargs="?", default="HEAD", help="Commit to show diff for"
|
|
|
+ )
|
|
|
+ args = parser.parse_args(args)
|
|
|
|
|
|
r = Repo(".")
|
|
|
- if args == []:
|
|
|
- commit_id = b"HEAD"
|
|
|
- else:
|
|
|
- commit_id = args[0]
|
|
|
+ commit_id = (
|
|
|
+ args.commit.encode() if isinstance(args.commit, str) else args.commit
|
|
|
+ )
|
|
|
commit = parse_commit(r, commit_id)
|
|
|
parent_commit = r[commit.parents[0]]
|
|
|
porcelain.diff_tree(
|
|
@@ -209,13 +217,11 @@ class cmd_diff(Command):
|
|
|
|
|
|
class cmd_dump_pack(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", [])
|
|
|
-
|
|
|
- if args == []:
|
|
|
- print("Usage: dulwich dump-pack FILENAME")
|
|
|
- sys.exit(1)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("filename", help="Pack file to dump")
|
|
|
+ args = parser.parse_args(args)
|
|
|
|
|
|
- basename, _ = os.path.splitext(args[0])
|
|
|
+ basename, _ = os.path.splitext(args.filename)
|
|
|
x = Pack(basename)
|
|
|
print(f"Object names checksum: {x.name()}")
|
|
|
print(f"Checksum: {sha_to_hex(x.get_stored_checksum())}")
|
|
@@ -232,14 +238,11 @@ class cmd_dump_pack(Command):
|
|
|
|
|
|
class cmd_dump_index(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", [])
|
|
|
-
|
|
|
- if args == []:
|
|
|
- print("Usage: dulwich dump-index FILENAME")
|
|
|
- sys.exit(1)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("filename", help="Index file to dump")
|
|
|
+ args = parser.parse_args(args)
|
|
|
|
|
|
- filename = args[0]
|
|
|
- idx = Index(filename)
|
|
|
+ idx = Index(args.filename)
|
|
|
|
|
|
for o in idx:
|
|
|
print(o, idx[o])
|
|
@@ -247,76 +250,64 @@ class cmd_dump_index(Command):
|
|
|
|
|
|
class cmd_init(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", ["bare"])
|
|
|
- kwopts = dict(opts)
|
|
|
-
|
|
|
- if args == []:
|
|
|
- path = os.getcwd()
|
|
|
- else:
|
|
|
- path = args[0]
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument(
|
|
|
+ "--bare", action="store_true", help="Create a bare repository"
|
|
|
+ )
|
|
|
+ parser.add_argument(
|
|
|
+ "path", nargs="?", default=os.getcwd(), help="Repository path"
|
|
|
+ )
|
|
|
+ args = parser.parse_args(args)
|
|
|
|
|
|
- porcelain.init(path, bare=("--bare" in kwopts))
|
|
|
+ porcelain.init(args.path, bare=args.bare)
|
|
|
|
|
|
|
|
|
class cmd_clone(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- parser.add_option(
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument(
|
|
|
"--bare",
|
|
|
- dest="bare",
|
|
|
help="Whether to create a bare repository.",
|
|
|
action="store_true",
|
|
|
)
|
|
|
- parser.add_option(
|
|
|
- "--depth", dest="depth", type=int, help="Depth at which to fetch"
|
|
|
- )
|
|
|
- parser.add_option(
|
|
|
+ parser.add_argument("--depth", type=int, help="Depth at which to fetch")
|
|
|
+ parser.add_argument(
|
|
|
"-b",
|
|
|
"--branch",
|
|
|
- dest="branch",
|
|
|
type=str,
|
|
|
- help=("Check out branch instead of branch pointed to by remote HEAD"),
|
|
|
+ help="Check out branch instead of branch pointed to by remote HEAD",
|
|
|
)
|
|
|
- parser.add_option(
|
|
|
+ parser.add_argument(
|
|
|
"--refspec",
|
|
|
- dest="refspec",
|
|
|
type=str,
|
|
|
help="References to fetch",
|
|
|
action="append",
|
|
|
)
|
|
|
- parser.add_option(
|
|
|
+ parser.add_argument(
|
|
|
"--filter",
|
|
|
dest="filter_spec",
|
|
|
type=str,
|
|
|
help="git-rev-list-style object filter",
|
|
|
)
|
|
|
- parser.add_option(
|
|
|
+ parser.add_argument(
|
|
|
"--protocol",
|
|
|
type=int,
|
|
|
help="Git protocol version to use",
|
|
|
)
|
|
|
- options, args = parser.parse_args(args)
|
|
|
-
|
|
|
- if args == []:
|
|
|
- print("usage: dulwich clone host:path [PATH]")
|
|
|
- sys.exit(1)
|
|
|
-
|
|
|
- source = args.pop(0)
|
|
|
- if len(args) > 0:
|
|
|
- target = args.pop(0)
|
|
|
- else:
|
|
|
- target = None
|
|
|
+ parser.add_argument("source", help="Repository to clone from")
|
|
|
+ parser.add_argument("target", nargs="?", help="Directory to clone into")
|
|
|
+ args = parser.parse_args(args)
|
|
|
|
|
|
try:
|
|
|
porcelain.clone(
|
|
|
- source,
|
|
|
- target,
|
|
|
- bare=options.bare,
|
|
|
- depth=options.depth,
|
|
|
- branch=options.branch,
|
|
|
- refspec=options.refspec,
|
|
|
- filter_spec=options.filter_spec,
|
|
|
- protocol_version=options.protocol,
|
|
|
+ args.source,
|
|
|
+ args.target,
|
|
|
+ bare=args.bare,
|
|
|
+ depth=args.depth,
|
|
|
+ branch=args.branch,
|
|
|
+ refspec=args.refspec,
|
|
|
+ filter_spec=args.filter_spec,
|
|
|
+ protocol_version=args.protocol,
|
|
|
)
|
|
|
except GitProtocolError as e:
|
|
|
print(f"{e}")
|
|
@@ -324,19 +315,19 @@ class cmd_clone(Command):
|
|
|
|
|
|
class cmd_commit(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", ["message="])
|
|
|
- kwopts = dict(opts)
|
|
|
- porcelain.commit(".", message=kwopts["--message"])
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("--message", "-m", required=True, help="Commit message")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+ porcelain.commit(".", message=args.message)
|
|
|
|
|
|
|
|
|
class cmd_commit_tree(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", ["message="])
|
|
|
- if args == []:
|
|
|
- print("usage: dulwich commit-tree tree")
|
|
|
- sys.exit(1)
|
|
|
- kwopts = dict(opts)
|
|
|
- porcelain.commit_tree(".", tree=args[0], message=kwopts["--message"])
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("--message", "-m", required=True, help="Commit message")
|
|
|
+ parser.add_argument("tree", help="Tree SHA to commit")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+ porcelain.commit_tree(".", tree=args.tree, message=args.message)
|
|
|
|
|
|
|
|
|
class cmd_update_server_info(Command):
|
|
@@ -346,13 +337,32 @@ class cmd_update_server_info(Command):
|
|
|
|
|
|
class cmd_symbolic_ref(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", ["ref-name", "force"])
|
|
|
- if not args:
|
|
|
- print("Usage: dulwich symbolic-ref REF_NAME [--force]")
|
|
|
- sys.exit(1)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("name", help="Symbolic reference name")
|
|
|
+ parser.add_argument("ref", nargs="?", help="Target reference")
|
|
|
+ parser.add_argument("--force", action="store_true", help="Force update")
|
|
|
+ args = parser.parse_args(args)
|
|
|
|
|
|
- ref_name = args.pop(0)
|
|
|
- porcelain.symbolic_ref(".", ref_name=ref_name, force="--force" in args)
|
|
|
+ # If ref is provided, we're setting; otherwise we're reading
|
|
|
+ if args.ref:
|
|
|
+ # Set symbolic reference
|
|
|
+ from .repo import Repo
|
|
|
+
|
|
|
+ with Repo(".") as repo:
|
|
|
+ repo.refs.set_symbolic_ref(args.name.encode(), args.ref.encode())
|
|
|
+ else:
|
|
|
+ # Read symbolic reference
|
|
|
+ from .repo import Repo
|
|
|
+
|
|
|
+ with Repo(".") as repo:
|
|
|
+ try:
|
|
|
+ target = repo.refs.read_ref(args.name.encode())
|
|
|
+ if target.startswith(b"ref: "):
|
|
|
+ print(target[5:].decode())
|
|
|
+ else:
|
|
|
+ print(target.decode())
|
|
|
+ except KeyError:
|
|
|
+ print(f"fatal: ref '{args.name}' is not a symbolic ref")
|
|
|
|
|
|
|
|
|
class cmd_pack_refs(Command):
|
|
@@ -372,68 +382,81 @@ class cmd_show(Command):
|
|
|
parser = argparse.ArgumentParser()
|
|
|
parser.add_argument("objectish", type=str, nargs="*")
|
|
|
args = parser.parse_args(argv)
|
|
|
- porcelain.show(".", args.objectish or None)
|
|
|
+ porcelain.show(".", args.objectish or None, outstream=sys.stdout)
|
|
|
|
|
|
|
|
|
class cmd_diff_tree(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", [])
|
|
|
- if len(args) < 2:
|
|
|
- print("Usage: dulwich diff-tree OLD-TREE NEW-TREE")
|
|
|
- sys.exit(1)
|
|
|
- porcelain.diff_tree(".", args[0], args[1])
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("old_tree", help="Old tree SHA")
|
|
|
+ parser.add_argument("new_tree", help="New tree SHA")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+ porcelain.diff_tree(".", args.old_tree, args.new_tree)
|
|
|
|
|
|
|
|
|
class cmd_rev_list(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", [])
|
|
|
- if len(args) < 1:
|
|
|
- print("Usage: dulwich rev-list COMMITID...")
|
|
|
- sys.exit(1)
|
|
|
- porcelain.rev_list(".", args)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("commits", nargs="+", help="Commit IDs to list")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+ porcelain.rev_list(".", args.commits)
|
|
|
|
|
|
|
|
|
class cmd_tag(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- parser.add_option(
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument(
|
|
|
"-a",
|
|
|
"--annotated",
|
|
|
help="Create an annotated tag.",
|
|
|
action="store_true",
|
|
|
)
|
|
|
- parser.add_option(
|
|
|
+ parser.add_argument(
|
|
|
"-s", "--sign", help="Sign the annotated tag.", action="store_true"
|
|
|
)
|
|
|
- options, args = parser.parse_args(args)
|
|
|
+ parser.add_argument("tag_name", help="Name of the tag to create")
|
|
|
+ args = parser.parse_args(args)
|
|
|
porcelain.tag_create(
|
|
|
- ".", args[0], annotated=options.annotated, sign=options.sign
|
|
|
+ ".", args.tag_name, annotated=args.annotated, sign=args.sign
|
|
|
)
|
|
|
|
|
|
|
|
|
class cmd_repack(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", [])
|
|
|
- dict(opts)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.parse_args(args)
|
|
|
porcelain.repack(".")
|
|
|
|
|
|
|
|
|
class cmd_reset(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", ["hard", "soft", "mixed"])
|
|
|
- kwopts = dict(opts)
|
|
|
- mode = ""
|
|
|
- if "--hard" in kwopts:
|
|
|
- mode = "hard"
|
|
|
- elif "--soft" in kwopts:
|
|
|
- mode = "soft"
|
|
|
- elif "--mixed" in kwopts:
|
|
|
- mode = "mixed"
|
|
|
- try:
|
|
|
- treeish = args.pop(0)
|
|
|
- except IndexError:
|
|
|
- treeish = None
|
|
|
- porcelain.reset(".", mode=mode, treeish=treeish)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ mode_group = parser.add_mutually_exclusive_group()
|
|
|
+ mode_group.add_argument(
|
|
|
+ "--hard", action="store_true", help="Reset working tree and index"
|
|
|
+ )
|
|
|
+ mode_group.add_argument("--soft", action="store_true", help="Reset only HEAD")
|
|
|
+ mode_group.add_argument(
|
|
|
+ "--mixed", action="store_true", help="Reset HEAD and index"
|
|
|
+ )
|
|
|
+ parser.add_argument("treeish", nargs="?", help="Commit/tree to reset to")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+
|
|
|
+ if args.hard:
|
|
|
+ porcelain.reset(".", mode="hard", treeish=args.treeish)
|
|
|
+ elif args.soft:
|
|
|
+ # Soft reset: only change HEAD
|
|
|
+ if args.treeish:
|
|
|
+ from .repo import Repo
|
|
|
+
|
|
|
+ with Repo(".") as repo:
|
|
|
+ repo.refs[b"HEAD"] = args.treeish.encode()
|
|
|
+ elif args.mixed:
|
|
|
+ # Mixed reset is not implemented yet
|
|
|
+ raise NotImplementedError("Mixed reset not yet implemented")
|
|
|
+ else:
|
|
|
+ # Default to mixed behavior (not implemented)
|
|
|
+ raise NotImplementedError("Mixed reset not yet implemented")
|
|
|
|
|
|
|
|
|
class cmd_daemon(Command):
|
|
@@ -442,102 +465,85 @@ class cmd_daemon(Command):
|
|
|
|
|
|
from .protocol import TCP_GIT_PORT
|
|
|
|
|
|
- parser = optparse.OptionParser()
|
|
|
- parser.add_option(
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument(
|
|
|
"-l",
|
|
|
"--listen_address",
|
|
|
- dest="listen_address",
|
|
|
default="localhost",
|
|
|
help="Binding IP address.",
|
|
|
)
|
|
|
- parser.add_option(
|
|
|
+ parser.add_argument(
|
|
|
"-p",
|
|
|
"--port",
|
|
|
- dest="port",
|
|
|
type=int,
|
|
|
default=TCP_GIT_PORT,
|
|
|
help="Binding TCP port.",
|
|
|
)
|
|
|
- options, args = parser.parse_args(args)
|
|
|
+ parser.add_argument(
|
|
|
+ "gitdir", nargs="?", default=".", help="Git directory to serve"
|
|
|
+ )
|
|
|
+ args = parser.parse_args(args)
|
|
|
|
|
|
log_utils.default_logging_config()
|
|
|
- if len(args) >= 1:
|
|
|
- gitdir = args[0]
|
|
|
- else:
|
|
|
- gitdir = "."
|
|
|
-
|
|
|
- porcelain.daemon(gitdir, address=options.listen_address, port=options.port)
|
|
|
+ porcelain.daemon(args.gitdir, address=args.listen_address, port=args.port)
|
|
|
|
|
|
|
|
|
class cmd_web_daemon(Command):
|
|
|
def run(self, args) -> None:
|
|
|
from dulwich import log_utils
|
|
|
|
|
|
- parser = optparse.OptionParser()
|
|
|
- parser.add_option(
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument(
|
|
|
"-l",
|
|
|
"--listen_address",
|
|
|
- dest="listen_address",
|
|
|
default="",
|
|
|
help="Binding IP address.",
|
|
|
)
|
|
|
- parser.add_option(
|
|
|
+ parser.add_argument(
|
|
|
"-p",
|
|
|
"--port",
|
|
|
- dest="port",
|
|
|
type=int,
|
|
|
default=8000,
|
|
|
help="Binding TCP port.",
|
|
|
)
|
|
|
- options, args = parser.parse_args(args)
|
|
|
+ parser.add_argument(
|
|
|
+ "gitdir", nargs="?", default=".", help="Git directory to serve"
|
|
|
+ )
|
|
|
+ args = parser.parse_args(args)
|
|
|
|
|
|
log_utils.default_logging_config()
|
|
|
- if len(args) >= 1:
|
|
|
- gitdir = args[0]
|
|
|
- else:
|
|
|
- gitdir = "."
|
|
|
-
|
|
|
- porcelain.web_daemon(gitdir, address=options.listen_address, port=options.port)
|
|
|
+ porcelain.web_daemon(args.gitdir, address=args.listen_address, port=args.port)
|
|
|
|
|
|
|
|
|
class cmd_write_tree(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- options, args = parser.parse_args(args)
|
|
|
- sys.stdout.write("{}\n".format(porcelain.write_tree(".")))
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.parse_args(args)
|
|
|
+ sys.stdout.write("{}\n".format(porcelain.write_tree(".").decode()))
|
|
|
|
|
|
|
|
|
class cmd_receive_pack(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- options, args = parser.parse_args(args)
|
|
|
- if len(args) >= 1:
|
|
|
- gitdir = args[0]
|
|
|
- else:
|
|
|
- gitdir = "."
|
|
|
- porcelain.receive_pack(gitdir)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("gitdir", nargs="?", default=".", help="Git directory")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+ porcelain.receive_pack(args.gitdir)
|
|
|
|
|
|
|
|
|
class cmd_upload_pack(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- options, args = parser.parse_args(args)
|
|
|
- if len(args) >= 1:
|
|
|
- gitdir = args[0]
|
|
|
- else:
|
|
|
- gitdir = "."
|
|
|
- porcelain.upload_pack(gitdir)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("gitdir", nargs="?", default=".", help="Git directory")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+ porcelain.upload_pack(args.gitdir)
|
|
|
|
|
|
|
|
|
class cmd_status(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- options, args = parser.parse_args(args)
|
|
|
- if len(args) >= 1:
|
|
|
- gitdir = args[0]
|
|
|
- else:
|
|
|
- gitdir = "."
|
|
|
- status = porcelain.status(gitdir)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("gitdir", nargs="?", default=".", help="Git directory")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+ status = porcelain.status(args.gitdir)
|
|
|
if any(names for (kind, names) in status.staged.items()):
|
|
|
sys.stdout.write("Changes to be committed:\n\n")
|
|
|
for kind, names in status.staged.items():
|
|
@@ -560,62 +566,66 @@ class cmd_status(Command):
|
|
|
|
|
|
class cmd_ls_remote(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- opts, args = getopt(args, "", [])
|
|
|
- if len(args) < 1:
|
|
|
- print("Usage: dulwich ls-remote URL")
|
|
|
- sys.exit(1)
|
|
|
- refs = porcelain.ls_remote(args[0])
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("url", help="Remote URL to list references from")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+ refs = porcelain.ls_remote(args.url)
|
|
|
for ref in sorted(refs):
|
|
|
sys.stdout.write(f"{ref}\t{refs[ref]}\n")
|
|
|
|
|
|
|
|
|
class cmd_ls_tree(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- parser.add_option(
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument(
|
|
|
"-r",
|
|
|
"--recursive",
|
|
|
action="store_true",
|
|
|
help="Recursively list tree contents.",
|
|
|
)
|
|
|
- parser.add_option("--name-only", action="store_true", help="Only display name.")
|
|
|
- options, args = parser.parse_args(args)
|
|
|
- try:
|
|
|
- treeish = args.pop(0)
|
|
|
- except IndexError:
|
|
|
- treeish = None
|
|
|
+ parser.add_argument(
|
|
|
+ "--name-only", action="store_true", help="Only display name."
|
|
|
+ )
|
|
|
+ parser.add_argument("treeish", nargs="?", help="Tree-ish to list")
|
|
|
+ args = parser.parse_args(args)
|
|
|
porcelain.ls_tree(
|
|
|
".",
|
|
|
- treeish,
|
|
|
+ args.treeish,
|
|
|
outstream=sys.stdout,
|
|
|
- recursive=options.recursive,
|
|
|
- name_only=options.name_only,
|
|
|
+ recursive=args.recursive,
|
|
|
+ name_only=args.name_only,
|
|
|
)
|
|
|
|
|
|
|
|
|
class cmd_pack_objects(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- deltify = False
|
|
|
- reuse_deltas = True
|
|
|
- opts, args = getopt(args, "", ["stdout", "deltify", "no-reuse-deltas"])
|
|
|
- kwopts = dict(opts)
|
|
|
- if len(args) < 1 and "--stdout" not in kwopts.keys():
|
|
|
- print("Usage: dulwich pack-objects basename")
|
|
|
- sys.exit(1)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument(
|
|
|
+ "--stdout", action="store_true", help="Write pack to stdout"
|
|
|
+ )
|
|
|
+ parser.add_argument("--deltify", action="store_true", help="Create deltas")
|
|
|
+ parser.add_argument(
|
|
|
+ "--no-reuse-deltas", action="store_true", help="Don't reuse existing deltas"
|
|
|
+ )
|
|
|
+ parser.add_argument("basename", nargs="?", help="Base name for pack files")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+
|
|
|
+ if not args.stdout and not args.basename:
|
|
|
+ parser.error("basename required when not using --stdout")
|
|
|
+
|
|
|
object_ids = [line.strip() for line in sys.stdin.readlines()]
|
|
|
- if "--deltify" in kwopts.keys():
|
|
|
- deltify = True
|
|
|
- if "--no-reuse-deltas" in kwopts.keys():
|
|
|
- reuse_deltas = False
|
|
|
- if "--stdout" in kwopts.keys():
|
|
|
+ deltify = args.deltify
|
|
|
+ reuse_deltas = not args.no_reuse_deltas
|
|
|
+
|
|
|
+ if args.stdout:
|
|
|
packf = getattr(sys.stdout, "buffer", sys.stdout)
|
|
|
idxf = None
|
|
|
close = []
|
|
|
else:
|
|
|
- basename = args[0]
|
|
|
- packf = open(basename + ".pack", "wb")
|
|
|
- idxf = open(basename + ".idx", "wb")
|
|
|
+ packf = open(args.basename + ".pack", "wb")
|
|
|
+ idxf = open(args.basename + ".idx", "wb")
|
|
|
close = [packf, idxf]
|
|
|
+
|
|
|
porcelain.pack_objects(
|
|
|
".", object_ids, packf, idxf, deltify=deltify, reuse_deltas=reuse_deltas
|
|
|
)
|
|
@@ -660,9 +670,11 @@ class cmd_push(Command):
|
|
|
|
|
|
class cmd_remote_add(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- options, args = parser.parse_args(args)
|
|
|
- porcelain.remote_add(".", args[0], args[1])
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("name", help="Name of the remote")
|
|
|
+ parser.add_argument("url", help="URL of the remote")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+ porcelain.remote_add(".", args.name, args.url)
|
|
|
|
|
|
|
|
|
class SuperCommand(Command):
|
|
@@ -670,11 +682,16 @@ class SuperCommand(Command):
|
|
|
default_command: ClassVar[Optional[type[Command]]] = None
|
|
|
|
|
|
def run(self, args):
|
|
|
- if not args and not self.default_command:
|
|
|
- print(
|
|
|
- "Supported subcommands: {}".format(", ".join(self.subcommands.keys()))
|
|
|
- )
|
|
|
- return False
|
|
|
+ if not args:
|
|
|
+ if self.default_command:
|
|
|
+ return self.default_command().run(args)
|
|
|
+ else:
|
|
|
+ print(
|
|
|
+ "Supported subcommands: {}".format(
|
|
|
+ ", ".join(self.subcommands.keys())
|
|
|
+ )
|
|
|
+ )
|
|
|
+ return False
|
|
|
cmd = args[0]
|
|
|
try:
|
|
|
cmd_kls = self.subcommands[cmd]
|
|
@@ -708,17 +725,19 @@ class cmd_submodule_init(Command):
|
|
|
class cmd_submodule(SuperCommand):
|
|
|
subcommands: ClassVar[dict[str, type[Command]]] = {
|
|
|
"init": cmd_submodule_init,
|
|
|
+ "list": cmd_submodule_list,
|
|
|
}
|
|
|
|
|
|
- default_command = cmd_submodule_init
|
|
|
+ default_command = cmd_submodule_list
|
|
|
|
|
|
|
|
|
class cmd_check_ignore(Command):
|
|
|
def run(self, args):
|
|
|
- parser = optparse.OptionParser()
|
|
|
- options, args = parser.parse_args(args)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("paths", nargs="+", help="Paths to check")
|
|
|
+ args = parser.parse_args(args)
|
|
|
ret = 1
|
|
|
- for path in porcelain.check_ignore(".", args):
|
|
|
+ for path in porcelain.check_ignore(".", args.paths):
|
|
|
print(path)
|
|
|
ret = 0
|
|
|
return ret
|
|
@@ -726,10 +745,11 @@ class cmd_check_ignore(Command):
|
|
|
|
|
|
class cmd_check_mailmap(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- options, args = parser.parse_args(args)
|
|
|
- for arg in args:
|
|
|
- canonical_identity = porcelain.check_mailmap(".", arg)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument("identities", nargs="+", help="Identities to check")
|
|
|
+ args = parser.parse_args(args)
|
|
|
+ for identity in args.identities:
|
|
|
+ canonical_identity = porcelain.check_mailmap(".", identity)
|
|
|
print(canonical_identity)
|
|
|
|
|
|
|
|
@@ -798,24 +818,24 @@ class cmd_checkout(Command):
|
|
|
|
|
|
class cmd_stash_list(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- options, args = parser.parse_args(args)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.parse_args(args)
|
|
|
for i, entry in porcelain.stash_list("."):
|
|
|
print("stash@{{{}}}: {}".format(i, entry.message.rstrip("\n")))
|
|
|
|
|
|
|
|
|
class cmd_stash_push(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- options, args = parser.parse_args(args)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.parse_args(args)
|
|
|
porcelain.stash_push(".")
|
|
|
print("Saved working directory and index state")
|
|
|
|
|
|
|
|
|
class cmd_stash_pop(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- options, args = parser.parse_args(args)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.parse_args(args)
|
|
|
porcelain.stash_pop(".")
|
|
|
print("Restored working directory and index state")
|
|
|
|
|
@@ -830,16 +850,16 @@ class cmd_stash(SuperCommand):
|
|
|
|
|
|
class cmd_ls_files(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- options, args = parser.parse_args(args)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.parse_args(args)
|
|
|
for name in porcelain.ls_files("."):
|
|
|
print(name)
|
|
|
|
|
|
|
|
|
class cmd_describe(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- options, args = parser.parse_args(args)
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.parse_args(args)
|
|
|
print(porcelain.describe("."))
|
|
|
|
|
|
|
|
@@ -888,17 +908,16 @@ class cmd_merge(Command):
|
|
|
|
|
|
class cmd_help(Command):
|
|
|
def run(self, args) -> None:
|
|
|
- parser = optparse.OptionParser()
|
|
|
- parser.add_option(
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
+ parser.add_argument(
|
|
|
"-a",
|
|
|
"--all",
|
|
|
- dest="all",
|
|
|
action="store_true",
|
|
|
help="List all commands.",
|
|
|
)
|
|
|
- options, args = parser.parse_args(args)
|
|
|
+ args = parser.parse_args(args)
|
|
|
|
|
|
- if options.all:
|
|
|
+ if args.all:
|
|
|
print("Available commands:")
|
|
|
for cmd in sorted(commands):
|
|
|
print(f" {cmd}")
|