git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4][Outreachy] Introduce os-version Capability with Configurable Options
@ 2025-01-06 10:30 Usman Akinyemi
  2025-01-06 10:30 ` [PATCH 1/4] version: refactor redact_non_printables() Usman Akinyemi
                   ` (4 more replies)
  0 siblings, 5 replies; 108+ messages in thread
From: Usman Akinyemi @ 2025-01-06 10:30 UTC (permalink / raw)
  To: git, christian.couder
  Cc: gitster, ps, johncai86, Johannes.Schindelin, me, phillip.wood

For debugging, statistical analysis, and security purposes, it can
be valuable for Git servers to know the operating system the clients
are using.

For example:
- A server noticing that a client is using an old Git version with
security issues on one platform, like macOS, could verify if the
user is indeed running macOS before sending a message to upgrade."
- Similarly, a server identifying a client that could benefit from
an upgrade (e.g., for performance reasons) could better customize the
message it sends to nudge the client to upgrade.

So let's add a new 'os-version' capability to the v2 protocol, in the
same way as the existing 'agent' capability that lets clients and servers
exchange the Git version they are running.

By default this sends similar info as `git bugreport` is already sending,
which uses uname(2). The difference is that it is sanitized in the same
way as the Git version sent by the 'agent' capability is sanitized
(by replacing characters having an ascii code less than 32 or more
than 127 with '.'). Also, it only sends the result of `uname -s` i.e
just only the operating system name (e.g "Linux").

Due to privacy issues and concerns, let's add the `transfer.advertiseOSVersion`
config option. This boolean option is enabled by default, but allows users to
disable this feature completely by setting it to "false".

To provide flexibility and customization, let also add the `osversion.command`
config option. This allows users to specify a custom command whose output will
be used as the string exchanged via the "os-version" capability. If this option
is not set, the default behavior exchanges only the operating system name,
such as "Linux" or "Windows".

Planned Feature: osversion.format
While the above configurations are already implemented, we will be introducing
an additional config option, `osversion.format`. This option would allow users
to fully customize the string sent to the other side using placeholders,
similar to how git for-each-ref uses %() syntax.

For example:
Format: "OS: %(os_name), Distro: %(distro), Arch: %(arch)"
Result: "OS: Linux, Distro: Fedora, Arch: x86_64"

We are wondering if it's worth it for placeholders to use the %()
syntax or if they could use another simpler syntax like $OS_NAME or
just OS_NAME instead of %(os_name).

Note that, due to differences between `uname(1)` (command-line
utility) and `uname(2)` (system call) outputs on Windows,
`transfer.advertiseOSVersion` is set to false on Windows during
testing. See the message part of patch 3/4 for more details.

My mentor, Christian Couder, sent a previous patch series about this
before. You can find it here 
https://lore.kernel.org/git/20240619125708.3719150-1-christian.couder@gmail.com/

Usman Akinyemi (4):
  version: refactor redact_non_printables()
  version: refactor get_uname_info()
  connect: advertise OS version
  version: introduce osversion.command config for os-version output

 Documentation/config/transfer.txt |  16 ++++
 Documentation/gitprotocol-v2.txt  |  21 +++++
 builtin/bugreport.c               |  13 +--
 connect.c                         |   3 +
 serve.c                           |  14 +++
 t/t5555-http-smart-common.sh      |  41 ++++++++-
 t/t5701-git-serve.sh              |  45 +++++++++-
 t/test-lib-functions.sh           |   8 ++
 version.c                         | 136 ++++++++++++++++++++++++++++--
 version.h                         |  13 +++
 10 files changed, 291 insertions(+), 19 deletions(-)

-- 
2.47.1


^ permalink raw reply	[flat|nested] 108+ messages in thread
* [PATCH v3 0/5] Introduce a "promisor-remote" capability
@ 2024-12-06 12:42 Christian Couder
  2025-01-27 15:16 ` [PATCH v4 0/6] " Christian Couder
  0 siblings, 1 reply; 108+ messages in thread
From: Christian Couder @ 2024-12-06 12:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, John Cai, Patrick Steinhardt, Taylor Blau,
	Eric Sunshine, Christian Couder

This work is part of some effort to better handle large files/blobs in
a client-server context using promisor remotes dedicated to storing
large blobs. To help understand this effort, this series now contains
a patch (patch 5/5) that adds design documentation about this effort.

Earlier this year, I sent 3 versions of a patch series with the goal
of allowing a client C to clone from a server S while using the same
promisor remote X that S already use. See:

https://lore.kernel.org/git/20240418184043.2900955-1-christian.couder@gmail.com/

Junio suggested to implement that feature using:

"a protocol extension that lets S tell C that S wants C to fetch
missing objects from X (which means that if C knows about X in its
".git/config" then there is no need for end-user interaction at all),
or a protocol extension that C tells S that C is willing to see
objects available from X omitted when S does not have them (again,
this could be done by looking at ".git/config" at C, but there may be
security implications???)"

This patch series implements that protocol extension called
"promisor-remote" (that name is open to change or simplification)
which allows S and C to agree on C using X directly or not.

I have tried to implement it in a quite generic way that could allow S
and C to share more information about promisor remotes and how to use
them.

For now, C doesn't use the information it gets from S when cloning.
That information is only used to decide if C is OK to use the promisor
remotes advertised by S. But this could change in the future which
could make it much simpler for clients than using the current way of
passing information about X with the `-c` option of `git clone` many
times on the command line.

Another improvement could be to not require GIT_NO_LAZY_FETCH=0 when S
and C have agreed on using S.

Changes compared to version 2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Summary of the changes: there are few changes in the C code, but a
numberof them in the tests, and a new design doc.

  - To avoid conflicts and benefit from recent improvements (like leak
    checks) this series has been rebased to a recent master:
    23692e08c6 (The thirteenth batch, 2024-12-04)

  - In patch 3/5, some functions are not passed a
    `struct repository *repo` argument anymore as this argument is only used
    in patch 4/5, so it's better to introduce it in that patch.

  - In patch 3/5, a memory leak was fixed using
    git_config_get_string_tmp() instead of git_config_get_string() as
    suggested by Patrick.

  - In patch 3/5, a number of tests using `git fetch` are added. This
    is why there are a number of other refactorings and improvements
    in the tests described in some points below.

  - In patch 3/5, some tests using `git clone` had a title that used
    "fetch" instead of "clone". This has been corrected.

  - In patch 3/5, the test helper function initialize_server() now
    takes 2 arguments to make it more generic.

  - In patch 3/5, a new copy_to_server2() test helper function has
    been introduced.

  - In patch 3/5, a test repacking with a filter was writting outside
    the test directory which has been corrected using
    `--filter-to="$(pwd)/pack"`.

  - In patch 3/5, a test was using `touch "$promisor_file"`. This was
    replaced with `>"$promisor_file"`.

  - In patch 4/5, some functions are now passed a
    `struct repository *repo` argument. This is related to the
    corresponding change in patch 3/5 that removed this argument.

  - In patch 4/5, some tests using `git clone` had a title that used
    "fetch" instead of "clone". This has been corrected (in the same
    way as in patch 3/5).

  - Patch 5/5 is new. It adds design documentation that could help
    understand the broader context of this patch series, as this was
    requested by some reviewers. This patch is optional. I am OK with
    removing it or discussing it as a single separate patch.

Thanks to Junio, Patrick, Eric and Taylor for their suggestions.

CI tests
~~~~~~~~

https://github.com/chriscool/git/actions/runs/12197064528

Unfortunately some tests (linux-sha256, linux-reftable, linux-gcc and
linux-gcc-default) failed after around 46 minutes as the dependencies
couldn't be intalled.

One test, linux-TEST-vars, failed much earlier, in what doesn't look
like a CI issue as I could reproduce the failure locally when setting
GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL to 1. I will investigate,
but in the meantime I think I can send this as-is so we can start
discussing.

Range diff compared to version 2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1:  0d9d094181 = 1:  13dd730641 version: refactor strbuf_sanitize()
2:  fc53229eff = 2:  8f2aecf6a1 strbuf: refactor strbuf_trim_trailing_ch()
3:  5c507e427f ! 3:  57e1481bc4 Add 'promisor-remote' capability to protocol v2
    @@ promisor-remote.c: void promisor_remote_get_direct(struct repository *repo,
     +  BUG("Unhandled 'enum accept_promisor' value '%d'", accept);
     +}
     +
    -+static void filter_promisor_remote(struct repository *repo,
    -+                             struct strvec *accepted,
    -+                             const char *info)
    ++static void filter_promisor_remote(struct strvec *accepted, const char *info)
     +{
     +  struct strbuf **remotes;
    -+  char *accept_str;
    ++  const char *accept_str;
     +  enum accept_promisor accept = ACCEPT_NONE;
     +
    -+  if (!git_config_get_string("promisor.acceptfromserver", &accept_str)) {
    ++  if (!git_config_get_string_tmp("promisor.acceptfromserver", &accept_str)) {
     +          if (!accept_str || !*accept_str || !strcasecmp("None", accept_str))
     +                  accept = ACCEPT_NONE;
     +          else if (!strcasecmp("All", accept_str))
    @@ promisor-remote.c: void promisor_remote_get_direct(struct repository *repo,
     +          free(decoded_url);
     +  }
     +
    -+  free(accept_str);
     +  strbuf_list_free(remotes);
     +}
     +
    @@ promisor-remote.c: void promisor_remote_get_direct(struct repository *repo,
     +  struct strvec accepted = STRVEC_INIT;
     +  struct strbuf reply = STRBUF_INIT;
     +
    -+  filter_promisor_remote(the_repository, &accepted, info);
    ++  filter_promisor_remote(&accepted, info);
     +
     +  if (!accepted.nr)
     +          return NULL;
    @@ t/t5710-promisor-remote-capability.sh (new)
     +  git -C "$1" rev-list --objects --all --missing=print > all.txt &&
     +  perl -ne 'print if s/^[?]//' all.txt >missing.txt &&
     +  test_line_count = "$2" missing.txt &&
    -+  test "$3" = "$(cat missing.txt)"
    ++  if test "$2" -lt 2
    ++  then
    ++          test "$3" = "$(cat missing.txt)"
    ++  else
    ++          test -f "$3" &&
    ++          sort <"$3" >expected_sorted &&
    ++          sort <missing.txt >actual_sorted &&
    ++          test_cmp expected_sorted actual_sorted
    ++  fi
     +}
     +
     +initialize_server () {
    ++  count="$1"
    ++  missing_oids="$2"
    ++
     +  # Repack everything first
     +  git -C server -c repack.writebitmaps=false repack -a -d &&
     +
    @@ t/t5710-promisor-remote-capability.sh (new)
     +
     +  # Repack without the largest object and create a promisor pack on server
     +  git -C server -c repack.writebitmaps=false repack -a -d \
    -+      --filter=blob:limit=5k --filter-to="$(pwd)" &&
    ++      --filter=blob:limit=5k --filter-to="$(pwd)/pack" &&
     +  promisor_file=$(ls server/objects/pack/*.pack | sed "s/\.pack/.promisor/") &&
    -+  touch "$promisor_file" &&
    ++  >"$promisor_file" &&
     +
    -+  # Check that only one object is missing on the server
    -+  check_missing_objects server 1 "$oid"
    ++  # Check objects missing on the server
    ++  check_missing_objects server "$count" "$missing_oids"
    ++}
    ++
    ++copy_to_server2 () {
    ++  oid_path="$(test_oid_to_path $1)" &&
    ++  path="server/objects/$oid_path" &&
    ++  path2="server2/objects/$oid_path" &&
    ++  mkdir -p $(dirname "$path2") &&
    ++  cp "$path" "$path2"
     +}
     +
     +test_expect_success "setup for testing promisor remote advertisement" '
    @@ t/t5710-promisor-remote-capability.sh (new)
     +  # Copy the largest object from server to server2
     +  obj="HEAD:foo" &&
     +  oid="$(git -C server rev-parse $obj)" &&
    -+  oid_path="$(test_oid_to_path $oid)" &&
    -+  path="server/objects/$oid_path" &&
    -+  path2="server2/objects/$oid_path" &&
    -+  mkdir -p $(dirname "$path2") &&
    -+  cp "$path" "$path2" &&
    ++  copy_to_server2 "$oid" &&
     +
    -+  initialize_server &&
    ++  initialize_server 1 "$oid" &&
     +
     +  # Configure server2 as promisor remote for server
     +  git -C server remote add server2 "file://$(pwd)/server2" &&
    @@ t/t5710-promisor-remote-capability.sh (new)
     +  git -C server config uploadpack.allowAnySHA1InWant true
     +'
     +
    -+test_expect_success "fetch with promisor.advertise set to 'true'" '
    ++test_expect_success "clone with promisor.advertise set to 'true'" '
     +  git -C server config promisor.advertise true &&
     +
     +  # Clone from server to create a client
    @@ t/t5710-promisor-remote-capability.sh (new)
     +  check_missing_objects server 1 "$oid"
     +'
     +
    -+test_expect_success "fetch with promisor.advertise set to 'false'" '
    ++test_expect_success "clone with promisor.advertise set to 'false'" '
     +  git -C server config promisor.advertise false &&
     +
     +  # Clone from server to create a client
    @@ t/t5710-promisor-remote-capability.sh (new)
     +  check_missing_objects server 0 "" &&
     +
     +  # Reinitialize server so that the largest object is missing again
    -+  initialize_server
    ++  initialize_server 1 "$oid"
     +'
     +
    -+test_expect_success "fetch with promisor.acceptfromserver set to 'None'" '
    ++test_expect_success "clone with promisor.acceptfromserver set to 'None'" '
     +  git -C server config promisor.advertise true &&
     +
     +  # Clone from server to create a client
    @@ t/t5710-promisor-remote-capability.sh (new)
     +  test_when_finished "rm -rf client" &&
     +
     +  # Check that the largest object is not missing on the server
    -+  check_missing_objects server 0 ""
    ++  check_missing_objects server 0 "" &&
    ++
    ++  # Reinitialize server so that the largest object is missing again
    ++  initialize_server 1 "$oid"
    ++'
    ++
    ++test_expect_success "init + fetch with promisor.advertise set to 'true'" '
    ++  git -C server config promisor.advertise true &&
    ++
    ++  test_when_finished "rm -rf client" &&
    ++  mkdir client &&
    ++  git -C client init &&
    ++  git -C client config remote.server2.promisor true &&
    ++  git -C client config remote.server2.fetch "+refs/heads/*:refs/remotes/server2/*" &&
    ++  git -C client config remote.server2.url "file://$(pwd)/server2" &&
    ++  git -C client config remote.server.url "file://$(pwd)/server" &&
    ++  git -C client config remote.server.fetch "+refs/heads/*:refs/remotes/server/*" &&
    ++  git -C client config promisor.acceptfromserver All &&
    ++  GIT_NO_LAZY_FETCH=0 git -C client fetch --filter="blob:limit=5k" server &&
    ++
    ++  # Check that the largest object is still missing on the server
    ++  check_missing_objects server 1 "$oid"
    ++'
    ++
    ++test_expect_success "clone with promisor.advertise set to 'true' but don't delete the client" '
    ++  git -C server config promisor.advertise true &&
    ++
    ++  # Clone from server to create a client
    ++  GIT_NO_LAZY_FETCH=0 git clone -c remote.server2.promisor=true \
    ++          -c remote.server2.fetch="+refs/heads/*:refs/remotes/server2/*" \
    ++          -c remote.server2.url="file://$(pwd)/server2" \
    ++          -c promisor.acceptfromserver=All \
    ++          --no-local --filter="blob:limit=5k" server client &&
    ++
    ++  # Check that the largest object is still missing on the server
    ++  check_missing_objects server 1 "$oid"
    ++'
    ++
    ++test_expect_success "setup for subsequent fetches" '
    ++  # Generate new commit with large blob
    ++  test-tool genrandom bar 10240 >template/bar &&
    ++  git -C template add bar &&
    ++  git -C template commit -m bar &&
    ++
    ++  # Fetch new commit with large blob
    ++  git -C server fetch origin &&
    ++  git -C server update-ref HEAD FETCH_HEAD &&
    ++  git -C server rev-parse HEAD >expected_head &&
    ++
    ++  # Repack everything twice and remove .promisor files before
    ++  # each repack. This makes sure everything gets repacked
    ++  # into a single packfile. The second repack is necessary
    ++  # because the first one fetches from server2 and creates a new
    ++  # packfile and its associated .promisor file.
    ++
    ++  rm -f server/objects/pack/*.promisor &&
    ++  git -C server -c repack.writebitmaps=false repack -a -d &&
    ++  rm -f server/objects/pack/*.promisor &&
    ++  git -C server -c repack.writebitmaps=false repack -a -d &&
    ++
    ++  # Unpack everything
    ++  rm pack-* &&
    ++  mv server/objects/pack/pack-* . &&
    ++  packfile=$(ls pack-*.pack) &&
    ++  git -C server unpack-objects --strict <"$packfile" &&
    ++
    ++  # Copy new large object to server2
    ++  obj_bar="HEAD:bar" &&
    ++  oid_bar="$(git -C server rev-parse $obj_bar)" &&
    ++  copy_to_server2 "$oid_bar" &&
    ++
    ++  # Reinitialize server so that the 2 largest objects are missing
    ++  printf "%s\n" "$oid" "$oid_bar" >expected_missing.txt &&
    ++  initialize_server 2 expected_missing.txt &&
    ++
    ++  # Create one more client
    ++  cp -r client client2
    ++'
    ++
    ++test_expect_success "subsequent fetch from a client when promisor.advertise is true" '
    ++  git -C server config promisor.advertise true &&
    ++
    ++  GIT_NO_LAZY_FETCH=0 git -C client pull origin &&
    ++
    ++  git -C client rev-parse HEAD >actual &&
    ++  test_cmp expected_head actual &&
    ++
    ++  cat client/bar >/dev/null &&
    ++
    ++  check_missing_objects server 2 expected_missing.txt
    ++'
    ++
    ++test_expect_success "subsequent fetch from a client when promisor.advertise is false" '
    ++  git -C server config promisor.advertise false &&
    ++
    ++  GIT_NO_LAZY_FETCH=0 git -C client2 pull origin &&
    ++
    ++  git -C client2 rev-parse HEAD >actual &&
    ++  test_cmp expected_head actual &&
    ++
    ++  cat client2/bar >/dev/null &&
    ++
    ++  check_missing_objects server 1 "$oid"
     +'
     +
     +test_done
4:  1c2794f139 ! 4:  7fcc619e41 promisor-remote: check advertised name or URL
    @@ promisor-remote.c: char *promisor_remote_info(struct repository *repo)
     +  return 0;
      }
      
    - static void filter_promisor_remote(struct repository *repo,
    -@@ promisor-remote.c: static void filter_promisor_remote(struct repository *repo,
    +-static void filter_promisor_remote(struct strvec *accepted, const char *info)
    ++static void filter_promisor_remote(struct repository *repo,
    ++                             struct strvec *accepted,
    ++                             const char *info)
    + {
        struct strbuf **remotes;
    -   char *accept_str;
    +   const char *accept_str;
        enum accept_promisor accept = ACCEPT_NONE;
     +  struct strvec names = STRVEC_INIT;
     +  struct strvec urls = STRVEC_INIT;
      
    -   if (!git_config_get_string("promisor.acceptfromserver", &accept_str)) {
    +   if (!git_config_get_string_tmp("promisor.acceptfromserver", &accept_str)) {
                if (!accept_str || !*accept_str || !strcasecmp("None", accept_str))
                        accept = ACCEPT_NONE;
     +          else if (!strcasecmp("KnownUrl", accept_str))
    @@ promisor-remote.c: static void filter_promisor_remote(struct repository *repo,
                else if (!strcasecmp("All", accept_str))
                        accept = ACCEPT_ALL;
                else
    -@@ promisor-remote.c: static void filter_promisor_remote(struct repository *repo,
    +@@ promisor-remote.c: static void filter_promisor_remote(struct strvec *accepted, const char *info)
        if (accept == ACCEPT_NONE)
                return;
      
    @@ promisor-remote.c: static void filter_promisor_remote(struct repository *repo,
        /* Parse remote info received */
      
        remotes = strbuf_split_str(info, ';', 0);
    -@@ promisor-remote.c: static void filter_promisor_remote(struct repository *repo,
    +@@ promisor-remote.c: static void filter_promisor_remote(struct strvec *accepted, const char *info)
                if (remote_url)
                        decoded_url = url_percent_decode(remote_url);
      
    @@ promisor-remote.c: static void filter_promisor_remote(struct repository *repo,
                        strvec_push(accepted, decoded_name);
      
                strbuf_list_free(elems);
    -@@ promisor-remote.c: static void filter_promisor_remote(struct repository *repo,
    +@@ promisor-remote.c: static void filter_promisor_remote(struct strvec *accepted, const char *info)
    +           free(decoded_url);
        }
      
    -   free(accept_str);
     +  strvec_clear(&names);
     +  strvec_clear(&urls);
        strbuf_list_free(remotes);
      }
      
    +@@ promisor-remote.c: char *promisor_remote_reply(const char *info)
    +   struct strvec accepted = STRVEC_INIT;
    +   struct strbuf reply = STRBUF_INIT;
    + 
    +-  filter_promisor_remote(&accepted, info);
    ++  filter_promisor_remote(the_repository, &accepted, info);
    + 
    +   if (!accepted.nr)
    +           return NULL;
     
      ## t/t5710-promisor-remote-capability.sh ##
    -@@ t/t5710-promisor-remote-capability.sh: test_expect_success "fetch with promisor.acceptfromserver set to 'None'" '
    -           --no-local --filter="blob:limit=5k" server client &&
    -   test_when_finished "rm -rf client" &&
    +@@ t/t5710-promisor-remote-capability.sh: test_expect_success "init + fetch with promisor.advertise set to 'true'" '
    +   check_missing_objects server 1 "$oid"
    + '
      
    -+  # Check that the largest object is not missing on the server
    -+  check_missing_objects server 0 "" &&
    -+
    -+  # Reinitialize server so that the largest object is missing again
    -+  initialize_server
    -+'
    -+
    -+test_expect_success "fetch with promisor.acceptfromserver set to 'KnownName'" '
    ++test_expect_success "clone with promisor.acceptfromserver set to 'KnownName'" '
     +  git -C server config promisor.advertise true &&
     +
     +  # Clone from server to create a client
    @@ t/t5710-promisor-remote-capability.sh: test_expect_success "fetch with promisor.
     +  check_missing_objects server 1 "$oid"
     +'
     +
    -+test_expect_success "fetch with 'KnownName' and different remote names" '
    ++test_expect_success "clone with 'KnownName' and different remote names" '
     +  git -C server config promisor.advertise true &&
     +
     +  # Clone from server to create a client
    @@ t/t5710-promisor-remote-capability.sh: test_expect_success "fetch with promisor.
     +  check_missing_objects server 0 "" &&
     +
     +  # Reinitialize server so that the largest object is missing again
    -+  initialize_server
    ++  initialize_server 1 "$oid"
     +'
     +
    -+test_expect_success "fetch with promisor.acceptfromserver set to 'KnownUrl'" '
    ++test_expect_success "clone with promisor.acceptfromserver set to 'KnownUrl'" '
     +  git -C server config promisor.advertise true &&
     +
     +  # Clone from server to create a client
    @@ t/t5710-promisor-remote-capability.sh: test_expect_success "fetch with promisor.
     +  check_missing_objects server 1 "$oid"
     +'
     +
    -+test_expect_success "fetch with 'KnownUrl' and different remote urls" '
    ++test_expect_success "clone with 'KnownUrl' and different remote urls" '
     +  ln -s server2 serverTwo &&
     +
     +  git -C server config promisor.advertise true &&
    @@ t/t5710-promisor-remote-capability.sh: test_expect_success "fetch with promisor.
     +          --no-local --filter="blob:limit=5k" server client &&
     +  test_when_finished "rm -rf client" &&
     +
    -   # Check that the largest object is not missing on the server
    -   check_missing_objects server 0 ""
    - '
    ++  # Check that the largest object is not missing on the server
    ++  check_missing_objects server 0 "" &&
    ++
    ++  # Reinitialize server so that the largest object is missing again
    ++  initialize_server 1 "$oid"
    ++'
    ++
    + test_expect_success "clone with promisor.advertise set to 'true' but don't delete the client" '
    +   git -C server config promisor.advertise true &&
    + 
-:  ---------- > 5:  c25c94707f doc: add technical design doc for large object promisors


Christian Couder (5):
  version: refactor strbuf_sanitize()
  strbuf: refactor strbuf_trim_trailing_ch()
  Add 'promisor-remote' capability to protocol v2
  promisor-remote: check advertised name or URL
  doc: add technical design doc for large object promisors

 Documentation/config/promisor.txt             |  27 +
 Documentation/gitprotocol-v2.txt              |  54 ++
 .../technical/large-object-promisors.txt      | 530 ++++++++++++++++++
 connect.c                                     |   9 +
 promisor-remote.c                             | 243 ++++++++
 promisor-remote.h                             |  36 +-
 serve.c                                       |  26 +
 strbuf.c                                      |  16 +
 strbuf.h                                      |  10 +
 t/t5710-promisor-remote-capability.sh         | 309 ++++++++++
 trace2/tr2_cfg.c                              |  10 +-
 upload-pack.c                                 |   3 +
 version.c                                     |   9 +-
 13 files changed, 1266 insertions(+), 16 deletions(-)
 create mode 100644 Documentation/technical/large-object-promisors.txt
 create mode 100755 t/t5710-promisor-remote-capability.sh

-- 
2.47.1.402.gc25c94707f


^ permalink raw reply	[flat|nested] 108+ messages in thread

end of thread, other threads:[~2025-02-18 17:14 UTC | newest]

Thread overview: 108+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-06 10:30 [PATCH 0/4][Outreachy] Introduce os-version Capability with Configurable Options Usman Akinyemi
2025-01-06 10:30 ` [PATCH 1/4] version: refactor redact_non_printables() Usman Akinyemi
2025-01-06 22:35   ` Eric Sunshine
2025-01-08 12:58     ` Usman Akinyemi
2025-01-06 10:30 ` [PATCH 2/4] version: refactor get_uname_info() Usman Akinyemi
2025-01-06 16:04   ` Junio C Hamano
2025-01-08 13:06     ` Usman Akinyemi
2025-01-06 10:30 ` [PATCH 3/4] connect: advertise OS version Usman Akinyemi
2025-01-06 16:22   ` Junio C Hamano
2025-01-08 13:06     ` Usman Akinyemi
2025-01-08 16:15       ` Junio C Hamano
2025-01-09 14:25         ` Usman Akinyemi
2025-01-09 15:46           ` Junio C Hamano
2025-01-10 17:56             ` Usman Akinyemi
2025-01-10 19:24               ` Junio C Hamano
2025-01-11 11:07                 ` Usman Akinyemi
2025-01-13 15:46                   ` Junio C Hamano
2025-01-13 18:26                     ` Usman Akinyemi
2025-01-13 19:47                       ` Junio C Hamano
2025-01-13 20:07                         ` rsbecker
2025-01-06 23:17   ` Eric Sunshine
2025-01-08 13:14     ` Usman Akinyemi
2025-01-06 10:30 ` [PATCH 4/4] version: introduce osversion.command config for os-version output Usman Akinyemi
2025-01-17 10:46 ` [PATCH v2 0/6][Outreachy] Introduce os-version Capability with Configurable Options Usman Akinyemi
2025-01-17 10:46   ` [PATCH v2 1/6] version: refactor redact_non_printables() Usman Akinyemi
2025-01-17 18:26     ` Junio C Hamano
2025-01-17 19:48       ` Junio C Hamano
2025-01-20 17:10       ` Usman Akinyemi
2025-01-21  8:12         ` Christian Couder
2025-01-21 18:01           ` Junio C Hamano
2025-01-17 10:46   ` [PATCH v2 2/6] version: refactor get_uname_info() Usman Akinyemi
2025-01-17 10:46   ` [PATCH v2 3/6] version: extend get_uname_info() to hide system details Usman Akinyemi
2025-01-17 18:27     ` Junio C Hamano
2025-01-17 10:46   ` [PATCH v2 4/6] t5701: add setup test to remove side-effect dependency Usman Akinyemi
2025-01-17 19:31     ` Junio C Hamano
2025-01-20 17:32       ` Usman Akinyemi
2025-01-20 19:52         ` Junio C Hamano
2025-01-21 13:43           ` Usman Akinyemi
2025-01-17 10:46   ` [PATCH v2 5/6] connect: advertise OS version Usman Akinyemi
2025-01-17 19:35     ` Junio C Hamano
2025-01-17 22:22     ` Junio C Hamano
2025-01-17 22:47       ` rsbecker
2025-01-17 23:04         ` Junio C Hamano
2025-01-20 18:15       ` Usman Akinyemi
2025-01-21 19:06         ` Junio C Hamano
2025-01-17 10:46   ` [PATCH v2 6/6] version: introduce osversion.command config for os-version output Usman Akinyemi
2025-01-17 21:44     ` Eric Sunshine
2025-01-20 18:17       ` Usman Akinyemi
2025-01-20 18:41         ` Eric Sunshine
2025-01-20 19:08           ` Usman Akinyemi
2025-01-17 22:33     ` Junio C Hamano
2025-01-17 22:49       ` rsbecker
2025-01-17 23:06         ` Junio C Hamano
2025-01-17 23:18           ` rsbecker
2025-01-20 18:58       ` Usman Akinyemi
2025-01-21 19:14         ` Junio C Hamano
2025-01-21 19:51           ` rsbecker
2025-01-24 12:21   ` [PATCH v3 0/6][Outreachy] Introduce os-version Capability with Configurable Options Usman Akinyemi
2025-01-24 12:21     ` [PATCH v3 1/6] version: replace manual ASCII checks with isprint() for clarity Usman Akinyemi
2025-01-24 18:13       ` Junio C Hamano
2025-01-24 12:21     ` [PATCH v3 2/6] version: refactor redact_non_printables() Usman Akinyemi
2025-01-24 12:21     ` [PATCH v3 3/6] version: refactor get_uname_info() Usman Akinyemi
2025-01-24 12:21     ` [PATCH v3 4/6] version: extend get_uname_info() to hide system details Usman Akinyemi
2025-01-24 12:21     ` [PATCH v3 5/6] t5701: add setup test to remove side-effect dependency Usman Akinyemi
2025-01-24 18:12       ` Junio C Hamano
2025-01-24 12:21     ` [PATCH v3 6/6] connect: advertise OS version Usman Akinyemi
2025-02-05 18:52       ` [PATCH v4 0/6][Outreachy] extend agent capability to include OS name Usman Akinyemi
2025-02-05 18:52         ` [PATCH v4 1/6] version: replace manual ASCII checks with isprint() for clarity Usman Akinyemi
2025-02-05 18:52         ` [PATCH v4 2/6] version: refactor redact_non_printables() Usman Akinyemi
2025-02-05 18:52         ` [PATCH v4 3/6] version: refactor get_uname_info() Usman Akinyemi
2025-02-05 18:52         ` [PATCH v4 4/6] version: extend get_uname_info() to hide system details Usman Akinyemi
2025-02-05 18:52         ` [PATCH v4 5/6] t5701: add setup test to remove side-effect dependency Usman Akinyemi
2025-02-05 18:52         ` [PATCH v4 6/6] agent: advertise OS name via agent capability Usman Akinyemi
2025-02-05 21:48           ` Junio C Hamano
2025-02-06  6:37             ` Usman Akinyemi
2025-02-06 15:13               ` Junio C Hamano
2025-02-07 17:27                 ` Usman Akinyemi
2025-02-07 17:57                   ` Junio C Hamano
2025-02-07 19:25             ` Usman Akinyemi
2025-02-14 12:36         ` [PATCH v5 0/6][Outreachy] extend agent capability to include OS name Usman Akinyemi
2025-02-14 12:36           ` [PATCH v5 1/6] version: replace manual ASCII checks with isprint() for clarity Usman Akinyemi
2025-02-14 12:36           ` [PATCH v5 2/6] version: refactor redact_non_printables() Usman Akinyemi
2025-02-14 12:36           ` [PATCH v5 3/6] version: refactor get_uname_info() Usman Akinyemi
2025-02-14 12:36           ` [PATCH v5 4/6] version: extend get_uname_info() to hide system details Usman Akinyemi
2025-02-14 12:36           ` [PATCH v5 5/6] t5701: add setup test to remove side-effect dependency Usman Akinyemi
2025-02-14 21:49             ` Junio C Hamano
2025-02-14 12:36           ` [PATCH v5 6/6] agent: advertise OS name via agent capability Usman Akinyemi
2025-02-14 22:07             ` Junio C Hamano
2025-02-15 15:29               ` Usman Akinyemi
2025-02-15 15:50           ` [PATCH v6 0/6][Outreachy] extend agent capability to include OS name Usman Akinyemi
2025-02-15 15:50             ` [PATCH v6 1/6] version: replace manual ASCII checks with isprint() for clarity Usman Akinyemi
2025-02-15 15:50             ` [PATCH v6 2/6] version: refactor redact_non_printables() Usman Akinyemi
2025-02-15 15:50             ` [PATCH v6 3/6] version: refactor get_uname_info() Usman Akinyemi
2025-02-15 15:50             ` [PATCH v6 4/6] version: extend get_uname_info() to hide system details Usman Akinyemi
2025-02-15 15:50             ` [PATCH v6 5/6] t5701: add setup test to remove side-effect dependency Usman Akinyemi
2025-02-15 15:50             ` [PATCH v6 6/6] agent: advertise OS name via agent capability Usman Akinyemi
2025-02-18 17:14               ` Junio C Hamano
2025-02-18 17:09             ` [PATCH v6 0/6][Outreachy] extend agent capability to include OS name Junio C Hamano
2025-01-24 18:39     ` [PATCH v3 0/6][Outreachy] Introduce os-version Capability with Configurable Options Junio C Hamano
2025-01-27 13:38       ` Christian Couder
2025-01-27 15:26         ` Junio C Hamano
2025-01-31 14:30           ` Christian Couder
2025-01-31 16:37             ` Junio C Hamano
2025-01-31 19:42               ` Usman Akinyemi
2025-01-31 20:15                 ` Junio C Hamano
2025-01-31 19:46               ` Usman Akinyemi
2025-01-31 20:17                 ` Junio C Hamano
  -- strict thread matches above, loose matches on Subject: below --
2024-12-06 12:42 [PATCH v3 0/5] Introduce a "promisor-remote" capability Christian Couder
2025-01-27 15:16 ` [PATCH v4 0/6] " Christian Couder
2025-01-27 15:16   ` [PATCH v4 2/6] version: refactor redact_non_printables() Christian Couder

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).