Skip to content

Commit

Permalink
add initial support for Git protocol v2 (#1244)
Browse files Browse the repository at this point in the history
Implement Git protocol version negotiation and use Git protocol v2 for
fetches if supported. For now, the observable behaviour of Dulwich is
equivalent regardless of protocol version, except that two new features
may be used if the server supports Git protocol v2.

The first feature is a reference prefix list which may be used to filter
refs server-side. This can be used to reduce the size of the initial
reference listing announced by the server. Reducing the size of this
announcement was a major design goal for protocol v2 to avoid sending of
very large announcements when a repository contains a lot of references.
This feature is intended as an optimization which servers are free to
ignore depending on available server-side resources. Therefore, users of
Dulwich should still be prepared to filter redundant refs manually (this
limitation also applies to Git itself).
A new --refspec porcelain option is provided in order to test this
feature on the command line.

The second feature is an object filter specification, which corresponds
to the --filter option of 'git clone'. This can be used to omit objects
while cloning repositories. For instance, the following command will
clone a given repsitory without fetching any blob objects:

   dulwich clone --filter blob:none --bare REPO_URL

(In this example the --bare option is used because creation of a work
tree would fail without any blobs present.)

The test suite now enables protocol v2 and keeps passing for me.
  • Loading branch information
jelmer authored Jun 28, 2024
2 parents 436ce9f + f270f0c commit 101a80c
Show file tree
Hide file tree
Showing 7 changed files with 633 additions and 65 deletions.
39 changes: 32 additions & 7 deletions dulwich/cli.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,22 @@ def run(self, args):
type=str,
help=("Check out branch instead of branch pointed to by remote " "HEAD"),
)
parser.add_option(
"--refspec",
dest="refspec",
type=str,
help="References to fetch",
action="append",
)
parser.add_option(
"--filter",
dest="filter_spec",
type=str,
help="git-rev-list-style object filter",
)
parser.add_option(
"--protocol", dest="protocol", type=int, help="Git protocol version to use"
)
options, args = parser.parse_args(args)

if args == []:
Expand All @@ -282,6 +298,9 @@ def run(self, args):
bare=options.bare,
depth=options.depth,
branch=options.branch,
refspec=options.refspec,
filter_spec=options.filter_spec,
protocol_version=options.protocol,
)
except GitProtocolError as e:
print(f"{e}")
Expand Down Expand Up @@ -586,13 +605,19 @@ def run(self, args):

class cmd_pull(Command):
def run(self, args):
parser = optparse.OptionParser()
options, args = parser.parse_args(args)
try:
from_location = args[0]
except IndexError:
from_location = None
porcelain.pull(".", from_location)
parser = argparse.ArgumentParser()
parser.add_argument("from_location", type=str)
parser.add_argument("refspec", type=str, nargs="*")
parser.add_argument("--filter", type=str, nargs=1)
parser.add_argument("--protocol", type=int, nargs=1)
args = parser.parse_args(args)
porcelain.pull(
".",
args.from_location or None,
args.refspec or None,
filter_spec=args.filter,
protocol_version=args.protocol_version or None,
)


class cmd_push(Command):
Expand Down
Loading

0 comments on commit 101a80c

Please sign in to comment.