Message ID | 20250106103713.1452035-4-usmanakinyemi202@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Introduce os-version Capability with Configurable Options | expand |
Usman Akinyemi <usmanakinyemi202@gmail.com> writes: > + > +transfer.advertiseOSVersion:: > + When `true`, the `os-version` capability is advertised by clients and > + 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. Shouldn't `sysname` be typeset as a literal, just like `true` and `os-version`? > +os-version > +~~~~~~~~~~ > + > +In the same way as the `agent` capability above, the server can > +advertise the `os-version` capability with a value `X` (in the form > +`os-version=X`) to notify the client that the server is running an > +operating system that can be identified by `X`. The client may Hmph. I am not sure what's the value of mentioning 'X' here. To me ... can advertise the `os-version` capability to notify the kind of operating system it is running on. conveys the same thing with much fewer bytes. > +optionally send its own `os-version` string by including the > +`os-version` capability with a value `Y` (in the form `os-version=Y`) > +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 This is misleading. ASCII printable characters range from 33 to 126 (inclusive), but by saying "except space", the readers are led to believe that the author of this documentation thinks ASCII 32 is printable, too. About 'X' and 'Y', we can just say "the value of this capability may consist of ASCII printable characters (from 33 to 126 inclusive)" or something. Is there a need for a registry of canonical os-version strings? One reason why you would want this user-settable (as opposed to being derived from "uname -s") is that a system that is presumably the same in end-user perception can call itself in different names (your Windows/MINGW64 example) and having the users set it to a string chosen from a small repertoire, the other end would be able to identify them more easily. I do not think it is a necessarily a good idea to limit what value the users can set to this configuration variable, but at least with a published guideline on calling various types of systems (and an explanation on the reason why we publish such a guideline), users would make an informed decision when picking what string to send. > +# Trim and replace each character with ascii code below 32 or above > +# 127 (included) using a dot '.' character. > +# Octal intervals \001-\040 and \177-\377 > +# corresponds to decimal intervals 1-32 and 127-255 > +test_redact_non_printables () { > + tr -d "\n" | tr "[\001-\040][\177-\377]" "." > +} Just being curious. Do we need to worry about carriage-returns not just line-feeds, and if not why? Thanks.
On Mon, Jan 6, 2025 at 5:37 AM Usman Akinyemi <usmanakinyemi202@gmail.com> wrote: > As some issues that can happen with a Git client can be operating system > specific, it can be useful for a server to know which OS a client is > using. In the same way it can be useful for a client to know which OS > a server is using. > > Let's introduce a new protocol (`os-version`) allowing Git clients and > servers to exchange operating system information. The protocol is > controlled by the new `transfer.advertiseOSVersion` config option. > > Add the `transfer.advertiseOSVersion` config option to address > privacy concerns issue. It defaults to `true` and can be changed to > `false`. When enabled, this option makes clients and servers send each > other the OS name (e.g., "Linux" or "Windows"). The information is > retrieved using the 'sysname' field of the `uname(2)` system call. > > However, there are differences between `uname(1)` (command-line utility) > and `uname(2)` (system call) outputs on Windows. These discrepancies > complicate testing on Windows platforms. For example: > - `uname(1)` output: MINGW64_NT-10.0-20348.3.4.10-87d57229.x86_64\ > .2024-02-14.20:17.UTC.x86_64 > - `uname(2)` output: Windows.10.0.20348 > > Until a good way to test the feature on Windows is found, the > transfer.advertiseOSVersion is set to false on Windows during testing. This is because the uname(2) you mention above is not actually system-supplied but is instead faked up Git itself for the Git for Windows port. See git/compat/mingw.c:uname(). The typical way to work around this sort of issue is to ensure that you check Git against Git itself instead of checking Git against "system". To do so, you would implement a new "test-util" command, say `test-util uname`, in git/t/helpers/test-uname.c which internally calls the same uname() function that other parts of Git call. Doing so ensures consistency of output. Whether or not it makes sense to go through that extra work for this particular case is a different question. > Mentored-by: Christian Couder <chriscool@tuxfamily.org> > Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com> > --- > diff --git a/t/t5555-http-smart-common.sh b/t/t5555-http-smart-common.sh > @@ -123,9 +123,19 @@ test_expect_success 'git receive-pack --advertise-refs: v1' ' > test_expect_success 'git upload-pack --advertise-refs: v2' ' > + printf "agent=FAKE" >agent_and_os_name && > + if test_have_prereq WINDOWS > + then > + # We do not use test_config here so that any tests below can reuse > + # the "expect" file from this test > + git config transfer.advertiseOSVersion false Should this have a comment explaining why you're disabling transfer.advertiseOSVersion, in particular that you found uname() on Windows unreliable, thus need to disable the check for this case? The comment you did compose exposes a fragility of the tests: in particular that subsequent tests rely upon a side-effect of this test. The fact that you had to include a special comment explaining the problem argues for a cleaner solution, such as splitting out part of this code into a separate test which comes before this one: specifically, a "setup"-type test which creates the "expect" file which gets reused by multiple tests. > + else > + printf "\nos-version=%s\n" $(uname -s | test_redact_non_printables) >>agent_and_os_name > + fi && > diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh > @@ -8,13 +8,23 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME > test_expect_success 'test capability advertisement' ' > + printf "agent=git/$(git version | cut -d" " -f3)" >agent_and_os_name && > + if test_have_prereq WINDOWS > + then > + # We do not use test_config here so that tests below will be able to reuse > + # the expect.base and expect.trailer files > + git config transfer.advertiseOSVersion false Ditto. > + else > + printf "\nos-version=%s\n" $(uname -s | test_redact_non_printables) >>agent_and_os_name > + fi &&
On Mon, Jan 6, 2025 at 9:52 PM Junio C Hamano <gitster@pobox.com> wrote: > Hi Junio, > Usman Akinyemi <usmanakinyemi202@gmail.com> writes: > > > + > > +transfer.advertiseOSVersion:: > > + When `true`, the `os-version` capability is advertised by clients and > > + 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. > > Shouldn't `sysname` be typeset as a literal, just like `true` and > `os-version`? I will do that in the next iteration. Thank you. > > > +os-version > > +~~~~~~~~~~ > > + > > +In the same way as the `agent` capability above, the server can > > +advertise the `os-version` capability with a value `X` (in the form > > +`os-version=X`) to notify the client that the server is running an > > +operating system that can be identified by `X`. The client may > > Hmph. I am not sure what's the value of mentioning 'X' here. To me > > ... can advertise the `os-version` capability to notify the kind > of operating system it is running on. > > conveys the same thing with much fewer bytes. Yeah, it is better, I will use it in the next iteration. > > > +optionally send its own `os-version` string by including the > > +`os-version` capability with a value `Y` (in the form `os-version=Y`) > > +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 > > This is misleading. ASCII printable characters range from 33 to 126 > (inclusive), but by saying "except space", the readers are led to > believe that the author of this documentation thinks ASCII 32 is > printable, too. Thanks for this, I will make changes in the next iteration. > > About 'X' and 'Y', we can just say "the value of this capability may > consist of ASCII printable characters (from 33 to 126 inclusive)" or > something. > Noted. Thank you. > Is there a need for a registry of canonical os-version strings? One > reason why you would want this user-settable (as opposed to being > derived from "uname -s") is that a system that is presumably the > same in end-user perception can call itself in different names (your > Windows/MINGW64 example) and having the users set it to a string > chosen from a small repertoire, the other end would be able to > identify them more easily. I do not think it is a necessarily a > good idea to limit what value the users can set to this > configuration variable, but at least with a published guideline on > calling various types of systems (and an explanation on the reason > why we publish such a guideline), users would make an informed > decision when picking what string to send. We plan to implement another config option `osVersion.format`, which allow users to fully customize the string sent to the other side using placeholders, similar to how git for-each-ref uses %() syntax. The user would be able to set it to the string they want i.e "Linux" or "Windows" (without any placeholder) and would be sent as-is. So, the `osVersion.format` should satisfy this need. I will ensure to document this option to tell that it can be used like this and will give a small list of `os-version` strings that can be used in this way. > > > +# Trim and replace each character with ascii code below 32 or above > > +# 127 (included) using a dot '.' character. > > +# Octal intervals \001-\040 and \177-\377 > > +# corresponds to decimal intervals 1-32 and 127-255 > > +test_redact_non_printables () { > > + tr -d "\n" | tr "[\001-\040][\177-\377]" "." > > +} > > Just being curious. Do we need to worry about carriage-returns not > just line-feeds, and if not why? The function `tr "[\001-\040][\177-\377]" "."` already replace the carriage-returns with "." the redact_non_printables() will also replace it with ".". Carriage-returns octal code is 015 and decimal code of 13. So, we do not need to worry about it. > > Thanks. Thank you. Usman.
On Tue, Jan 7, 2025 at 4:47 AM Eric Sunshine <sunshine@sunshineco.com> wrote: > > On Mon, Jan 6, 2025 at 5:37 AM Usman Akinyemi > <usmanakinyemi202@gmail.com> wrote: > > As some issues that can happen with a Git client can be operating system > > specific, it can be useful for a server to know which OS a client is > > using. In the same way it can be useful for a client to know which OS > > a server is using. > > > > Let's introduce a new protocol (`os-version`) allowing Git clients and > > servers to exchange operating system information. The protocol is > > controlled by the new `transfer.advertiseOSVersion` config option. > > > > Add the `transfer.advertiseOSVersion` config option to address > > privacy concerns issue. It defaults to `true` and can be changed to > > `false`. When enabled, this option makes clients and servers send each > > other the OS name (e.g., "Linux" or "Windows"). The information is > > retrieved using the 'sysname' field of the `uname(2)` system call. > > > > However, there are differences between `uname(1)` (command-line utility) > > and `uname(2)` (system call) outputs on Windows. These discrepancies > > complicate testing on Windows platforms. For example: > > - `uname(1)` output: MINGW64_NT-10.0-20348.3.4.10-87d57229.x86_64\ > > .2024-02-14.20:17.UTC.x86_64 > > - `uname(2)` output: Windows.10.0.20348 > > > > Until a good way to test the feature on Windows is found, the > > transfer.advertiseOSVersion is set to false on Windows during testing. > > This is because the uname(2) you mention above is not actually > system-supplied but is instead faked up Git itself for the Git for > Windows port. See git/compat/mingw.c:uname(). > > The typical way to work around this sort of issue is to ensure that > you check Git against Git itself instead of checking Git against > "system". To do so, you would implement a new "test-util" command, say > `test-util uname`, in git/t/helpers/test-uname.c which internally > calls the same uname() function that other parts of Git call. Doing so > ensures consistency of output. > > Whether or not it makes sense to go through that extra work for this > particular case is a different question. Hi Eric, Thank you for the explanation. I will look into it. > > > Mentored-by: Christian Couder <chriscool@tuxfamily.org> > > Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com> > > --- > > diff --git a/t/t5555-http-smart-common.sh b/t/t5555-http-smart-common.sh > > @@ -123,9 +123,19 @@ test_expect_success 'git receive-pack --advertise-refs: v1' ' > > test_expect_success 'git upload-pack --advertise-refs: v2' ' > > + printf "agent=FAKE" >agent_and_os_name && > > + if test_have_prereq WINDOWS > > + then > > + # We do not use test_config here so that any tests below can reuse > > + # the "expect" file from this test > > + git config transfer.advertiseOSVersion false > > Should this have a comment explaining why you're disabling > transfer.advertiseOSVersion, in particular that you found uname() on > Windows unreliable, thus need to disable the check for this case? > > The comment you did compose exposes a fragility of the tests: in > particular that subsequent tests rely upon a side-effect of this test. > The fact that you had to include a special comment explaining the > problem argues for a cleaner solution, such as splitting out part of > this code into a separate test which comes before this one: > specifically, a "setup"-type test which creates the "expect" file > which gets reused by multiple tests. I will work on it and update it in the next iteration. Thank you very much. Usman. > > > + else > > + printf "\nos-version=%s\n" $(uname -s | test_redact_non_printables) >>agent_and_os_name > > + fi && > > diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh > > @@ -8,13 +8,23 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME > > test_expect_success 'test capability advertisement' ' > > + printf "agent=git/$(git version | cut -d" " -f3)" >agent_and_os_name && > > + if test_have_prereq WINDOWS > > + then > > + # We do not use test_config here so that tests below will be able to reuse > > + # the expect.base and expect.trailer files > > + git config transfer.advertiseOSVersion false > > Ditto. > > > + else > > + printf "\nos-version=%s\n" $(uname -s | test_redact_non_printables) >>agent_and_os_name > > + fi &&
Usman Akinyemi <usmanakinyemi202@gmail.com> writes: >> Is there a need for a registry of canonical os-version strings? One >> reason why you would want this user-settable (as opposed to being >> derived from "uname -s") is that a system that is presumably the >> same in end-user perception can call itself in different names (your >> Windows/MINGW64 example) and having the users set it to a string >> chosen from a small repertoire, the other end would be able to >> identify them more easily. I do not think it is a necessarily a >> good idea to limit what value the users can set to this >> configuration variable, but at least with a published guideline on >> calling various types of systems (and an explanation on the reason >> why we publish such a guideline), users would make an informed >> decision when picking what string to send. > > We plan to implement another config option `osVersion.format`, which > allow users to fully customize the string sent to the other side using > placeholders, Sorry, you lost me. I was wondering if we want to (informally at first) make it _less_ flexible, so that we can prevent people from being "creative" when the value of being creative is negative. Adding even more ways to customize the string to subject the receiving/inspecting end to more unnecessary variations to call the same thing in different names is the last thing we want to see in that context, isn't it? If you have "any random string goes" configuration mechanism, it is pretty much game over. You do not need to add an elaborate .format mechanism to let users throw random garbage at the other side of the connection. >> > +# Trim and replace each character with ascii code below 32 or above >> > +# 127 (included) using a dot '.' character. >> > +# Octal intervals \001-\040 and \177-\377 >> > +# corresponds to decimal intervals 1-32 and 127-255 >> > +test_redact_non_printables () { >> > + tr -d "\n" | tr "[\001-\040][\177-\377]" "." >> > +} >> >> Just being curious. Do we need to worry about carriage-returns not >> just line-feeds, and if not why? > The function `tr "[\001-\040][\177-\377]" "."` already replace the > carriage-returns with "." That is exactly my point. LF are stripped; I do not see a sensible reason why shouldn't CR be removed the same way. Thanks.
diff --git a/Documentation/config/transfer.txt b/Documentation/config/transfer.txt index f1ce50f4a6..e2d95d1ccd 100644 --- a/Documentation/config/transfer.txt +++ b/Documentation/config/transfer.txt @@ -125,3 +125,10 @@ transfer.bundleURI:: transfer.advertiseObjectInfo:: When `true`, the `object-info` capability is advertised by servers. Defaults to false. + +transfer.advertiseOSVersion:: + When `true`, the `os-version` capability is advertised by clients and + 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. diff --git a/Documentation/gitprotocol-v2.txt b/Documentation/gitprotocol-v2.txt index 1652fef3ae..c28262c60b 100644 --- a/Documentation/gitprotocol-v2.txt +++ b/Documentation/gitprotocol-v2.txt @@ -190,6 +190,26 @@ printable ASCII characters except space (i.e., the byte range 32 < x < and debugging purposes, and MUST NOT be used to programmatically assume the presence or absence of particular features. +os-version +~~~~~~~~~~ + +In the same way as the `agent` capability above, the server can +advertise the `os-version` capability with a value `X` (in the form +`os-version=X`) to notify the client that the server is running an +operating system that can be identified by `X`. The client may +optionally send its own `os-version` string by including the +`os-version` capability with a value `Y` (in the form `os-version=Y`) +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. + ls-refs ~~~~~~~ diff --git a/connect.c b/connect.c index 10fad43e98..6d5792b63c 100644 --- a/connect.c +++ b/connect.c @@ -492,6 +492,9 @@ static void send_capabilities(int fd_out, struct packet_reader *reader) if (server_supports_v2("agent")) packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized()); + if (server_supports_v2("os-version") && advertise_os_version(the_repository)) + packet_write_fmt(fd_out, "os-version=%s", os_version_sanitized()); + if (server_feature_v2("object-format", &hash_name)) { int hash_algo = hash_algo_by_name(hash_name); if (hash_algo == GIT_HASH_UNKNOWN) diff --git a/serve.c b/serve.c index c8694e3751..5b0d54ae9a 100644 --- a/serve.c +++ b/serve.c @@ -31,6 +31,16 @@ static int agent_advertise(struct repository *r UNUSED, return 1; } +static int os_version_advertise(struct repository *r, + struct strbuf *value) +{ + if (!advertise_os_version(r)) + return 0; + if (value) + strbuf_addstr(value, os_version_sanitized()); + return 1; +} + static int object_format_advertise(struct repository *r, struct strbuf *value) { @@ -123,6 +133,10 @@ static struct protocol_capability capabilities[] = { .name = "agent", .advertise = agent_advertise, }, + { + .name = "os-version", + .advertise = os_version_advertise, + }, { .name = "ls-refs", .advertise = ls_refs_advertise, diff --git a/t/t5555-http-smart-common.sh b/t/t5555-http-smart-common.sh index e47ea1ad10..f9e2a66cba 100755 --- a/t/t5555-http-smart-common.sh +++ b/t/t5555-http-smart-common.sh @@ -123,9 +123,19 @@ test_expect_success 'git receive-pack --advertise-refs: v1' ' ' test_expect_success 'git upload-pack --advertise-refs: v2' ' + printf "agent=FAKE" >agent_and_os_name && + if test_have_prereq WINDOWS + then + # We do not use test_config here so that any tests below can reuse + # the "expect" file from this test + git config transfer.advertiseOSVersion false + else + printf "\nos-version=%s\n" $(uname -s | test_redact_non_printables) >>agent_and_os_name + fi && + cat >expect <<-EOF && version 2 - agent=FAKE + $(cat agent_and_os_name) ls-refs=unborn fetch=shallow wait-for-done server-option diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh index de904c1655..f4668b7acd 100755 --- a/t/t5701-git-serve.sh +++ b/t/t5701-git-serve.sh @@ -8,13 +8,23 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh test_expect_success 'test capability advertisement' ' + printf "agent=git/$(git version | cut -d" " -f3)" >agent_and_os_name && + if test_have_prereq WINDOWS + then + # We do not use test_config here so that tests below will be able to reuse + # the expect.base and expect.trailer files + git config transfer.advertiseOSVersion false + else + printf "\nos-version=%s\n" $(uname -s | test_redact_non_printables) >>agent_and_os_name + fi && + test_oid_cache <<-EOF && wrong_algo sha1:sha256 wrong_algo sha256:sha1 EOF cat >expect.base <<-EOF && version 2 - agent=git/$(git version | cut -d" " -f3) + $(cat agent_and_os_name) ls-refs=unborn fetch=shallow wait-for-done server-option diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 78e054ab50..447c698d74 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -2007,3 +2007,11 @@ test_trailing_hash () { test-tool hexdump | sed "s/ //g" } + +# Trim and replace each character with ascii code below 32 or above +# 127 (included) using a dot '.' character. +# Octal intervals \001-\040 and \177-\377 +# corresponds to decimal intervals 1-32 and 127-255 +test_redact_non_printables () { + tr -d "\n" | tr "[\001-\040][\177-\377]" "." +} diff --git a/version.c b/version.c index 44ffc4dd57..8242baf41c 100644 --- a/version.c +++ b/version.c @@ -3,6 +3,7 @@ #include "version-def.h" #include "strbuf.h" #include "gettext.h" +#include "config.h" const char git_version_string[] = GIT_VERSION; const char git_built_from_commit_string[] = GIT_BUILT_FROM_COMMIT; @@ -70,3 +71,44 @@ int get_uname_info(struct strbuf *buf, unsigned int full) strbuf_addf(buf, "%s\n", uname_info.sysname); return 0; } + +const char *os_version(void) +{ + static const char *os = NULL; + + if (!os) { + struct strbuf buf = STRBUF_INIT; + + get_uname_info(&buf, 0); + os = strbuf_detach(&buf, NULL); + } + + return os; +} + +const char *os_version_sanitized(void) +{ + static const char *os_sanitized = NULL; + + if (!os_sanitized) { + struct strbuf buf = STRBUF_INIT; + + strbuf_addstr(&buf, os_version()); + redact_non_printables(&buf); + os_sanitized = strbuf_detach(&buf, NULL); + } + + return os_sanitized; +} + +int advertise_os_version(struct repository *r) +{ + static int transfer_advertise_os_version = -1; + + if (transfer_advertise_os_version == -1) { + repo_config_get_bool(r, "transfer.advertiseosversion", &transfer_advertise_os_version); + /* enabled by default */ + transfer_advertise_os_version = !!transfer_advertise_os_version; + } + return transfer_advertise_os_version; +} diff --git a/version.h b/version.h index 5eb586c0bd..8167ce956a 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,8 @@ #ifndef VERSION_H #define VERSION_H +struct repository; + extern const char git_version_string[]; extern const char git_built_from_commit_string[]; @@ -14,4 +16,8 @@ const char *git_user_agent_sanitized(void); */ int get_uname_info(struct strbuf *buf, unsigned int full); +const char *os_version(void); +const char *os_version_sanitized(void); +int advertise_os_version(struct repository *r); + #endif /* VERSION_H */
As some issues that can happen with a Git client can be operating system specific, it can be useful for a server to know which OS a client is using. In the same way it can be useful for a client to know which OS a server is using. Let's introduce a new protocol (`os-version`) allowing Git clients and servers to exchange operating system information. The protocol is controlled by the new `transfer.advertiseOSVersion` config option. Add the `transfer.advertiseOSVersion` config option to address privacy concerns issue. It defaults to `true` and can be changed to `false`. When enabled, this option makes clients and servers send each other the OS name (e.g., "Linux" or "Windows"). The information is retrieved using the 'sysname' field of the `uname(2)` system call. However, there are differences between `uname(1)` (command-line utility) and `uname(2)` (system call) outputs on Windows. These discrepancies complicate testing on Windows platforms. For example: - `uname(1)` output: MINGW64_NT-10.0-20348.3.4.10-87d57229.x86_64\ .2024-02-14.20:17.UTC.x86_64 - `uname(2)` output: Windows.10.0.20348 Until a good way to test the feature on Windows is found, the transfer.advertiseOSVersion is set to false on Windows during testing. Mentored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com> --- Documentation/config/transfer.txt | 7 ++++++ Documentation/gitprotocol-v2.txt | 20 +++++++++++++++ connect.c | 3 +++ serve.c | 14 +++++++++++ t/t5555-http-smart-common.sh | 12 ++++++++- t/t5701-git-serve.sh | 12 ++++++++- t/test-lib-functions.sh | 8 ++++++ version.c | 42 +++++++++++++++++++++++++++++++ version.h | 6 +++++ 9 files changed, 122 insertions(+), 2 deletions(-)