@@ -131,4 +131,13 @@ transfer.advertiseOSVersion::
servers. It makes clients and servers send to each other a string
representing the operating system name, like "Linux" or "Windows".
This string is retrieved from the 'sysname' field of the struct returned
- by the uname(2) system call. Defaults to true.
+ by the uname(2) system call. If the `osVersion.command` is set, the
+ output of the command specified will be the string exchanged by the clients
+ and the servers. Defaults to true.
+
+osVersion.command::
+ If this variable is set, the specified command will be run and the output
+ will be used as the value `X` for `os-version` capability (in the form
+ `os-version=X`). `osVersion.command` is only used if `transfer.advertiseOSVersion`
+ is true. Refer to the linkgit:git-config[1] documentation to learn more about
+ `transfer.advertiseOSVersion` config option.
@@ -203,12 +203,13 @@ in its request to the server (but it MUST NOT do so if the server did
not advertise the os-version capability). The `X` and `Y` strings may
contain any printable ASCII characters except space (i.e., the byte
range 32 < x < 127), and are typically made from the result of
-`uname -s`(OS name e.g Linux). The os-version capability can be disabled
-entirely by setting the `transfer.advertiseOSVersion` config option
-to `false`. The `os-version` strings are purely informative for
-statistics and debugging purposes, and MUST NOT be used to
-programmatically assume the presence or absence of particular
-features.
+`uname -s`(OS name e.g Linux). If the `osVersion.command` is set,
+the `X` and `Y` are made from the ouput of the command specified.
+The os-version capability can be disabled entirely by setting the
+`transfer.advertiseOSVersion` config option to `false`. The `os-version`
+strings are purely informative for statistics and debugging purposes, and
+MUST NOT be used to programmatically assume the presence or absence of
+particular features.
ls-refs
~~~~~~~
@@ -152,6 +152,35 @@ test_expect_success 'git upload-pack --advertise-refs: v2' '
test_cmp actual expect
'
+test_expect_success 'git upload-pack --advertise-refs: v2 with osVersion.command config set' '
+ # test_config is used here as we are not reusing any file output from here
+ test_config osVersion.command "uname -srvm" &&
+ printf "agent=FAKE" >agent_and_long_os_name &&
+
+ if test_have_prereq !WINDOWS
+ then
+ printf "\nos-version=%s\n" $(uname -srvm | test_redact_non_printables) >>agent_and_long_os_name
+ fi &&
+
+ cat >expect <<-EOF &&
+ version 2
+ $(cat agent_and_long_os_name)
+ ls-refs=unborn
+ fetch=shallow wait-for-done
+ server-option
+ object-format=$(test_oid algo)
+ 0000
+ EOF
+
+ GIT_PROTOCOL=version=2 \
+ GIT_USER_AGENT=FAKE \
+ git upload-pack --advertise-refs . >out 2>err &&
+
+ test-tool pkt-line unpack <out >actual &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+'
+
test_expect_success 'git receive-pack --advertise-refs: v2' '
# There is no v2 yet for receive-pack, implicit v0
cat >expect <<-EOF &&
@@ -41,6 +41,39 @@ test_expect_success 'test capability advertisement' '
test_cmp expect actual
'
+test_expect_success 'test capability advertisement with osVersion.command config set' '
+ # test_config is used here as we are not reusing any file output from here
+ test_config osVersion.command "uname -srvm" &&
+ printf "agent=git/$(git version | cut -d" " -f3)" >agent_and_long_os_name &&
+
+ if test_have_prereq !WINDOWS
+ then
+ printf "\nos-version=%s\n" $(uname -srvm | test_redact_non_printables) >>agent_and_long_os_name
+ fi &&
+
+ test_oid_cache <<-EOF &&
+ wrong_algo sha1:sha256
+ wrong_algo sha256:sha1
+ EOF
+ cat >expect.base_long <<-EOF &&
+ version 2
+ $(cat agent_and_long_os_name)
+ ls-refs=unborn
+ fetch=shallow wait-for-done
+ server-option
+ object-format=$(test_oid algo)
+ EOF
+ cat >expect.trailer_long <<-EOF &&
+ 0000
+ EOF
+ cat expect.base_long expect.trailer_long >expect &&
+
+ GIT_TEST_SIDEBAND_ALL=0 test-tool serve-v2 \
+ --advertise-capabilities >out &&
+ test-tool pkt-line unpack <out >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'stateless-rpc flag does not list capabilities' '
# Empty request
test-tool pkt-line pack >in <<-EOF &&
@@ -1,9 +1,13 @@
+#define USE_THE_REPOSITORY_VARIABLE
+
#include "git-compat-util.h"
#include "version.h"
#include "version-def.h"
#include "strbuf.h"
#include "gettext.h"
#include "config.h"
+#include "run-command.h"
+#include "alias.h"
const char git_version_string[] = GIT_VERSION;
const char git_built_from_commit_string[] = GIT_BUILT_FROM_COMMIT;
@@ -72,6 +76,50 @@ int get_uname_info(struct strbuf *buf, unsigned int full)
return 0;
}
+/*
+ * Return -1 if unable to retrieve the osversion.command config or
+ * if the command is malformed; otherwise, return 0 if successful.
+ */
+static int fill_os_version_command(struct child_process *cmd)
+{
+ const char *os_version_command;
+ const char **argv;
+ char *os_version_copy;
+ int n;
+
+ if (git_config_get_string_tmp("osversion.command", &os_version_command))
+ return -1;
+
+ os_version_copy = xstrdup(os_version_command);
+ n = split_cmdline(os_version_copy, &argv);
+
+ if (n < 0) {
+ warning(_("malformed osVersion.command config option: %s"),
+ _(split_cmdline_strerror(n)));
+ free(os_version_copy);
+ return -1;
+ }
+
+ for (int i = 0; i < n; i++)
+ strvec_push(&cmd->args, argv[i]);
+ free(os_version_copy);
+ free(argv);
+
+ return 0;
+}
+
+static int capture_os_version(struct strbuf *buf)
+{
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ if (fill_os_version_command(&cmd))
+ return -1;
+ if (capture_command(&cmd, buf, 0))
+ return -1;
+
+ return 0;
+}
+
const char *os_version(void)
{
static const char *os = NULL;
@@ -79,7 +127,8 @@ const char *os_version(void)
if (!os) {
struct strbuf buf = STRBUF_INIT;
- get_uname_info(&buf, 0);
+ if (capture_os_version(&buf))
+ get_uname_info(&buf, 0);
os = strbuf_detach(&buf, NULL);
}
Currently by default, the new `os-version` capability only exchange the operating system name between servers and clients i.e "Linux" or "Windows". Let's introduce a new configuration option, `osversion.command`, to handle the string exchange between servers and clients. This option allows customization of the exchanged string by leveraging the output of the specified command. If this is not set, the `os-version` capability exchange just the operating system name. Mentored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com> --- Documentation/config/transfer.txt | 11 ++++++- Documentation/gitprotocol-v2.txt | 13 ++++---- t/t5555-http-smart-common.sh | 29 ++++++++++++++++++ t/t5701-git-serve.sh | 33 ++++++++++++++++++++ version.c | 51 ++++++++++++++++++++++++++++++- 5 files changed, 129 insertions(+), 8 deletions(-)