{"thread":{"id":"60509","subject":"[PATCH 00/13] Enabling z/OS workflow for git","startedAt":"2023-11-13T10:24:21Z","lastAt":"2023-12-05T20:58:43Z","messageCount":21,"participants":["Haritha via GitGitGadget","Haritha D via GitGitGadget","brian m. carlson","Junio C Hamano","Eric Sunshine","René Scharfe"],"isPatch":true,"patchVersion":1,"patchTotal":13},"messages":[{"id":"484786","messageId":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":null,"subject":"[PATCH 00/13] Enabling z/OS workflow for git","fromName":"Haritha via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:02Z","receivedAt":"2023-11-13T10:24:21Z","isPatch":true,"sender":{"key":"name:Haritha","avatar":null},"body":"z/OS is an IBM mainframe operating system, also known as OS/390. Our team\nhas been actively involved in porting Git to z/OS and we have made\nsignificant modifications to facilitate this process. The patch below is the\ninitial configuration for z/OS. I also have few follow up changes and I will\nsend that after these changes are approved. Please let me know if there are\nany concerns.\n\nHaritha D (13):\n  Enabling z/OS workflow for git\n  Enable builds for z/OS.\n  spaces and errors fix Handled git pipeline errors\n  fixes for build errors Handled git pipeline errorse\n  fixes for build errors\n  spaces and errors fix Handled git pipeline errors\n  spaces and errors fix Handled git pipeline errors\n  platform_name fix Handled git pipeline errors\n  strncpy fix Handled git pipeline errors\n  strncpy fix Handled git pipeline errors\n  strncpy fix Handled git pipeline errors\n  Handled git pipeline errors - Memory leak\n  Handled git pipeline errors - z/OS enable\n\n Makefile              | 21 +++++++++---\n builtin.h             |  3 ++\n builtin/archive.c     |  6 ++++\n builtin/hash-object.c | 28 +++++++++++++++\n combine-diff.c        |  4 +++\n config.c              |  7 ++++\n config.mak.uname      | 20 +++++++++++\n configure.ac          |  3 ++\n convert.c             | 58 +++++++++++++++++++++++++++----\n copy.c                |  3 ++\n diff.c                | 11 ++++++\n entry.c               | 26 ++++++++++++++\n environment.c         |  3 ++\n fetch-negotiator.h    |  2 +-\n fetch-pack.c          |  4 +--\n git-compat-util.h     |  8 +++++\n negotiator/default.c  |  4 +--\n negotiator/noop.c     |  4 +--\n negotiator/skipping.c |  4 +--\n object-file.c         | 80 ++++++++++++++++++++++++++++++++++++++++++-\n read-cache.c          |  3 ++\n utf8.c                | 11 ++++++\n 22 files changed, 292 insertions(+), 21 deletions(-)\n\n\nbase-commit: a9ecda2788e229afc9b611acaa26d0d9d4da53ed\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1537%2FHarithaIBM%2Fenablezos-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1537/HarithaIBM/enablezos-v1\nPull-Request: https://github.com/git/git/pull/1537\n-- \ngitgitgadget\n"},{"id":"484787","messageId":"712eb3712f1efb6f98b28bfe1e7d4f4f1aaa0152.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 01/13] Enabling z/OS workflow for git","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:03Z","receivedAt":"2023-11-13T10:24:21Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nOur team ported Git to z/OS w/ significant modifcation.\nThis patch is Initial Config\n\nSigned-off-by: Haritha D <harithamma.d@ibm.com>\n---\n config.mak.uname | 20 ++++++++++++++++++++\n 1 file changed, 20 insertions(+)\n\ndiff --git a/config.mak.uname b/config.mak.uname\nindex 3bb03f423a0..6ba9b707006 100644\n--- a/config.mak.uname\n+++ b/config.mak.uname\n@@ -625,6 +625,26 @@ ifeq ($(uname_S),NONSTOP_KERNEL)\n \tSANE_TOOL_PATH = /usr/coreutils/bin:/usr/local/bin\n \tSHELL_PATH = /usr/coreutils/bin/bash\n endif\n+\n+ifeq ($(uname_S),OS/390)\n+\tPERL_PATH = perl\n+\tPERL_PATH_FOR_SCRIPTS = /bin/env perl\n+\tSHELL_PATH = bash\n+\tSHELL_PATH_FOR_SCRIPTS = /bin/env bash\n+\tPYTHON_PATH = python\n+\tNO_SYS_POLL_H = YesPlease\n+\tNO_STRCASESTR = YesPlease\n+\tNO_REGEX = YesPlease\n+\tNO_MMAP = YesPlease\n+\tNO_NSEC = YesPlease\n+\tNO_STRLCPY = YesPlease\n+\tNO_MKDTEMP = YesPlease\n+\tNO_MEMMEM = YesPlease\n+\tNO_GECOS_IN_PWENT = YesPlease\n+\tHAVE_STRINGS_H = YesPlease\n+\tNEEDS_MODE_TRANSLATION = YesPlease\n+endif\n+\n ifeq ($(uname_S),MINGW)\n \tifeq ($(shell expr \"$(uname_R)\" : '1\\.'),2)\n \t\t$(error \"Building with MSys is no longer supported\")\n-- \ngitgitgadget\n\n"},{"id":"484788","messageId":"e31be0d764f47c21519016729259f8d74a53e21f.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 03/13] spaces and errors fix Handled git pipeline errors","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:05Z","receivedAt":"2023-11-13T10:24:23Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nThis PR has fixes to enable build on z/OS\n\nSigned-off-by: Harithamma D <harithamma.d@ibm.com>\n---\n builtin/hash-object.c |  6 +++---\n convert.c             | 22 +++++++++++++++++-----\n entry.c               | 22 +++++++++++-----------\n object-file.c         |  6 +++---\n 4 files changed, 34 insertions(+), 22 deletions(-)\n\ndiff --git a/builtin/hash-object.c b/builtin/hash-object.c\nindex b33b32ff977..9129658a37c 100644\n--- a/builtin/hash-object.c\n+++ b/builtin/hash-object.c\n@@ -62,8 +62,8 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags,\n #  include <stdio.h>\n #  include <stdlib.h>\n \n-   int setbinaryfd(int fd)\n-   {\n+int setbinaryfd(int fd)\n+{\n      attrib_t attr;\n      int rc;\n \n@@ -74,7 +74,7 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags,\n \n      rc = __fchattr(fd, &attr, sizeof(attr));\n      return rc;\n-   }\n+}\n #  endif\n #endif\n \ndiff --git a/convert.c b/convert.c\nindex 4f14ff6f1ed..17cc849efed 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1315,15 +1315,28 @@ static struct attr_check *check;\n \n static const char* get_platform() {\n \tstruct utsname uname_info;\n+\tchar *result;\n+\tif(!uname_info.sysname)\n+\t{\n+\t\tresult = (char *)malloc(strlen(uname_info.sysname)+1);\n+\t\tint index=0;\n+\t\twhile(index <= strlen(uname_info.sysname))\n+\t\t{\n+\t\t\t*result = uname_info.sysname[index];\n+\t\t\t++result;\n+\t\t\t++index;\n+\t\t}\n+\t}\n \n \tif (uname(&uname_info))\n \t\tdie(_(\"uname() failed with error '%s' (%d)\\n\"),\n \t\t\t    strerror(errno),\n \t\t\t    errno);\n \n-  if (!strcmp(uname_info.sysname, \"OS/390\"))\n-    return \"zos\";\n-  return uname_info.sysname;\n+\tif (!strcmp(uname_info.sysname, \"OS/390\"))\n+\t\tresult=\"zos\";\n+\n+\treturn result;\n }\n \n \n@@ -1331,11 +1344,10 @@ void convert_attrs(struct index_state *istate,\n \t\t   struct conv_attrs *ca, const char *path)\n {\n \tstruct attr_check_item *ccheck = NULL;\n-  struct strbuf platform_working_tree_encoding = STRBUF_INIT;\n+\tstruct strbuf platform_working_tree_encoding = STRBUF_INIT;\n \n \tstrbuf_addf(&platform_working_tree_encoding, \"%s-working-tree-encoding\", get_platform());\n \n-\n \tif (!check) {\n \t\tcheck = attr_check_initl(\"crlf\", \"ident\", \"filter\",\n \t\t\t\t\t \"eol\", \"text\", \"working-tree-encoding\", platform_working_tree_encoding.buf,\ndiff --git a/entry.c b/entry.c\nindex df6feb2234b..f2a7b2adbf5 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -130,17 +130,17 @@ int fstat_checkout_output(int fd, const struct checkout *state, struct stat *st)\n void tag_file_as_working_tree_encoding(struct index_state *istate, char* path, int fd) {\n \tstruct conv_attrs ca;\n \tconvert_attrs(istate, &ca, path);\n-  if (ca.attr_action != CRLF_BINARY) {\n-    if (ca.working_tree_encoding)\n-      __chgfdcodeset(fd, ca.working_tree_encoding);\n-    else\n-      __setfdtext(fd);\n-  }\n-  else {\n-    __setfdbinary(fd);\n-  }\n-\n-  __disableautocvt(fd);\n+\tif (ca.attr_action != CRLF_BINARY) {\n+\t\tif (ca.working_tree_encoding)\n+\t\t\t__chgfdcodeset(fd, ca.working_tree_encoding);\n+\t\telse\n+\t\t\t__setfdtext(fd);\n+\t}\n+\telse {\n+\t\t__setfdbinary(fd);\n+\t}\n+\n+\t__disableautocvt(fd);\n }\n #endif\n \ndiff --git a/object-file.c b/object-file.c\nindex 28e69ed1e33..562d1344422 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -2557,15 +2557,15 @@ int index_path(struct index_state *istate, struct object_id *oid,\n \tswitch (st->st_mode & S_IFMT) {\n \tcase S_IFREG:\n #ifdef __MVS__\n-    validate_codeset(istate, path, &autocvtToASCII);\n+\tvalidate_codeset(istate, path, &autocvtToASCII);\n #endif\n \t\tfd = open(path, O_RDONLY);\n \t\tif (fd < 0)\n \t\t\treturn error_errno(\"open(\\\"%s\\\")\", path);\n \n #ifdef __MVS__\n-   if (!autocvtToASCII)\n-     __disableautocvt(fd);\n+\tif (!autocvtToASCII)\n+\t\t__disableautocvt(fd);\n #endif\n \n \t\tif (index_fd(istate, oid, fd, st, OBJ_BLOB, path, flags) < 0)\n-- \ngitgitgadget\n\n"},{"id":"484789","messageId":"7bace397b4a4ea49c1ad5b931a0d07493fe44a16.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 04/13] fixes for build errors Handled git pipeline errorse","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:06Z","receivedAt":"2023-11-13T10:24:25Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nThis PR has fixes to enable build on z/OS\n\nSigned-off-by: Harithamma D <harithamma.d@ibm.com>\n---\n convert.c          | 4 ++--\n fetch-negotiator.h | 2 +-\n fetch-pack.c       | 2 +-\n 3 files changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/convert.c b/convert.c\nindex 17cc849efed..da05f6c2e51 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1313,13 +1313,13 @@ static int git_path_check_ident(struct attr_check_item *check)\n \n static struct attr_check *check;\n \n-static const char* get_platform() {\n+static const char* get_platform(void) {\n \tstruct utsname uname_info;\n \tchar *result;\n \tif(!uname_info.sysname)\n \t{\n-\t\tresult = (char *)malloc(strlen(uname_info.sysname)+1);\n \t\tint index=0;\n+\t\tresult = (char *)malloc(strlen(uname_info.sysname)+1);\n \t\twhile(index <= strlen(uname_info.sysname))\n \t\t{\n \t\t\t*result = uname_info.sysname[index];\ndiff --git a/fetch-negotiator.h b/fetch-negotiator.h\nindex e348905a1f0..2e19ef247f9 100644\n--- a/fetch-negotiator.h\n+++ b/fetch-negotiator.h\n@@ -47,7 +47,7 @@ struct fetch_negotiator {\n \t */\n \tint (*ack)(struct fetch_negotiator *, struct commit *);\n \n-\tvoid (*release)(struct fetch_negotiator *);\n+\tvoid (*release_negotiator)(struct fetch_negotiator *);\n \n \t/* internal use */\n \tvoid *data;\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex 26999e3b659..f40b90dfa65 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -1232,7 +1232,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,\n \n  all_done:\n \tif (negotiator)\n-\t\tnegotiator->release(negotiator);\n+\t\tnegotiator->release_negotiator(negotiator);\n \treturn ref;\n }\n \n-- \ngitgitgadget\n\n"},{"id":"484790","messageId":"3b6d1f8066841e87bbbd31c55226209e54c64e03.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 05/13] fixes for build errors","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:07Z","receivedAt":"2023-11-13T10:24:25Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nThis patch has fixes for build errors\n\nSigned-off-by: Haritha D <harithamma.d@ibm.com>\n---\n convert.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/convert.c b/convert.c\nindex da05f6c2e51..d3f204b4c29 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1315,8 +1315,8 @@ static struct attr_check *check;\n \n static const char* get_platform(void) {\n \tstruct utsname uname_info;\n-\tchar *result;\n-\tif(!uname_info.sysname)\n+\tchar *result = NULL;\n+\tif(!uname_info.sysname[0])\n \t{\n \t\tint index=0;\n \t\tresult = (char *)malloc(strlen(uname_info.sysname)+1);\n-- \ngitgitgadget\n\n"},{"id":"484791","messageId":"3c9b02e18d232fbccf27c4e95d8b3193ba9348a2.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 06/13] spaces and errors fix Handled git pipeline errors","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:08Z","receivedAt":"2023-11-13T10:24:25Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nThis PR has fixes to enable build on z/OS\n\nSigned-off-by: Harithamma D <harithamma.d@ibm.com>\n---\n convert.c    | 2 +-\n fetch-pack.c | 2 +-\n 2 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/convert.c b/convert.c\nindex d3f204b4c29..7fe107710ec 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1314,7 +1314,7 @@ static int git_path_check_ident(struct attr_check_item *check)\n static struct attr_check *check;\n \n static const char* get_platform(void) {\n-\tstruct utsname uname_info;\n+\tstruct utsname uname_info = {0};\n \tchar *result = NULL;\n \tif(!uname_info.sysname[0])\n \t{\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex f40b90dfa65..c1f2e714f8e 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -1853,7 +1853,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,\n \t\tdie(\"fsck failed\");\n \n \tif (negotiator)\n-\t\tnegotiator->release(negotiator);\n+\t\tnegotiator->release_negotiator(negotiator);\n \n \toidset_clear(&common);\n \treturn ref;\n-- \ngitgitgadget\n\n"},{"id":"484795","messageId":"098b9ca8ece4fdce45a9b48e576b474ed81dced1.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 02/13] Enable builds for z/OS.","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:04Z","receivedAt":"2023-11-13T10:24:25Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nThis commit enables git to build on z/OS.\nIt takes advantage of enahanced ASCII\nservices on z/OS to auto-convert input\nfiles to ASCII\nIt also adds support for\n[platform]-working-tree-encoding.\nPlatform is substituted with uname_info.sysname,\nso it will only apply to the given platform.\nAlso adds support for scripts that are not in\nstandard locations so that /bin/env bash\ncan be specified.\n\nSigned-off-by: Harithamma D <harithamma.d@ibm.com>\n---\n Makefile              | 21 +++++++++---\n builtin.h             |  3 ++\n builtin/archive.c     |  6 ++++\n builtin/hash-object.c | 28 +++++++++++++++\n combine-diff.c        |  4 +++\n config.c              |  7 ++++\n configure.ac          |  3 ++\n convert.c             | 44 ++++++++++++++++++++----\n copy.c                |  3 ++\n diff.c                | 11 ++++++\n entry.c               | 26 ++++++++++++++\n environment.c         |  3 ++\n git-compat-util.h     |  8 +++++\n negotiator/default.c  |  4 +--\n negotiator/noop.c     |  4 +--\n negotiator/skipping.c |  4 +--\n object-file.c         | 80 ++++++++++++++++++++++++++++++++++++++++++-\n read-cache.c          |  3 ++\n utf8.c                | 11 ++++++\n 19 files changed, 255 insertions(+), 18 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 9c6a2f125f8..30aa76da4f4 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -20,6 +20,8 @@ include shared.mak\n #\n # Define SHELL_PATH to a POSIX shell if your /bin/sh is broken.\n #\n+# Define SHELL_PATH_FOR_SCRIPTS to a POSIX shell if your /bin/sh is broken.\n+#\n # Define SANE_TOOL_PATH to a colon-separated list of paths to prepend\n # to PATH if your tools in /usr/bin are broken.\n #\n@@ -215,6 +217,8 @@ include shared.mak\n #\n # Define PERL_PATH to the path of your Perl binary (usually /usr/bin/perl).\n #\n+# Define PERL_PATH_FOR_SCRIPTS to a Perl binary if your /usr/bin/perl is broken.\n+#\n # Define NO_PERL if you do not want Perl scripts or libraries at all.\n #\n # Define NO_PERL_CPAN_FALLBACKS if you do not want to install bundled\n@@ -903,9 +907,15 @@ BINDIR_PROGRAMS_NO_X += git-cvsserver\n ifndef SHELL_PATH\n \tSHELL_PATH = /bin/sh\n endif\n+ifndef SHELL_PATH_FOR_SCRIPTS\n+\tSHELL_PATH_FOR_SCRIPTS = /bin/sh\n+endif\n ifndef PERL_PATH\n \tPERL_PATH = /usr/bin/perl\n endif\n+ifndef PERL_PATH_FOR_SCRIPTS\n+\tPERL_PATH_FOR_SCRIPTS = /usr/bin/perl\n+endif\n ifndef PYTHON_PATH\n \tPYTHON_PATH = /usr/bin/python\n endif\n@@ -1336,7 +1346,7 @@ THIRD_PARTY_SOURCES += sha1dc/%\n \n # xdiff and reftable libs may in turn depend on what is in libgit.a\n GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(LIB_FILE)\n-EXTLIBS =\n+EXTLIBS = $(ZOPEN_EXTRA_LIBS)\n \n GIT_USER_AGENT = git/$(GIT_VERSION)\n \n@@ -2226,9 +2236,10 @@ perllibdir_relative_SQ = $(subst ','\\'',$(perllibdir_relative))\n gitwebdir_SQ = $(subst ','\\'',$(gitwebdir))\n gitwebstaticdir_SQ = $(subst ','\\'',$(gitwebstaticdir))\n \n-SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n+SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH_FOR_SCRIPTS))\n TEST_SHELL_PATH_SQ = $(subst ','\\'',$(TEST_SHELL_PATH))\n PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n+PERL_PATH_FOR_SCRIPTS_SQ = $(subst ','\\'',$(PERL_PATH_FOR_SCRIPTS))\n PYTHON_PATH_SQ = $(subst ','\\'',$(PYTHON_PATH))\n TCLTK_PATH_SQ = $(subst ','\\'',$(TCLTK_PATH))\n DIFF_SQ = $(subst ','\\'',$(DIFF))\n@@ -2448,7 +2459,7 @@ hook-list.h: generate-hooklist.sh Documentation/githooks.txt\n \n SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):\\\n \t$(localedir_SQ):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\\\n-\t$(gitwebdir_SQ):$(PERL_PATH_SQ):$(PAGER_ENV):\\\n+\t$(gitwebdir_SQ):$(PERL_PATH_FOR_SCRIPTS_SQ):$(PAGER_ENV):\\\n \t$(perllibdir_SQ)\n GIT-SCRIPT-DEFINES: FORCE\n \t@FLAGS='$(SCRIPT_DEFINES)'; \\\n@@ -2465,7 +2476,7 @@ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n     -e 's/@@USE_GETTEXT_SCHEME@@/$(USE_GETTEXT_SCHEME)/g' \\\n     -e $(BROKEN_PATH_FIX) \\\n     -e 's|@@GITWEBDIR@@|$(gitwebdir_SQ)|g' \\\n-    -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \\\n+    -e 's|@@PERL@@|$(PERL_PATH_FOR_SCRIPTS_SQ)|g' \\\n     -e 's|@@PAGER_ENV@@|$(PAGER_ENV_SQ)|g' \\\n     $@.sh >$@+\n endef\n@@ -2519,7 +2530,7 @@ PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)\n $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \t$(QUIET_GEN) \\\n \tsed -e '1{' \\\n-\t    -e '\ts|#!.*perl|#!$(PERL_PATH_SQ)|' \\\n+\t    -e '\ts|#!.*perl|#!$(PERL_PATH_FOR_SCRIPTS_SQ)|' \\\n \t    -e '\tr GIT-PERL-HEADER' \\\n \t    -e '\tG' \\\n \t    -e '}' \\\ndiff --git a/builtin.h b/builtin.h\nindex d560baa6618..806af1a262d 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -250,5 +250,8 @@ int cmd_verify_pack(int argc, const char **argv, const char *prefix);\n int cmd_show_ref(int argc, const char **argv, const char *prefix);\n int cmd_pack_refs(int argc, const char **argv, const char *prefix);\n int cmd_replace(int argc, const char **argv, const char *prefix);\n+#ifdef __MVS__\n+  extern int setbinaryfd(int);\n+#endif\n \n #endif\ndiff --git a/builtin/archive.c b/builtin/archive.c\nindex 90761fdfee0..53ec794356f 100644\n--- a/builtin/archive.c\n+++ b/builtin/archive.c\n@@ -14,6 +14,12 @@\n static void create_output_file(const char *output_file)\n {\n \tint output_fd = xopen(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);\n+#ifdef __MVS__\n+ #if (__CHARSET_LIB == 1)\n+\tif (setbinaryfd(output_fd))\n+\t\tdie_errno(_(\"could not tag archive file '%s'\"), output_file);\n+ #endif\n+#endif\n \tif (output_fd != 1) {\n \t\tif (dup2(output_fd, 1) < 0)\n \t\t\tdie_errno(_(\"could not redirect output\"));\ndiff --git a/builtin/hash-object.c b/builtin/hash-object.c\nindex 5ffec99dcea..b33b32ff977 100644\n--- a/builtin/hash-object.c\n+++ b/builtin/hash-object.c\n@@ -57,11 +57,39 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags,\n \tmaybe_flush_or_die(stdout, \"hash to stdout\");\n }\n \n+#ifdef __MVS__\n+#  if (__CHARSET_LIB == 1)\n+#  include <stdio.h>\n+#  include <stdlib.h>\n+\n+   int setbinaryfd(int fd)\n+   {\n+     attrib_t attr;\n+     int rc;\n+\n+     memset(&attr, 0, sizeof(attr));\n+     attr.att_filetagchg = 1;\n+     attr.att_filetag.ft_ccsid = FT_BINARY;\n+     attr.att_filetag.ft_txtflag = 0;\n+\n+     rc = __fchattr(fd, &attr, sizeof(attr));\n+     return rc;\n+   }\n+#  endif\n+#endif\n+\n+\n static void hash_object(const char *path, const char *type, const char *vpath,\n \t\t\tunsigned flags, int literally)\n {\n \tint fd;\n \tfd = xopen(path, O_RDONLY);\n+#ifdef __MVS__\n+#  if (__CHARSET_LIB == 1)\n+  if (setbinaryfd(fd))\n+\t\tdie_errno(\"Cannot set to binary '%s'\", path);\n+#  endif\n+#endif\n \thash_fd(fd, type, vpath, flags, literally);\n }\n \ndiff --git a/combine-diff.c b/combine-diff.c\nindex f90f4424829..73445a517c7 100644\n--- a/combine-diff.c\n+++ b/combine-diff.c\n@@ -1082,6 +1082,10 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,\n \t\t\tssize_t done;\n \t\t\tint is_file, i;\n \n+#ifdef __MVS__\n+      __disableautocvt(fd);\n+#endif\n+\n \t\t\telem->mode = canon_mode(st.st_mode);\n \t\t\t/* if symlinks don't work, assume symlink if all parents\n \t\t\t * are symlinks\ndiff --git a/config.c b/config.c\nindex f9a1cca4e8a..37c124a37c0 100644\n--- a/config.c\n+++ b/config.c\n@@ -1521,6 +1521,13 @@ static int git_default_core_config(const char *var, const char *value,\n \t\treturn 0;\n \t}\n \n+\t#ifdef __MVS__\n+\tif (!strcmp(var, \"core.ignorefiletags\")) {\n+\t\tignore_file_tags = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n+\t#endif\n+\n \tif (!strcmp(var, \"core.safecrlf\")) {\n \t\tint eol_rndtrp_die;\n \t\tif (value && !strcasecmp(value, \"warn\")) {\ndiff --git a/configure.ac b/configure.ac\nindex 276593cd9dd..ed380504be6 100644\n--- a/configure.ac\n+++ b/configure.ac\n@@ -463,6 +463,9 @@ else\n             CC_LD_DYNPATH=-Wl,+b,\n           else\n              CC_LD_DYNPATH=\n+             if test \"$(uname -s)\" = \"OS/390\"; then\n+                CC_LD_DYNPATH=-L\n+             fi\n              AC_MSG_WARN([linker does not support runtime path to dynamic libraries])\n           fi\n       fi\ndiff --git a/convert.c b/convert.c\nindex a8870baff36..4f14ff6f1ed 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -377,12 +377,15 @@ static int check_roundtrip(const char *enc_name)\n static const char *default_encoding = \"UTF-8\";\n \n static int encode_to_git(const char *path, const char *src, size_t src_len,\n-\t\t\t struct strbuf *buf, const char *enc, int conv_flags)\n+\t\t\t struct strbuf *buf, const char *enc, enum convert_crlf_action attr_action, int conv_flags)\n {\n \tchar *dst;\n \tsize_t dst_len;\n \tint die_on_error = conv_flags & CONV_WRITE_OBJECT;\n \n+  if (attr_action == CRLF_BINARY) {\n+    return 0;\n+  }\n \t/*\n \t * No encoding is specified or there is nothing to encode.\n \t * Tell the caller that the content was not modified.\n@@ -403,6 +406,11 @@ static int encode_to_git(const char *path, const char *src, size_t src_len,\n \t\treturn 0;\n \n \ttrace_encoding(\"source\", path, enc, src, src_len);\n+#ifdef __MVS__\n+  // Don't convert ISO8859-1 on z/OS\n+  if (strcasecmp(\"ISO8859-1\", enc) == 0)\n+    return 0;\n+#endif\n \tdst = reencode_string_len(src, src_len, default_encoding, enc,\n \t\t\t\t  &dst_len);\n \tif (!dst) {\n@@ -468,11 +476,14 @@ static int encode_to_git(const char *path, const char *src, size_t src_len,\n }\n \n static int encode_to_worktree(const char *path, const char *src, size_t src_len,\n-\t\t\t      struct strbuf *buf, const char *enc)\n+\t\t\t      struct strbuf *buf, enum convert_crlf_action attr_action, const char *enc)\n {\n \tchar *dst;\n \tsize_t dst_len;\n \n+  if (attr_action == CRLF_BINARY) {\n+    return 0;\n+  }\n \t/*\n \t * No encoding is specified or there is nothing to encode.\n \t * Tell the caller that the content was not modified.\n@@ -1302,18 +1313,37 @@ static int git_path_check_ident(struct attr_check_item *check)\n \n static struct attr_check *check;\n \n+static const char* get_platform() {\n+\tstruct utsname uname_info;\n+\n+\tif (uname(&uname_info))\n+\t\tdie(_(\"uname() failed with error '%s' (%d)\\n\"),\n+\t\t\t    strerror(errno),\n+\t\t\t    errno);\n+\n+  if (!strcmp(uname_info.sysname, \"OS/390\"))\n+    return \"zos\";\n+  return uname_info.sysname;\n+}\n+\n+\n void convert_attrs(struct index_state *istate,\n \t\t   struct conv_attrs *ca, const char *path)\n {\n \tstruct attr_check_item *ccheck = NULL;\n+  struct strbuf platform_working_tree_encoding = STRBUF_INIT;\n+\n+\tstrbuf_addf(&platform_working_tree_encoding, \"%s-working-tree-encoding\", get_platform());\n+\n \n \tif (!check) {\n \t\tcheck = attr_check_initl(\"crlf\", \"ident\", \"filter\",\n-\t\t\t\t\t \"eol\", \"text\", \"working-tree-encoding\",\n+\t\t\t\t\t \"eol\", \"text\", \"working-tree-encoding\", platform_working_tree_encoding.buf,\n \t\t\t\t\t NULL);\n \t\tuser_convert_tail = &user_convert;\n \t\tgit_config(read_convert_config, NULL);\n \t}\n+\tstrbuf_release(&platform_working_tree_encoding);\n \n \tgit_check_attr(istate, path, check);\n \tccheck = check->items;\n@@ -1334,6 +1364,8 @@ void convert_attrs(struct index_state *istate,\n \t\t\tca->crlf_action = CRLF_TEXT_CRLF;\n \t}\n \tca->working_tree_encoding = git_path_check_encoding(ccheck + 5);\n+  if (git_path_check_encoding(ccheck + 6))\n+    ca->working_tree_encoding = git_path_check_encoding(ccheck + 6);\n \n \t/* Save attr and make a decision for action */\n \tca->attr_action = ca->crlf_action;\n@@ -1427,7 +1459,7 @@ int convert_to_git(struct index_state *istate,\n \t\tlen = dst->len;\n \t}\n \n-\tret |= encode_to_git(path, src, len, dst, ca.working_tree_encoding, conv_flags);\n+\tret |= encode_to_git(path, src, len, dst, ca.working_tree_encoding, ca.attr_action, conv_flags);\n \tif (ret && dst) {\n \t\tsrc = dst->buf;\n \t\tlen = dst->len;\n@@ -1455,7 +1487,7 @@ void convert_to_git_filter_fd(struct index_state *istate,\n \tif (!apply_filter(path, NULL, 0, fd, dst, ca.drv, CAP_CLEAN, NULL, NULL))\n \t\tdie(_(\"%s: clean filter '%s' failed\"), path, ca.drv->name);\n \n-\tencode_to_git(path, dst->buf, dst->len, dst, ca.working_tree_encoding, conv_flags);\n+\tencode_to_git(path, dst->buf, dst->len, dst, ca.working_tree_encoding, ca.attr_action, conv_flags);\n \tcrlf_to_git(istate, path, dst->buf, dst->len, dst, ca.crlf_action, conv_flags);\n \tident_to_git(dst->buf, dst->len, dst, ca.ident);\n }\n@@ -1487,7 +1519,7 @@ static int convert_to_working_tree_ca_internal(const struct conv_attrs *ca,\n \t\t}\n \t}\n \n-\tret |= encode_to_worktree(path, src, len, dst, ca->working_tree_encoding);\n+\tret |= encode_to_worktree(path, src, len, dst, ca->attr_action, ca->working_tree_encoding);\n \tif (ret) {\n \t\tsrc = dst->buf;\n \t\tlen = dst->len;\ndiff --git a/copy.c b/copy.c\nindex 23d84c6c1db..63546aecf81 100644\n--- a/copy.c\n+++ b/copy.c\n@@ -14,6 +14,9 @@ int copy_fd(int ifd, int ofd)\n \t\tif (write_in_full(ofd, buffer, len) < 0)\n \t\t\treturn COPY_WRITE_ERROR;\n \t}\n+#ifdef __MVS__\n+  __copyfdccsid(ifd, ofd);\n+#endif\n \treturn 0;\n }\n \ndiff --git a/diff.c b/diff.c\nindex 2c602df10a3..28b96d53dbc 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -4083,6 +4083,9 @@ int diff_populate_filespec(struct repository *r,\n \tint check_binary = options ? options->check_binary : 0;\n \tint err = 0;\n \tint conv_flags = global_conv_flags_eol;\n+#ifdef __MVS__\n+\tint autocvtToASCII;\n+#endif\n \t/*\n \t * demote FAIL to WARN to allow inspecting the situation\n \t * instead of refusing.\n@@ -4155,9 +4158,17 @@ int diff_populate_filespec(struct repository *r,\n \t\t\ts->is_binary = 1;\n \t\t\treturn 0;\n \t\t}\n+#ifdef __MVS__\n+    validate_codeset(r->index, s->path, &autocvtToASCII);\n+#endif\n \t\tfd = open(s->path, O_RDONLY);\n \t\tif (fd < 0)\n \t\t\tgoto err_empty;\n+\n+#ifdef __MVS__\n+    if (!autocvtToASCII)\n+      __disableautocvt(fd);\n+#endif\n \t\ts->data = xmmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0);\n \t\tclose(fd);\n \t\ts->should_munmap = 1;\ndiff --git a/entry.c b/entry.c\nindex 076e97eb89c..df6feb2234b 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -126,6 +126,24 @@ int fstat_checkout_output(int fd, const struct checkout *state, struct stat *st)\n \treturn 0;\n }\n \n+#ifdef __MVS__\n+void tag_file_as_working_tree_encoding(struct index_state *istate, char* path, int fd) {\n+\tstruct conv_attrs ca;\n+\tconvert_attrs(istate, &ca, path);\n+  if (ca.attr_action != CRLF_BINARY) {\n+    if (ca.working_tree_encoding)\n+      __chgfdcodeset(fd, ca.working_tree_encoding);\n+    else\n+      __setfdtext(fd);\n+  }\n+  else {\n+    __setfdbinary(fd);\n+  }\n+\n+  __disableautocvt(fd);\n+}\n+#endif\n+\n static int streaming_write_entry(const struct cache_entry *ce, char *path,\n \t\t\t\t struct stream_filter *filter,\n \t\t\t\t const struct checkout *state, int to_tempfile,\n@@ -138,6 +156,10 @@ static int streaming_write_entry(const struct cache_entry *ce, char *path,\n \tif (fd < 0)\n \t\treturn -1;\n \n+#ifdef __MVS__\n+  tag_file_as_working_tree_encoding(state->istate, path, fd);\n+#endif\n+\n \tresult |= stream_blob_to_fd(fd, &ce->oid, filter, 1);\n \t*fstat_done = fstat_checkout_output(fd, state, statbuf);\n \tresult |= close(fd);\n@@ -374,6 +396,10 @@ static int write_entry(struct cache_entry *ce, char *path, struct conv_attrs *ca\n \t\t\treturn error_errno(\"unable to create file %s\", path);\n \t\t}\n \n+#ifdef __MVS__\n+    tag_file_as_working_tree_encoding(state->istate, path, fd);\n+#endif\n+\n \t\twrote = write_in_full(fd, new_blob, size);\n \t\tif (!to_tempfile)\n \t\t\tfstat_done = fstat_checkout_output(fd, state, &st);\ndiff --git a/environment.c b/environment.c\nindex bb3c2a96a33..2e4d3a1e058 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -51,6 +51,9 @@ const char *git_hooks_path;\n int zlib_compression_level = Z_BEST_SPEED;\n int pack_compression_level = Z_DEFAULT_COMPRESSION;\n int fsync_object_files = -1;\n+#ifdef __MVS__\n+int ignore_file_tags = 0;\n+#endif\n int use_fsync = -1;\n enum fsync_method fsync_method = FSYNC_METHOD_DEFAULT;\n enum fsync_component fsync_components = FSYNC_COMPONENTS_DEFAULT;\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 3e7a59b5ff1..66e0abec24b 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -223,7 +223,15 @@ struct strbuf;\n #include <sys/stat.h>\n #include <fcntl.h>\n #include <stddef.h>\n+#ifdef __MVS__\n+#define release stdlib_release\n+#define fetch stdlib_fetch\n+#endif\n #include <stdlib.h>\n+#ifdef __MVS__\n+#undef fetch\n+#undef release\n+#endif\n #include <stdarg.h>\n #include <string.h>\n #ifdef HAVE_STRINGS_H\ndiff --git a/negotiator/default.c b/negotiator/default.c\nindex 9a5b6963272..b1f9f153372 100644\n--- a/negotiator/default.c\n+++ b/negotiator/default.c\n@@ -174,7 +174,7 @@ static int ack(struct fetch_negotiator *n, struct commit *c)\n \treturn known_to_be_common;\n }\n \n-static void release(struct fetch_negotiator *n)\n+static void release_negotiator(struct fetch_negotiator *n)\n {\n \tclear_prio_queue(&((struct negotiation_state *)n->data)->rev_list);\n \tFREE_AND_NULL(n->data);\n@@ -187,7 +187,7 @@ void default_negotiator_init(struct fetch_negotiator *negotiator)\n \tnegotiator->add_tip = add_tip;\n \tnegotiator->next = next;\n \tnegotiator->ack = ack;\n-\tnegotiator->release = release;\n+\tnegotiator->release_negotiator = release_negotiator;\n \tnegotiator->data = CALLOC_ARRAY(ns, 1);\n \tns->rev_list.compare = compare_commits_by_commit_date;\n \ndiff --git a/negotiator/noop.c b/negotiator/noop.c\nindex de39028ab7f..82089654d8b 100644\n--- a/negotiator/noop.c\n+++ b/negotiator/noop.c\n@@ -30,7 +30,7 @@ static int ack(struct fetch_negotiator *n UNUSED, struct commit *c UNUSED)\n \treturn 0;\n }\n \n-static void release(struct fetch_negotiator *n UNUSED)\n+static void release_negotiator(struct fetch_negotiator *n UNUSED)\n {\n \t/* nothing to release */\n }\n@@ -41,6 +41,6 @@ void noop_negotiator_init(struct fetch_negotiator *negotiator)\n \tnegotiator->add_tip = add_tip;\n \tnegotiator->next = next;\n \tnegotiator->ack = ack;\n-\tnegotiator->release = release;\n+\tnegotiator->release_negotiator = release_negotiator;\n \tnegotiator->data = NULL;\n }\ndiff --git a/negotiator/skipping.c b/negotiator/skipping.c\nindex 5b91520430c..783b3f27e63 100644\n--- a/negotiator/skipping.c\n+++ b/negotiator/skipping.c\n@@ -243,7 +243,7 @@ static int ack(struct fetch_negotiator *n, struct commit *c)\n \treturn known_to_be_common;\n }\n \n-static void release(struct fetch_negotiator *n)\n+static void release_negotiator(struct fetch_negotiator *n)\n {\n \tclear_prio_queue(&((struct data *)n->data)->rev_list);\n \tFREE_AND_NULL(n->data);\n@@ -256,7 +256,7 @@ void skipping_negotiator_init(struct fetch_negotiator *negotiator)\n \tnegotiator->add_tip = add_tip;\n \tnegotiator->next = next;\n \tnegotiator->ack = ack;\n-\tnegotiator->release = release;\n+\tnegotiator->release_negotiator = release_negotiator;\n \tnegotiator->data = CALLOC_ARRAY(data, 1);\n \tdata->rev_list.compare = compare;\n \ndiff --git a/object-file.c b/object-file.c\nindex 7c7afe57936..28e69ed1e33 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -43,7 +43,9 @@\n #include \"setup.h\"\n #include \"submodule.h\"\n #include \"fsck.h\"\n-\n+#ifdef __MVS__\n+#include <_Ccsid.h>\n+#endif\n /* The maximum size for an object header. */\n #define MAX_HEADER_LEN 32\n \n@@ -2478,6 +2480,68 @@ int index_fd(struct index_state *istate, struct object_id *oid,\n \treturn ret;\n }\n \n+#ifdef __MVS__\n+void validate_codeset(struct index_state *istate, const char *path, int* autoconvertToASCII) {\n+       struct conv_attrs ca;\n+  struct stat st;\n+  unsigned short attr_ccsid;\n+  unsigned short file_ccsid;\n+\n+  if (ignore_file_tags)\n+   return;\n+\n+  *autoconvertToASCII = 0;\n+       convert_attrs(istate, &ca, path);\n+  if (ca.attr_action == CRLF_BINARY) {\n+    attr_ccsid = FT_BINARY;\n+  }\n+  else if (ca.working_tree_encoding) {\n+    attr_ccsid = __toCcsid(ca.working_tree_encoding);\n+  }\n+  else\n+    attr_ccsid = 819;\n+\n+  if (stat(path, &st) < 0)\n+    return;\n+\n+  file_ccsid = st.st_tag.ft_ccsid;\n+\n+  if (file_ccsid == FT_UNTAGGED) {\n+    die(\"File %s is untagged, set the correct file tag (using the chtag command).\", path);\n+  }\n+\n+  if (attr_ccsid != file_ccsid) {\n+    if (file_ccsid == 1047 && attr_ccsid == 819) {\n+      *autoconvertToASCII = 1;\n+      return;\n+    }\n+    // Allow tag mixing of 819 and 1208\n+    if ((file_ccsid == 819 || file_ccsid == 1208) && (attr_ccsid == 1208 || attr_ccsid == 819)) {\n+      return;\n+    }\n+    // Don't check for binary files, just add them\n+    if (attr_ccsid == FT_BINARY)\n+      return;\n+\n+    char attr_csname[_XOPEN_PATH_MAX] = {0};\n+    char file_csname[_XOPEN_PATH_MAX] = {0};\n+    if (attr_ccsid != FT_BINARY) {\n+      __toCSName(attr_ccsid, attr_csname);\n+    } else {\n+      snprintf(attr_csname, _XOPEN_PATH_MAX, \"%s\", \"binary\");\n+    }\n+    if (file_ccsid != FT_BINARY) {\n+      __toCSName(file_ccsid, file_csname);\n+    } else {\n+      snprintf(file_csname, _XOPEN_PATH_MAX, \"%s\", \"binary\");\n+    }\n+    die(\"%s added file: file tag (%s) does not match working-tree-encoding (%s)\", path, file_csname, attr_csname);\n+  }\n+}\n+#endif\n+\n+\n+\n int index_path(struct index_state *istate, struct object_id *oid,\n \t       const char *path, struct stat *st, unsigned flags)\n {\n@@ -2485,11 +2549,25 @@ int index_path(struct index_state *istate, struct object_id *oid,\n \tstruct strbuf sb = STRBUF_INIT;\n \tint rc = 0;\n \n+#ifdef __MVS__\n+\tstruct conv_attrs ca;\n+\tint autocvtToASCII;\n+#endif\n+\n \tswitch (st->st_mode & S_IFMT) {\n \tcase S_IFREG:\n+#ifdef __MVS__\n+    validate_codeset(istate, path, &autocvtToASCII);\n+#endif\n \t\tfd = open(path, O_RDONLY);\n \t\tif (fd < 0)\n \t\t\treturn error_errno(\"open(\\\"%s\\\")\", path);\n+\n+#ifdef __MVS__\n+   if (!autocvtToASCII)\n+     __disableautocvt(fd);\n+#endif\n+\n \t\tif (index_fd(istate, oid, fd, st, OBJ_BLOB, path, flags) < 0)\n \t\t\treturn error(_(\"%s: failed to insert into database\"),\n \t\t\t\t     path);\ndiff --git a/read-cache.c b/read-cache.c\nindex 080bd39713b..75c06121302 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -205,6 +205,9 @@ static int ce_compare_data(struct index_state *istate,\n \tint fd = git_open_cloexec(ce->name, O_RDONLY);\n \n \tif (fd >= 0) {\n+#ifdef __MVS__\n+    __disableautocvt(fd);\n+#endif\n \t\tstruct object_id oid;\n \t\tif (!index_fd(istate, &oid, fd, st, OBJ_BLOB, ce->name, 0))\n \t\t\tmatch = !oideq(&oid, &ce->oid);\ndiff --git a/utf8.c b/utf8.c\nindex 6a0dd25b0fe..b9cb56abf14 100644\n--- a/utf8.c\n+++ b/utf8.c\n@@ -590,6 +590,17 @@ char *reencode_string_len(const char *in, size_t insz,\n #endif\n \t}\n \n+#ifdef __MVS__\n+  //HACK: For backwards compat, ISO8859-1 really means utf-8 in the z/OS world\n+  if (strcasecmp(\"ISO8859-1\", in_encoding) == 0) {\n+    in_encoding = \"UTF-8\";\n+    out_encoding = \"UTF-8\";\n+  }\n+  if (strcasecmp(\"ISO8859-1\", out_encoding) == 0) {\n+    in_encoding = \"UTF-8\";\n+    out_encoding = \"UTF-8\";\n+  }\n+#endif\n \tconv = iconv_open(out_encoding, in_encoding);\n \tif (conv == (iconv_t) -1) {\n \t\tin_encoding = fallback_encoding(in_encoding);\n-- \ngitgitgadget\n\n"},{"id":"484793","messageId":"8165196f869267ff35d2b252c20a622013b0fb04.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 07/13] spaces and errors fix Handled git pipeline errors","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:09Z","receivedAt":"2023-11-13T10:24:26Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nThis PR has fixes to enable build on z/OS\n\nSigned-off-by: Harithamma D <harithamma.d@ibm.com>\n---\n convert.c | 18 +++++++++++-------\n 1 file changed, 11 insertions(+), 7 deletions(-)\n\ndiff --git a/convert.c b/convert.c\nindex 7fe107710ec..c8d30011458 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1314,9 +1314,15 @@ static int git_path_check_ident(struct attr_check_item *check)\n static struct attr_check *check;\n \n static const char* get_platform(void) {\n-\tstruct utsname uname_info = {0};\n+\tstruct utsname uname_info;\n \tchar *result = NULL;\n-\tif(!uname_info.sysname[0])\n+\n+\tif (uname(&uname_info) < 0)\n+\t\tdie(_(\"uname() failed with error '%s' (%d)\\n\"),\n+\t\t\tstrerror(errno),\n+\t\t\terrno);\n+\n+\tif(*uname_info.sysname != '\\0')\n \t{\n \t\tint index=0;\n \t\tresult = (char *)malloc(strlen(uname_info.sysname)+1);\n@@ -1326,15 +1332,13 @@ static const char* get_platform(void) {\n \t\t\t++result;\n \t\t\t++index;\n \t\t}\n+\t\t*result = '\\0';\n \t}\n \n-\tif (uname(&uname_info))\n-\t\tdie(_(\"uname() failed with error '%s' (%d)\\n\"),\n-\t\t\t    strerror(errno),\n-\t\t\t    errno);\n-\n+#ifdef __MVS__\n \tif (!strcmp(uname_info.sysname, \"OS/390\"))\n \t\tresult=\"zos\";\n+#endif\n \n \treturn result;\n }\n-- \ngitgitgadget\n\n"},{"id":"484792","messageId":"9fb74d92e3f5b7209478c8040312277cc27431c1.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 08/13] platform_name fix Handled git pipeline errors","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:10Z","receivedAt":"2023-11-13T10:24:27Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nThis PR has fixes to enable build on z/OS\n\nSigned-off-by: Harithamma D <harithamma.d@ibm.com>\n---\n convert.c | 11 +++--------\n 1 file changed, 3 insertions(+), 8 deletions(-)\n\ndiff --git a/convert.c b/convert.c\nindex c8d30011458..9cd0c1382ac 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1321,19 +1321,14 @@ static const char* get_platform(void) {\n \t\tdie(_(\"uname() failed with error '%s' (%d)\\n\"),\n \t\t\tstrerror(errno),\n \t\t\terrno);\n-\n+#ifndef __MVS__\n \tif(*uname_info.sysname != '\\0')\n \t{\n \t\tint index=0;\n \t\tresult = (char *)malloc(strlen(uname_info.sysname)+1);\n-\t\twhile(index <= strlen(uname_info.sysname))\n-\t\t{\n-\t\t\t*result = uname_info.sysname[index];\n-\t\t\t++result;\n-\t\t\t++index;\n-\t\t}\n-\t\t*result = '\\0';\n+\t\tstrncpy(result, uname_info.sysname, strlen(uname_info.sysname));\n \t}\n+#endif\n \n #ifdef __MVS__\n \tif (!strcmp(uname_info.sysname, \"OS/390\"))\n-- \ngitgitgadget\n\n"},{"id":"484794","messageId":"8fa15ac45f78fbf0fda321a073a1020a471ee479.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 09/13] strncpy fix Handled git pipeline errors","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:11Z","receivedAt":"2023-11-13T10:24:27Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nThis PR has fixes to enable build on z/OS\n\nSigned-off-by: Harithamma D <harithamma.d@ibm.com>\n---\n convert.c | 8 +++++++-\n 1 file changed, 7 insertions(+), 1 deletion(-)\n\ndiff --git a/convert.c b/convert.c\nindex 9cd0c1382ac..78403de422d 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1326,7 +1326,13 @@ static const char* get_platform(void) {\n \t{\n \t\tint index=0;\n \t\tresult = (char *)malloc(strlen(uname_info.sysname)+1);\n-\t\tstrncpy(result, uname_info.sysname, strlen(uname_info.sysname));\n+\t\twhile(index <= strlen(uname_info.sysname))\n+\t\t{\n+\t\t\t*result = uname_info.sysname[index];\n+\t\t\t++result;\n+\t\t\t++index;\n+\t\t}\n+\t\t*result = '\\0';\n \t}\n #endif\n \n-- \ngitgitgadget\n\n"},{"id":"484796","messageId":"63479fe36966bf3b1a8dbc3ae68f8558da4690bc.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 10/13] strncpy fix Handled git pipeline errors","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:12Z","receivedAt":"2023-11-13T10:24:29Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nThis PR has fixes to enable build on z/OS\n\nSigned-off-by: Harithamma D <harithamma.d@ibm.com>\n---\n convert.c | 10 +++-------\n 1 file changed, 3 insertions(+), 7 deletions(-)\n\ndiff --git a/convert.c b/convert.c\nindex 78403de422d..ef44e6429da 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1326,13 +1326,10 @@ static const char* get_platform(void) {\n \t{\n \t\tint index=0;\n \t\tresult = (char *)malloc(strlen(uname_info.sysname)+1);\n-\t\twhile(index <= strlen(uname_info.sysname))\n+\t\twhile(result[index] = uname_info.sysname[index])\n \t\t{\n-\t\t\t*result = uname_info.sysname[index];\n-\t\t\t++result;\n-\t\t\t++index;\n+\t\t\tindex++;\n \t\t}\n-\t\t*result = '\\0';\n \t}\n #endif\n \n@@ -1340,8 +1337,7 @@ static const char* get_platform(void) {\n \tif (!strcmp(uname_info.sysname, \"OS/390\"))\n \t\tresult=\"zos\";\n #endif\n-\n-\treturn result;\n+\treturn (char*)result;\n }\n \n \n-- \ngitgitgadget\n\n"},{"id":"484797","messageId":"25271363e573f05e390ec09bfd3906730cae30e6.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 11/13] strncpy fix Handled git pipeline errors","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:13Z","receivedAt":"2023-11-13T10:24:30Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nThis PR has fixes to enable build on z/OS\n\nSigned-off-by: Harithamma D <harithamma.d@ibm.com>\n---\n convert.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/convert.c b/convert.c\nindex ef44e6429da..16173a1caf6 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1326,8 +1326,9 @@ static const char* get_platform(void) {\n \t{\n \t\tint index=0;\n \t\tresult = (char *)malloc(strlen(uname_info.sysname)+1);\n-\t\twhile(result[index] = uname_info.sysname[index])\n+\t\twhile(index <= strlen(uname_info.sysname))\n \t\t{\n+\t\t\tresult[index] = uname_info.sysname[index];\n \t\t\tindex++;\n \t\t}\n \t}\n-- \ngitgitgadget\n\n"},{"id":"484798","messageId":"06658ebad1027cdc72d9dc013b7a022245dd22c9.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 12/13] Handled git pipeline errors - Memory leak","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:14Z","receivedAt":"2023-11-13T10:24:31Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nThis PR has fixes to enable build on z/OS\n\nSigned-off-by: Harithamma D <harithamma.d@ibm.com>\n---\n convert.c | 18 ++++++++++--------\n 1 file changed, 10 insertions(+), 8 deletions(-)\n\ndiff --git a/convert.c b/convert.c\nindex 16173a1caf6..4c034bb714c 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1313,9 +1313,9 @@ static int git_path_check_ident(struct attr_check_item *check)\n \n static struct attr_check *check;\n \n-static const char* get_platform(void) {\n+static void get_platform(char** result) {\n \tstruct utsname uname_info;\n-\tchar *result = NULL;\n+\t*result = NULL;\n \n \tif (uname(&uname_info) < 0)\n \t\tdie(_(\"uname() failed with error '%s' (%d)\\n\"),\n@@ -1325,10 +1325,10 @@ static const char* get_platform(void) {\n \tif(*uname_info.sysname != '\\0')\n \t{\n \t\tint index=0;\n-\t\tresult = (char *)malloc(strlen(uname_info.sysname)+1);\n+\t\t*result = (char *)malloc(strlen(uname_info.sysname)+1);\n \t\twhile(index <= strlen(uname_info.sysname))\n \t\t{\n-\t\t\tresult[index] = uname_info.sysname[index];\n+\t\t\t(*result)[index] = uname_info.sysname[index];\n \t\t\tindex++;\n \t\t}\n \t}\n@@ -1336,9 +1336,8 @@ static const char* get_platform(void) {\n \n #ifdef __MVS__\n \tif (!strcmp(uname_info.sysname, \"OS/390\"))\n-\t\tresult=\"zos\";\n+\t\t*result = \"zos\";\n #endif\n-\treturn (char*)result;\n }\n \n \n@@ -1347,8 +1346,11 @@ void convert_attrs(struct index_state *istate,\n {\n \tstruct attr_check_item *ccheck = NULL;\n \tstruct strbuf platform_working_tree_encoding = STRBUF_INIT;\n-\n-\tstrbuf_addf(&platform_working_tree_encoding, \"%s-working-tree-encoding\", get_platform());\n+\tchar* result=NULL;\n+\tget_platform(&result);\n+\tstrbuf_addf(&platform_working_tree_encoding, \"%s-working-tree-encoding\", result);\n+\tif (result != NULL)\n+\t\tfree (result);\n \n \tif (!check) {\n \t\tcheck = attr_check_initl(\"crlf\", \"ident\", \"filter\",\n-- \ngitgitgadget\n\n"},{"id":"484799","messageId":"804624950aee9112b2ba88dd8f489b91a5392ad3.1699871056.git.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH 13/13] Handled git pipeline errors - z/OS enable","fromName":"Haritha D via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-13T10:24:15Z","receivedAt":"2023-11-13T10:24:32Z","isPatch":true,"sender":{"key":"harithamma.d@ibm.com","avatar":"https://avatars.githubusercontent.com/u/112700353?v=4"},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nThis PR has fixes to enable build on z/OS\n\nSigned-off-by: Harithamma D <harithamma.d@ibm.com>\n---\n convert.c | 6 ++----\n 1 file changed, 2 insertions(+), 4 deletions(-)\n\ndiff --git a/convert.c b/convert.c\nindex 4c034bb714c..c66f5b3ecec 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1315,7 +1315,6 @@ static struct attr_check *check;\n \n static void get_platform(char** result) {\n \tstruct utsname uname_info;\n-\t*result = NULL;\n \n \tif (uname(&uname_info) < 0)\n \t\tdie(_(\"uname() failed with error '%s' (%d)\\n\"),\n@@ -1346,11 +1345,10 @@ void convert_attrs(struct index_state *istate,\n {\n \tstruct attr_check_item *ccheck = NULL;\n \tstruct strbuf platform_working_tree_encoding = STRBUF_INIT;\n-\tchar* result=NULL;\n+\tchar* result=\"Unknown\";\n \tget_platform(&result);\n \tstrbuf_addf(&platform_working_tree_encoding, \"%s-working-tree-encoding\", result);\n-\tif (result != NULL)\n-\t\tfree (result);\n+\tfree (result);\n \n \tif (!check) {\n \t\tcheck = attr_check_initl(\"crlf\", \"ident\", \"filter\",\n-- \ngitgitgadget\n"},{"id":"484823","messageId":"ZVKrWSv7JguKTSYw@tapette.crustytoothpaste.net","threadId":"60509","inReplyTo":"098b9ca8ece4fdce45a9b48e576b474ed81dced1.1699871056.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 02/13] Enable builds for z/OS.","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2023-11-13T23:03:53Z","receivedAt":"2023-11-13T23:04:00Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2023-11-13 at 10:24:04, Haritha D via GitGitGadget wrote:\n> From: Haritha D <harithamma.d@ibm.com>\n> \n> This commit enables git to build on z/OS.\n> It takes advantage of enahanced ASCII\n> services on z/OS to auto-convert input\n> files to ASCII\n\nIn general, we don't want to convert files to ASCII, since we assume\ntext files are UTF-8 unless otherwise specified.  If you're suggesting\nthat your system is normally EBCDIC, changing that should be an initial\npiece of setup code or something used in `xopen` on your platform so it\napplies everywhere with minimal changes.\n\n> It also adds support for\n> [platform]-working-tree-encoding.\n> Platform is substituted with uname_info.sysname,\n> so it will only apply to the given platform.\n\nI think this is going to need to be a separate patch and feature with\nits own explanation of why it's valuable.\n\n> Also adds support for scripts that are not in\n> standard locations so that /bin/env bash\n> can be specified.\n\n\n> Signed-off-by: Harithamma D <harithamma.d@ibm.com>\n> ---\n>  Makefile              | 21 +++++++++---\n>  builtin.h             |  3 ++\n>  builtin/archive.c     |  6 ++++\n>  builtin/hash-object.c | 28 +++++++++++++++\n>  combine-diff.c        |  4 +++\n>  config.c              |  7 ++++\n>  configure.ac          |  3 ++\n>  convert.c             | 44 ++++++++++++++++++++----\n>  copy.c                |  3 ++\n>  diff.c                | 11 ++++++\n>  entry.c               | 26 ++++++++++++++\n>  environment.c         |  3 ++\n>  git-compat-util.h     |  8 +++++\n>  negotiator/default.c  |  4 +--\n>  negotiator/noop.c     |  4 +--\n>  negotiator/skipping.c |  4 +--\n>  object-file.c         | 80 ++++++++++++++++++++++++++++++++++++++++++-\n>  read-cache.c          |  3 ++\n>  utf8.c                | 11 ++++++\n>  19 files changed, 255 insertions(+), 18 deletions(-)\n> \n> diff --git a/Makefile b/Makefile\n> index 9c6a2f125f8..30aa76da4f4 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -20,6 +20,8 @@ include shared.mak\n>  #\n>  # Define SHELL_PATH to a POSIX shell if your /bin/sh is broken.\n>  #\n> +# Define SHELL_PATH_FOR_SCRIPTS to a POSIX shell if your /bin/sh is broken.\n> +#\n>  # Define SANE_TOOL_PATH to a colon-separated list of paths to prepend\n>  # to PATH if your tools in /usr/bin are broken.\n>  #\n> @@ -215,6 +217,8 @@ include shared.mak\n>  #\n>  # Define PERL_PATH to the path of your Perl binary (usually /usr/bin/perl).\n>  #\n> +# Define PERL_PATH_FOR_SCRIPTS to a Perl binary if your /usr/bin/perl is broken.\n\nYou will probably want to explain in your commit message why these two\nare required to be different from the standard values and explain here\nwhat the relevant difference is so that users can set them\nappropriately.\n\n> diff --git a/builtin/archive.c b/builtin/archive.c\n> index 90761fdfee0..53ec794356f 100644\n> --- a/builtin/archive.c\n> +++ b/builtin/archive.c\n> @@ -14,6 +14,12 @@\n>  static void create_output_file(const char *output_file)\n>  {\n>  \tint output_fd = xopen(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);\n> +#ifdef __MVS__\n> + #if (__CHARSET_LIB == 1)\n> +\tif (setbinaryfd(output_fd))\n> +\t\tdie_errno(_(\"could not tag archive file '%s'\"), output_file);\n> + #endif\n> +#endif\n\nThis would be better to place in `xopen` itself so that all files are\ncorrectly configured.  That would do well as its own patch, and you'd\nwant to explain well in the commit message what this function does, why\nit's necessary, and what the consequences of not using it are, as well\nas any alternatives that you've rejected.\n\n>  \tif (output_fd != 1) {\n>  \t\tif (dup2(output_fd, 1) < 0)\n>  \t\t\tdie_errno(_(\"could not redirect output\"));\n> diff --git a/builtin/hash-object.c b/builtin/hash-object.c\n> index 5ffec99dcea..b33b32ff977 100644\n> --- a/builtin/hash-object.c\n> +++ b/builtin/hash-object.c\n> @@ -57,11 +57,39 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags,\n>  \tmaybe_flush_or_die(stdout, \"hash to stdout\");\n>  }\n>  \n> +#ifdef __MVS__\n> +#  if (__CHARSET_LIB == 1)\n> +#  include <stdio.h>\n> +#  include <stdlib.h>\n\nWe typically don't include the standard headers here.  Instead, they're\nincluded by git-compat-util.h because on some systems they have to be\nincluded in a certain order with certain options.  If you include that\nheader instead at the top of the file, or one of the headers that\nincludes it, then typically that should do the right thing.\n\n> +   int setbinaryfd(int fd)\n> +   {\n> +     attrib_t attr;\n> +     int rc;\n> +\n> +     memset(&attr, 0, sizeof(attr));\n> +     attr.att_filetagchg = 1;\n> +     attr.att_filetag.ft_ccsid = FT_BINARY;\n> +     attr.att_filetag.ft_txtflag = 0;\n> +\n> +     rc = __fchattr(fd, &attr, sizeof(attr));\n> +     return rc;\n> +   }\n> +#  endif\n> +#endif\n\nI would think a comment explaining what this function does and why it's\nnecessary would be appropriate, since it's not in POSIX and isn't\ntypically necessary on POSIX systems.\n\n> diff --git a/combine-diff.c b/combine-diff.c\n> index f90f4424829..73445a517c7 100644\n> --- a/combine-diff.c\n> +++ b/combine-diff.c\n> @@ -1082,6 +1082,10 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,\n>  \t\t\tssize_t done;\n>  \t\t\tint is_file, i;\n>  \n> +#ifdef __MVS__\n> +      __disableautocvt(fd);\n> +#endif\n\nAgain, if this can be centralized, it should be, and it should be\nexplained well in the commit message.  I'm uncertain what it does or\nwhat value it provides.\n\n> diff --git a/config.c b/config.c\n> index f9a1cca4e8a..37c124a37c0 100644\n> --- a/config.c\n> +++ b/config.c\n> @@ -1521,6 +1521,13 @@ static int git_default_core_config(const char *var, const char *value,\n>  \t\treturn 0;\n>  \t}\n>  \n> +\t#ifdef __MVS__\n> +\tif (!strcmp(var, \"core.ignorefiletags\")) {\n> +\t\tignore_file_tags = git_config_bool(var, value);\n> +\t\treturn 0;\n> +\t}\n> +\t#endif\n\nThis should also live in its own patch and the commit message should\nexplain what it does.  We'd also want it to be documented in the config\noptions in the Documentation directory.\n\n> diff --git a/convert.c b/convert.c\n> index a8870baff36..4f14ff6f1ed 100644\n> --- a/convert.c\n> +++ b/convert.c\n> @@ -377,12 +377,15 @@ static int check_roundtrip(const char *enc_name)\n>  static const char *default_encoding = \"UTF-8\";\n>  \n>  static int encode_to_git(const char *path, const char *src, size_t src_len,\n> -\t\t\t struct strbuf *buf, const char *enc, int conv_flags)\n> +\t\t\t struct strbuf *buf, const char *enc, enum convert_crlf_action attr_action, int conv_flags)\n>  {\n>  \tchar *dst;\n>  \tsize_t dst_len;\n>  \tint die_on_error = conv_flags & CONV_WRITE_OBJECT;\n>  \n> +  if (attr_action == CRLF_BINARY) {\n> +    return 0;\n> +  }\n\nI'm pretty sure this is a change in behaviour from what we had before.\nIt should live in its own patch, with an explanation in the commit\nmessage why it's a compelling and correct change overall, and with\nsuitable tests.\n\n>  \t/*\n>  \t * No encoding is specified or there is nothing to encode.\n>  \t * Tell the caller that the content was not modified.\n> @@ -403,6 +406,11 @@ static int encode_to_git(const char *path, const char *src, size_t src_len,\n>  \t\treturn 0;\n>  \n>  \ttrace_encoding(\"source\", path, enc, src, src_len);\n> +#ifdef __MVS__\n> +  // Don't convert ISO8859-1 on z/OS\n> +  if (strcasecmp(\"ISO8859-1\", enc) == 0)\n> +    return 0;\n> +#endif\n\nThis definitely needs explanation in the commit message and should\nprobably be its own patch, explaining why z/OS has this compelling need\nto not convert ISO8859-1.  Note that ISO8859-1 is not the same as \"no\nbinary conversion\", since it doesn't include many control codes.\n\nNote that if, as it says later on, this really means \"UTF-8\", that's a\nplatform wart you'd want to paper over in a file in the compat code.  In\ngeneral, the compat directory is a good place to put anything that your\nplatform needs specifically.\n\n> +static const char* get_platform() {\n> +\tstruct utsname uname_info;\n> +\n> +\tif (uname(&uname_info))\n> +\t\tdie(_(\"uname() failed with error '%s' (%d)\\n\"),\n> +\t\t\t    strerror(errno),\n> +\t\t\t    errno);\n> +\n> +  if (!strcmp(uname_info.sysname, \"OS/390\"))\n> +    return \"zos\";\n> +  return uname_info.sysname;\n> +}\n\nThis is definitely a new feature, and I'm not sure why it's necessary or\nuseful.  I suspect there's something about z/OS that makes it valuable,\nbut I don't know what it is since the commit message doesn't tell me.\nI'm also not sure that these values will be correct on Windows.\n\nI think I could go on to make similar comments about the rest of this\nseries.  I'm not opposed to seeing z/OS changes come in, but you've\namalgamated at least a half-dozen separate patches into one and haven't\nexplained them very thoroughly in the commit message.\n\nI'd generally want to look at the commit message and understand the\nproblem the code is trying to solve and then look at the code and think,\n\"Oh, yes, this seems like the obvious and logical way to solve this\nproblem,\" or at least think, \"Oh, no, I think we should solve this\nproblem in a different way,\" so I can help make a thoughtful review\ncomment.  Right now, I lack the information to have an informed opinion\nand so I can't provide any helpful feedback or analysis of the patches.\n\nWhen you're adding new features or fixing bugs, we'll also want tests\nfor those cases to help us avoid regressing that code in the future.\nEven if we don't normally run the testsuite on z/OS, at least _you_ will\nnotice that the tests have failed and then we'll be able to address the\nbugs in a timely manner.\n\nI also noted that there were some fixup commits later on in the series\nthat address whitespace issues.  Typically, we'd want to squash those in\nto the earlier patches.  Nobody expects perfection, but squashing errors\ninto earlier patches helps us keep the history neat and let us pretend\nlike you never made those errors at all.  It also lets tools like git\nblame and git bisect work more nicely for users.\n\nI'd recommend a quick pass over the SubmittingPatches file, which is\nalso available at https://git-scm.com/docs/SubmittingPatches.  The\nsections on making separate commits for separate changes and describing\nchanges well come to mind as places to focus.\n\nI know this may seem overwhelming and like I'm upset or disappointed;\nI'm definitely not.  I'm very much interested in seeing Git available\nfor more platforms, but right now it's too hard for me to reason about\nthe changes for z/OS to provide helpful feedback, so I'm hoping you can\nsend a fixed v2 that helps me (and everyone else) understand these\nchanges better so you can get a helpful review.\n-- \nbrian m. carlson (he/him or they/them)\nToronto, Ontario, CA\n"},{"id":"484831","messageId":"xmqqpm0d2mpa.fsf@gitster.g","threadId":"60509","inReplyTo":"e31be0d764f47c21519016729259f8d74a53e21f.1699871056.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 03/13] spaces and errors fix Handled git pipeline errors","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-11-14T00:38:41Z","receivedAt":"2023-11-14T00:38:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Haritha D via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> Subject: Re: [PATCH 03/13] spaces and errors fix Handled git pipeline errors\n\n-ECANNOTPARSE.  Perhaps Documentation/CodingGuidelines and\n Documentation/SubmittingPatches may help?\n\n> From: Haritha D <harithamma.d@ibm.com>\n>\n> This PR has fixes to enable build on z/OS\n\nThis is way under-explained.  Your proposed log message should be\nable to answer when somebody asks \"Is anything broken in the\nexisting codebase to cause your build to fail, or is it your\ncompiler toolchain that is broken?\" but the above does not help\nunderstanding what and why you needed to fix at all.\n\n> diff --git a/builtin/hash-object.c b/builtin/hash-object.c\n> index b33b32ff977..9129658a37c 100644\n> --- a/builtin/hash-object.c\n> +++ b/builtin/hash-object.c\n> @@ -62,8 +62,8 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags,\n>  #  include <stdio.h>\n>  #  include <stdlib.h>\n>  \n> -   int setbinaryfd(int fd)\n> -   {\n> +int setbinaryfd(int fd)\n> +{\n>       attrib_t attr;\n>       int rc;\n>  \n> @@ -74,7 +74,7 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags,\n>  \n>       rc = __fchattr(fd, &attr, sizeof(attr));\n>       return rc;\n> -   }\n> +}\n>  #  endif\n>  #endif\n\nNo such function in our codebase.  Are you fixing somebody else's\nforked version of Git and we shouldn't even be looking at this\npatch, perhaps?\n\n> diff --git a/convert.c b/convert.c\n> index 4f14ff6f1ed..17cc849efed 100644\n> --- a/convert.c\n> +++ b/convert.c\n> @@ -1315,15 +1315,28 @@ static struct attr_check *check;\n>  \n>  static const char* get_platform() {\n>  \tstruct utsname uname_info;\n> +\tchar *result;\n> +\tif(!uname_info.sysname)\n> +\t{\n> +\t\tresult = (char *)malloc(strlen(uname_info.sysname)+1);\n> +\t\tint index=0;\n> +\t\twhile(index <= strlen(uname_info.sysname))\n> +\t\t{\n> +\t\t\t*result = uname_info.sysname[index];\n> +\t\t\t++result;\n> +\t\t\t++index;\n> +\t\t}\n> +\t}\n\nNo such function in our codebase.  I doubt these patches have much\nrelevance to this project?\n\nI'll stop here.\n"},{"id":"484832","messageId":"xmqqcywd2m9i.fsf@gitster.g","threadId":"60509","inReplyTo":"098b9ca8ece4fdce45a9b48e576b474ed81dced1.1699871056.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 02/13] Enable builds for z/OS.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-11-14T00:48:09Z","receivedAt":"2023-11-14T00:48:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Haritha D via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> Subject: Re: [PATCH 02/13] Enable builds for z/OS.\n\nDocumentation/CodingGuidelines and Documentation/SubmittingPatches\nwould help here, I think.\n\n>  # Define SHELL_PATH to a POSIX shell if your /bin/sh is broken.\n>  #\n> +# Define SHELL_PATH_FOR_SCRIPTS to a POSIX shell if your /bin/sh is broken.\n\nThe reason to exist for the _FOR_SCRIPTS variants is not justified\nanywhere in the proposed log message.\n\nThe former should be sufficient, and our policy is to let the\nbuilder specify exactly what binaries the build products depend on,\n(instead of random $PATH interfere with the choice by using\n\"#!/bin/env tool\" that also has to assume that everybody's \"env\" is\ninstalled in \"/bin\").\n\nThis patch has too many #ifdefs in the primary codepaths.  Your\nporting strategy may need to be rethought.  Our usual convention is\nto encapsulate these platform differences as much as possible in\ngit-compat-util.h and platform specific files in compat/ directory.\n\n> diff --git a/builtin/hash-object.c b/builtin/hash-object.c\n> index 5ffec99dcea..b33b32ff977 100644\n> --- a/builtin/hash-object.c\n> +++ b/builtin/hash-object.c\n> @@ -57,11 +57,39 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags,\n>  \tmaybe_flush_or_die(stdout, \"hash to stdout\");\n>  }\n>  \n> +#ifdef __MVS__\n> +#  if (__CHARSET_LIB == 1)\n> +#  include <stdio.h>\n> +#  include <stdlib.h>\n> +\n> +   int setbinaryfd(int fd)\n> +   {\n> +     attrib_t attr;\n> +     int rc;\n\nAhh, OK, I saw [03/13] first and was utterly confused by this thing.\nDo not send in such a mess that introduces broken code in an early\nstep that you need to later say \"oops that one was broken and I need\nto fix it up with this patch\".  \"rebase -i\" is your friend to clean\nup your mess into a logical progression to help readers better\nunderstand what you wrote.\n\nI'll stop here.\n"},{"id":"484837","messageId":"xmqqleb114xs.fsf@gitster.g","threadId":"60509","inReplyTo":"ZVKrWSv7JguKTSYw@tapette.crustytoothpaste.net","subject":"Re: [PATCH 02/13] Enable builds for z/OS.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-11-14T01:47:43Z","receivedAt":"2023-11-14T01:47:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"brian m. carlson\" <sandals@crustytoothpaste.net> writes:\n\n> I'd generally want to look at the commit message and understand the\n> problem the code is trying to solve and then look at the code and think,\n> \"Oh, yes, this seems like the obvious and logical way to solve this\n> problem,\" or at least think, \"Oh, no, I think we should solve this\n> problem in a different way,\" so I can help make a thoughtful review\n> comment.  Right now, I lack the information to have an informed opinion\n> and so I can't provide any helpful feedback or analysis of the patches.\n> ...\n> I'd recommend a quick pass over the SubmittingPatches file, which is\n> also available at https://git-scm.com/docs/SubmittingPatches.  The\n> sections on making separate commits for separate changes and describing\n> changes well come to mind as places to focus.\n>\n> I know this may seem overwhelming and like I'm upset or disappointed;\n> I'm definitely not.  I'm very much interested in seeing Git available\n> for more platforms, but right now it's too hard for me to reason about\n> the changes for z/OS to provide helpful feedback, so I'm hoping you can\n> send a fixed v2 that helps me (and everyone else) understand these\n> changes better so you can get a helpful review.\n\nAll very good pieces of advice.  I suspect we are missing some of\nthem from our SubmittingPatches or CodingGuidelines documents and\nmay want to add them there.\n\nThanks.\n"},{"id":"485351","messageId":"pull.1537.v2.git.git.1701699574054.gitgitgadget@gmail.com","threadId":"60509","inReplyTo":"pull.1537.git.git.1699871056.gitgitgadget@gmail.com","subject":"[PATCH v2] This PR enables a successful git build on z/OS.","fromName":"Haritha via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-12-04T14:19:33Z","receivedAt":"2023-12-04T14:19:38Z","isPatch":true,"sender":{"key":"name:Haritha","avatar":null},"body":"From: Haritha D <harithamma.d@ibm.com>\n\nRename functions like \"release\" and \"fetch\"\ndue to conflict in z/OS standard C libraries.\nAlso disables autoconversion facility on z/OS\nand relies on iconv.\nNew files created in binary format are also\ntagged as binary.\n\nSigned-off-by: Haritha D <harithamma.d@ibm.com>\n---\n    Enabling z/OS workflow for git\n    \n    z/OS is an IBM mainframe operating system, also known as OS/390. Our\n    team has been actively involved in porting Git to z/OS and we have made\n    significant modifications to facilitate this process. The patch below is\n    the initial configuration for z/OS. I also have few follow up changes\n    and I will send that after these changes are approved. Please let me\n    know if there are any concerns.\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1537%2FHarithaIBM%2Fenablezos-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1537/HarithaIBM/enablezos-v2\nPull-Request: https://github.com/git/git/pull/1537\n\nRange-diff vs v1:\n\n  1:  712eb3712f1 <  -:  ----------- Enabling z/OS workflow for git\n  2:  098b9ca8ece !  1:  b9882d90c5d Enable builds for z/OS.\n     @@ Metadata\n      Author: Haritha D <harithamma.d@ibm.com>\n      \n       ## Commit message ##\n     -    Enable builds for z/OS.\n     +    This PR enables a successful git build on z/OS.\n      \n     -    This commit enables git to build on z/OS.\n     -    It takes advantage of enahanced ASCII\n     -    services on z/OS to auto-convert input\n     -    files to ASCII\n     -    It also adds support for\n     -    [platform]-working-tree-encoding.\n     -    Platform is substituted with uname_info.sysname,\n     -    so it will only apply to the given platform.\n     -    Also adds support for scripts that are not in\n     -    standard locations so that /bin/env bash\n     -    can be specified.\n     +    Rename functions like \"release\" and \"fetch\"\n     +    due to conflict in z/OS standard C libraries.\n     +    Also disables autoconversion facility on z/OS\n     +    and relies on iconv.\n     +    New files created in binary format are also\n     +    tagged as binary.\n      \n     -    Signed-off-by: Harithamma D <harithamma.d@ibm.com>\n     -\n     - ## Makefile ##\n     -@@ Makefile: include shared.mak\n     - #\n     - # Define SHELL_PATH to a POSIX shell if your /bin/sh is broken.\n     - #\n     -+# Define SHELL_PATH_FOR_SCRIPTS to a POSIX shell if your /bin/sh is broken.\n     -+#\n     - # Define SANE_TOOL_PATH to a colon-separated list of paths to prepend\n     - # to PATH if your tools in /usr/bin are broken.\n     - #\n     -@@ Makefile: include shared.mak\n     - #\n     - # Define PERL_PATH to the path of your Perl binary (usually /usr/bin/perl).\n     - #\n     -+# Define PERL_PATH_FOR_SCRIPTS to a Perl binary if your /usr/bin/perl is broken.\n     -+#\n     - # Define NO_PERL if you do not want Perl scripts or libraries at all.\n     - #\n     - # Define NO_PERL_CPAN_FALLBACKS if you do not want to install bundled\n     -@@ Makefile: BINDIR_PROGRAMS_NO_X += git-cvsserver\n     - ifndef SHELL_PATH\n     - \tSHELL_PATH = /bin/sh\n     - endif\n     -+ifndef SHELL_PATH_FOR_SCRIPTS\n     -+\tSHELL_PATH_FOR_SCRIPTS = /bin/sh\n     -+endif\n     - ifndef PERL_PATH\n     - \tPERL_PATH = /usr/bin/perl\n     - endif\n     -+ifndef PERL_PATH_FOR_SCRIPTS\n     -+\tPERL_PATH_FOR_SCRIPTS = /usr/bin/perl\n     -+endif\n     - ifndef PYTHON_PATH\n     - \tPYTHON_PATH = /usr/bin/python\n     - endif\n     -@@ Makefile: THIRD_PARTY_SOURCES += sha1dc/%\n     - \n     - # xdiff and reftable libs may in turn depend on what is in libgit.a\n     - GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(LIB_FILE)\n     --EXTLIBS =\n     -+EXTLIBS = $(ZOPEN_EXTRA_LIBS)\n     - \n     - GIT_USER_AGENT = git/$(GIT_VERSION)\n     - \n     -@@ Makefile: perllibdir_relative_SQ = $(subst ','\\'',$(perllibdir_relative))\n     - gitwebdir_SQ = $(subst ','\\'',$(gitwebdir))\n     - gitwebstaticdir_SQ = $(subst ','\\'',$(gitwebstaticdir))\n     - \n     --SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n     -+SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH_FOR_SCRIPTS))\n     - TEST_SHELL_PATH_SQ = $(subst ','\\'',$(TEST_SHELL_PATH))\n     - PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n     -+PERL_PATH_FOR_SCRIPTS_SQ = $(subst ','\\'',$(PERL_PATH_FOR_SCRIPTS))\n     - PYTHON_PATH_SQ = $(subst ','\\'',$(PYTHON_PATH))\n     - TCLTK_PATH_SQ = $(subst ','\\'',$(TCLTK_PATH))\n     - DIFF_SQ = $(subst ','\\'',$(DIFF))\n     -@@ Makefile: hook-list.h: generate-hooklist.sh Documentation/githooks.txt\n     - \n     - SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):\\\n     - \t$(localedir_SQ):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\\\n     --\t$(gitwebdir_SQ):$(PERL_PATH_SQ):$(PAGER_ENV):\\\n     -+\t$(gitwebdir_SQ):$(PERL_PATH_FOR_SCRIPTS_SQ):$(PAGER_ENV):\\\n     - \t$(perllibdir_SQ)\n     - GIT-SCRIPT-DEFINES: FORCE\n     - \t@FLAGS='$(SCRIPT_DEFINES)'; \\\n     -@@ Makefile: sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n     -     -e 's/@@USE_GETTEXT_SCHEME@@/$(USE_GETTEXT_SCHEME)/g' \\\n     -     -e $(BROKEN_PATH_FIX) \\\n     -     -e 's|@@GITWEBDIR@@|$(gitwebdir_SQ)|g' \\\n     --    -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \\\n     -+    -e 's|@@PERL@@|$(PERL_PATH_FOR_SCRIPTS_SQ)|g' \\\n     -     -e 's|@@PAGER_ENV@@|$(PAGER_ENV_SQ)|g' \\\n     -     $@.sh >$@+\n     - endef\n     -@@ Makefile: PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)\n     - $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n     - \t$(QUIET_GEN) \\\n     - \tsed -e '1{' \\\n     --\t    -e '\ts|#!.*perl|#!$(PERL_PATH_SQ)|' \\\n     -+\t    -e '\ts|#!.*perl|#!$(PERL_PATH_FOR_SCRIPTS_SQ)|' \\\n     - \t    -e '\tr GIT-PERL-HEADER' \\\n     - \t    -e '\tG' \\\n     - \t    -e '}' \\\n     -\n     - ## builtin.h ##\n     -@@ builtin.h: int cmd_verify_pack(int argc, const char **argv, const char *prefix);\n     - int cmd_show_ref(int argc, const char **argv, const char *prefix);\n     - int cmd_pack_refs(int argc, const char **argv, const char *prefix);\n     - int cmd_replace(int argc, const char **argv, const char *prefix);\n     -+#ifdef __MVS__\n     -+  extern int setbinaryfd(int);\n     -+#endif\n     - \n     - #endif\n     +    Signed-off-by: Haritha D <harithamma.d@ibm.com>\n      \n       ## builtin/archive.c ##\n      @@\n     @@ builtin/archive.c\n       {\n       \tint output_fd = xopen(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);\n      +#ifdef __MVS__\n     -+ #if (__CHARSET_LIB == 1)\n     -+\tif (setbinaryfd(output_fd))\n     ++\t/*\n     ++\t * Since the data is in binary format,\n     ++\t * we need to set the z/OS file tag\n     ++\t * to binary to disable autoconversion\n     ++\t */\n     ++\tif (__setfdbinary(output_fd))\n      +\t\tdie_errno(_(\"could not tag archive file '%s'\"), output_file);\n     -+ #endif\n      +#endif\n       \tif (output_fd != 1) {\n       \t\tif (dup2(output_fd, 1) < 0)\n       \t\t\tdie_errno(_(\"could not redirect output\"));\n      \n       ## builtin/hash-object.c ##\n     -@@ builtin/hash-object.c: static void hash_fd(int fd, const char *type, const char *path, unsigned flags,\n     - \tmaybe_flush_or_die(stdout, \"hash to stdout\");\n     - }\n     - \n     -+#ifdef __MVS__\n     -+#  if (__CHARSET_LIB == 1)\n     -+#  include <stdio.h>\n     -+#  include <stdlib.h>\n     -+\n     -+   int setbinaryfd(int fd)\n     -+   {\n     -+     attrib_t attr;\n     -+     int rc;\n     -+\n     -+     memset(&attr, 0, sizeof(attr));\n     -+     attr.att_filetagchg = 1;\n     -+     attr.att_filetag.ft_ccsid = FT_BINARY;\n     -+     attr.att_filetag.ft_txtflag = 0;\n     -+\n     -+     rc = __fchattr(fd, &attr, sizeof(attr));\n     -+     return rc;\n     -+   }\n     -+#  endif\n     -+#endif\n     -+\n     -+\n     - static void hash_object(const char *path, const char *type, const char *vpath,\n     - \t\t\tunsigned flags, int literally)\n     +@@ builtin/hash-object.c: static void hash_object(const char *path, const char *type, const char *vpath,\n       {\n       \tint fd;\n       \tfd = xopen(path, O_RDONLY);\n      +#ifdef __MVS__\n     -+#  if (__CHARSET_LIB == 1)\n     -+  if (setbinaryfd(fd))\n     ++\t/*\n     ++\t * Since the data being read is in binary format,\n     ++\t * we need to disable autoconversion for z/OS\n     ++\t */\n     ++\tif (__setfdbinary(fd))\n      +\t\tdie_errno(\"Cannot set to binary '%s'\", path);\n     -+#  endif\n      +#endif\n       \thash_fd(fd, type, vpath, flags, literally);\n       }\n     @@ combine-diff.c: static void show_patch_diff(struct combine_diff_path *elem, int\n       \t\t\tssize_t done;\n       \t\t\tint is_file, i;\n       \n     -+#ifdef __MVS__\n     -+      __disableautocvt(fd);\n     -+#endif\n     ++\t\t#ifdef __MVS__\n     ++\t\t\t/*\n     ++\t\t\t * Disable implicit autconversion on z/os,\n     ++\t\t\t * rely on conversion from iconv\n     ++\t\t\t */\n     ++\t\t\t__disableautocvt(fd);\n     ++\t\t#endif\n      +\n       \t\t\telem->mode = canon_mode(st.st_mode);\n       \t\t\t/* if symlinks don't work, assume symlink if all parents\n       \t\t\t * are symlinks\n      \n     - ## config.c ##\n     -@@ config.c: static int git_default_core_config(const char *var, const char *value,\n     - \t\treturn 0;\n     - \t}\n     - \n     -+\t#ifdef __MVS__\n     -+\tif (!strcmp(var, \"core.ignorefiletags\")) {\n     -+\t\tignore_file_tags = git_config_bool(var, value);\n     -+\t\treturn 0;\n     -+\t}\n     -+\t#endif\n     -+\n     - \tif (!strcmp(var, \"core.safecrlf\")) {\n     - \t\tint eol_rndtrp_die;\n     - \t\tif (value && !strcasecmp(value, \"warn\")) {\n     -\n     - ## configure.ac ##\n     -@@ configure.ac: else\n     -             CC_LD_DYNPATH=-Wl,+b,\n     -           else\n     -              CC_LD_DYNPATH=\n     -+             if test \"$(uname -s)\" = \"OS/390\"; then\n     -+                CC_LD_DYNPATH=-L\n     -+             fi\n     -              AC_MSG_WARN([linker does not support runtime path to dynamic libraries])\n     -           fi\n     -       fi\n     -\n     - ## convert.c ##\n     -@@ convert.c: static int check_roundtrip(const char *enc_name)\n     - static const char *default_encoding = \"UTF-8\";\n     - \n     - static int encode_to_git(const char *path, const char *src, size_t src_len,\n     --\t\t\t struct strbuf *buf, const char *enc, int conv_flags)\n     -+\t\t\t struct strbuf *buf, const char *enc, enum convert_crlf_action attr_action, int conv_flags)\n     - {\n     - \tchar *dst;\n     - \tsize_t dst_len;\n     - \tint die_on_error = conv_flags & CONV_WRITE_OBJECT;\n     - \n     -+  if (attr_action == CRLF_BINARY) {\n     -+    return 0;\n     -+  }\n     - \t/*\n     - \t * No encoding is specified or there is nothing to encode.\n     - \t * Tell the caller that the content was not modified.\n     -@@ convert.c: static int encode_to_git(const char *path, const char *src, size_t src_len,\n     - \t\treturn 0;\n     - \n     - \ttrace_encoding(\"source\", path, enc, src, src_len);\n     -+#ifdef __MVS__\n     -+  // Don't convert ISO8859-1 on z/OS\n     -+  if (strcasecmp(\"ISO8859-1\", enc) == 0)\n     -+    return 0;\n     -+#endif\n     - \tdst = reencode_string_len(src, src_len, default_encoding, enc,\n     - \t\t\t\t  &dst_len);\n     - \tif (!dst) {\n     -@@ convert.c: static int encode_to_git(const char *path, const char *src, size_t src_len,\n     - }\n     - \n     - static int encode_to_worktree(const char *path, const char *src, size_t src_len,\n     --\t\t\t      struct strbuf *buf, const char *enc)\n     -+\t\t\t      struct strbuf *buf, enum convert_crlf_action attr_action, const char *enc)\n     - {\n     - \tchar *dst;\n     - \tsize_t dst_len;\n     - \n     -+  if (attr_action == CRLF_BINARY) {\n     -+    return 0;\n     -+  }\n     - \t/*\n     - \t * No encoding is specified or there is nothing to encode.\n     - \t * Tell the caller that the content was not modified.\n     -@@ convert.c: static int git_path_check_ident(struct attr_check_item *check)\n     - \n     - static struct attr_check *check;\n     - \n     -+static const char* get_platform() {\n     -+\tstruct utsname uname_info;\n     -+\n     -+\tif (uname(&uname_info))\n     -+\t\tdie(_(\"uname() failed with error '%s' (%d)\\n\"),\n     -+\t\t\t    strerror(errno),\n     -+\t\t\t    errno);\n     -+\n     -+  if (!strcmp(uname_info.sysname, \"OS/390\"))\n     -+    return \"zos\";\n     -+  return uname_info.sysname;\n     -+}\n     -+\n     -+\n     - void convert_attrs(struct index_state *istate,\n     - \t\t   struct conv_attrs *ca, const char *path)\n     - {\n     - \tstruct attr_check_item *ccheck = NULL;\n     -+  struct strbuf platform_working_tree_encoding = STRBUF_INIT;\n     -+\n     -+\tstrbuf_addf(&platform_working_tree_encoding, \"%s-working-tree-encoding\", get_platform());\n     -+\n     - \n     - \tif (!check) {\n     - \t\tcheck = attr_check_initl(\"crlf\", \"ident\", \"filter\",\n     --\t\t\t\t\t \"eol\", \"text\", \"working-tree-encoding\",\n     -+\t\t\t\t\t \"eol\", \"text\", \"working-tree-encoding\", platform_working_tree_encoding.buf,\n     - \t\t\t\t\t NULL);\n     - \t\tuser_convert_tail = &user_convert;\n     - \t\tgit_config(read_convert_config, NULL);\n     - \t}\n     -+\tstrbuf_release(&platform_working_tree_encoding);\n     - \n     - \tgit_check_attr(istate, path, check);\n     - \tccheck = check->items;\n     -@@ convert.c: void convert_attrs(struct index_state *istate,\n     - \t\t\tca->crlf_action = CRLF_TEXT_CRLF;\n     - \t}\n     - \tca->working_tree_encoding = git_path_check_encoding(ccheck + 5);\n     -+  if (git_path_check_encoding(ccheck + 6))\n     -+    ca->working_tree_encoding = git_path_check_encoding(ccheck + 6);\n     - \n     - \t/* Save attr and make a decision for action */\n     - \tca->attr_action = ca->crlf_action;\n     -@@ convert.c: int convert_to_git(struct index_state *istate,\n     - \t\tlen = dst->len;\n     - \t}\n     - \n     --\tret |= encode_to_git(path, src, len, dst, ca.working_tree_encoding, conv_flags);\n     -+\tret |= encode_to_git(path, src, len, dst, ca.working_tree_encoding, ca.attr_action, conv_flags);\n     - \tif (ret && dst) {\n     - \t\tsrc = dst->buf;\n     - \t\tlen = dst->len;\n     -@@ convert.c: void convert_to_git_filter_fd(struct index_state *istate,\n     - \tif (!apply_filter(path, NULL, 0, fd, dst, ca.drv, CAP_CLEAN, NULL, NULL))\n     - \t\tdie(_(\"%s: clean filter '%s' failed\"), path, ca.drv->name);\n     - \n     --\tencode_to_git(path, dst->buf, dst->len, dst, ca.working_tree_encoding, conv_flags);\n     -+\tencode_to_git(path, dst->buf, dst->len, dst, ca.working_tree_encoding, ca.attr_action, conv_flags);\n     - \tcrlf_to_git(istate, path, dst->buf, dst->len, dst, ca.crlf_action, conv_flags);\n     - \tident_to_git(dst->buf, dst->len, dst, ca.ident);\n     - }\n     -@@ convert.c: static int convert_to_working_tree_ca_internal(const struct conv_attrs *ca,\n     - \t\t}\n     - \t}\n     - \n     --\tret |= encode_to_worktree(path, src, len, dst, ca->working_tree_encoding);\n     -+\tret |= encode_to_worktree(path, src, len, dst, ca->attr_action, ca->working_tree_encoding);\n     - \tif (ret) {\n     - \t\tsrc = dst->buf;\n     - \t\tlen = dst->len;\n     -\n       ## copy.c ##\n      @@ copy.c: int copy_fd(int ifd, int ofd)\n       \t\tif (write_in_full(ofd, buffer, len) < 0)\n       \t\t\treturn COPY_WRITE_ERROR;\n       \t}\n     -+#ifdef __MVS__\n     -+  __copyfdccsid(ifd, ofd);\n     -+#endif\n     ++\t#ifdef __MVS__\n     ++\t\t/*\n     ++\t\t * This is to ensure that file tags are copied\n     ++\t\t * from source to destination\n     ++\t\t */\n     ++\t\t__copyfdccsid(ifd, ofd);\n     ++\t#endif\n       \treturn 0;\n       }\n       \n      \n     - ## diff.c ##\n     -@@ diff.c: int diff_populate_filespec(struct repository *r,\n     - \tint check_binary = options ? options->check_binary : 0;\n     - \tint err = 0;\n     - \tint conv_flags = global_conv_flags_eol;\n     -+#ifdef __MVS__\n     -+\tint autocvtToASCII;\n     -+#endif\n     - \t/*\n     - \t * demote FAIL to WARN to allow inspecting the situation\n     - \t * instead of refusing.\n     -@@ diff.c: int diff_populate_filespec(struct repository *r,\n     - \t\t\ts->is_binary = 1;\n     - \t\t\treturn 0;\n     - \t\t}\n     -+#ifdef __MVS__\n     -+    validate_codeset(r->index, s->path, &autocvtToASCII);\n     -+#endif\n     - \t\tfd = open(s->path, O_RDONLY);\n     - \t\tif (fd < 0)\n     - \t\t\tgoto err_empty;\n     -+\n     -+#ifdef __MVS__\n     -+    if (!autocvtToASCII)\n     -+      __disableautocvt(fd);\n     -+#endif\n     - \t\ts->data = xmmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0);\n     - \t\tclose(fd);\n     - \t\ts->should_munmap = 1;\n     -\n     - ## entry.c ##\n     -@@ entry.c: int fstat_checkout_output(int fd, const struct checkout *state, struct stat *st)\n     - \treturn 0;\n     + ## fetch-negotiator.h ##\n     +@@ fetch-negotiator.h: struct repository;\n     +  * Then, when \"have\" lines are required, call next(). Call ack() to report what\n     +  * the server tells us.\n     +  *\n     +- * Once negotiation is done, call release(). The negotiator then cannot be used\n     ++ * Once negotiation is done, call release_negotiator(). The negotiator then cannot be used\n     +  * (unless reinitialized with fetch_negotiator_init()).\n     +  */\n     + struct fetch_negotiator {\n     +@@ fetch-negotiator.h: struct fetch_negotiator {\n     + \t */\n     + \tint (*ack)(struct fetch_negotiator *, struct commit *);\n     + \n     +-\tvoid (*release)(struct fetch_negotiator *);\n     ++\tvoid (*release_negotiator)(struct fetch_negotiator *);\n     + \n     + \t/* internal use */\n     + \tvoid *data;\n     +\n     + ## fetch-pack.c ##\n     +@@ fetch-pack.c: static struct ref *do_fetch_pack(struct fetch_pack_args *args,\n     + \n     +  all_done:\n     + \tif (negotiator)\n     +-\t\tnegotiator->release(negotiator);\n     ++\t\tnegotiator->release_negotiator(negotiator);\n     + \treturn ref;\n       }\n       \n     -+#ifdef __MVS__\n     -+void tag_file_as_working_tree_encoding(struct index_state *istate, char* path, int fd) {\n     -+\tstruct conv_attrs ca;\n     -+\tconvert_attrs(istate, &ca, path);\n     -+  if (ca.attr_action != CRLF_BINARY) {\n     -+    if (ca.working_tree_encoding)\n     -+      __chgfdcodeset(fd, ca.working_tree_encoding);\n     -+    else\n     -+      __setfdtext(fd);\n     -+  }\n     -+  else {\n     -+    __setfdbinary(fd);\n     -+  }\n     -+\n     -+  __disableautocvt(fd);\n     -+}\n     -+#endif\n     -+\n     - static int streaming_write_entry(const struct cache_entry *ce, char *path,\n     - \t\t\t\t struct stream_filter *filter,\n     - \t\t\t\t const struct checkout *state, int to_tempfile,\n     -@@ entry.c: static int streaming_write_entry(const struct cache_entry *ce, char *path,\n     - \tif (fd < 0)\n     - \t\treturn -1;\n     +@@ fetch-pack.c: static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,\n     + \t\tdie(\"fsck failed\");\n       \n     -+#ifdef __MVS__\n     -+  tag_file_as_working_tree_encoding(state->istate, path, fd);\n     -+#endif\n     -+\n     - \tresult |= stream_blob_to_fd(fd, &ce->oid, filter, 1);\n     - \t*fstat_done = fstat_checkout_output(fd, state, statbuf);\n     - \tresult |= close(fd);\n     -@@ entry.c: static int write_entry(struct cache_entry *ce, char *path, struct conv_attrs *ca\n     - \t\t\treturn error_errno(\"unable to create file %s\", path);\n     - \t\t}\n     + \tif (negotiator)\n     +-\t\tnegotiator->release(negotiator);\n     ++\t\tnegotiator->release_negotiator(negotiator);\n       \n     -+#ifdef __MVS__\n     -+    tag_file_as_working_tree_encoding(state->istate, path, fd);\n     -+#endif\n     -+\n     - \t\twrote = write_in_full(fd, new_blob, size);\n     - \t\tif (!to_tempfile)\n     - \t\t\tfstat_done = fstat_checkout_output(fd, state, &st);\n     -\n     - ## environment.c ##\n     -@@ environment.c: const char *git_hooks_path;\n     - int zlib_compression_level = Z_BEST_SPEED;\n     - int pack_compression_level = Z_DEFAULT_COMPRESSION;\n     - int fsync_object_files = -1;\n     -+#ifdef __MVS__\n     -+int ignore_file_tags = 0;\n     -+#endif\n     - int use_fsync = -1;\n     - enum fsync_method fsync_method = FSYNC_METHOD_DEFAULT;\n     - enum fsync_component fsync_components = FSYNC_COMPONENTS_DEFAULT;\n     + \toidset_clear(&common);\n     + \treturn ref;\n      \n       ## git-compat-util.h ##\n      @@ git-compat-util.h: struct strbuf;\n     @@ git-compat-util.h: struct strbuf;\n       #include <fcntl.h>\n       #include <stddef.h>\n      +#ifdef __MVS__\n     -+#define release stdlib_release\n     -+#define fetch stdlib_fetch\n     ++\t#define release stdlib_release\n     ++\t#define fetch stdlib_fetch\n      +#endif\n       #include <stdlib.h>\n      +#ifdef __MVS__\n     -+#undef fetch\n     -+#undef release\n     ++\t#undef fetch\n     ++\t#undef release\n      +#endif\n       #include <stdarg.h>\n       #include <string.h>\n     @@ negotiator/noop.c: static int ack(struct fetch_negotiator *n UNUSED, struct comm\n       }\n       \n      -static void release(struct fetch_negotiator *n UNUSED)\n     -+static void release_negotiator(struct fetch_negotiator *n UNUSED)\n     ++static void release_negotiator (struct fetch_negotiator *n UNUSED)\n       {\n       \t/* nothing to release */\n       }\n     @@ negotiator/skipping.c: void skipping_negotiator_init(struct fetch_negotiator *ne\n       \tdata->rev_list.compare = compare;\n       \n      \n     - ## object-file.c ##\n     -@@\n     - #include \"setup.h\"\n     - #include \"submodule.h\"\n     - #include \"fsck.h\"\n     --\n     -+#ifdef __MVS__\n     -+#include <_Ccsid.h>\n     -+#endif\n     - /* The maximum size for an object header. */\n     - #define MAX_HEADER_LEN 32\n     - \n     -@@ object-file.c: int index_fd(struct index_state *istate, struct object_id *oid,\n     - \treturn ret;\n     - }\n     - \n     -+#ifdef __MVS__\n     -+void validate_codeset(struct index_state *istate, const char *path, int* autoconvertToASCII) {\n     -+       struct conv_attrs ca;\n     -+  struct stat st;\n     -+  unsigned short attr_ccsid;\n     -+  unsigned short file_ccsid;\n     -+\n     -+  if (ignore_file_tags)\n     -+   return;\n     -+\n     -+  *autoconvertToASCII = 0;\n     -+       convert_attrs(istate, &ca, path);\n     -+  if (ca.attr_action == CRLF_BINARY) {\n     -+    attr_ccsid = FT_BINARY;\n     -+  }\n     -+  else if (ca.working_tree_encoding) {\n     -+    attr_ccsid = __toCcsid(ca.working_tree_encoding);\n     -+  }\n     -+  else\n     -+    attr_ccsid = 819;\n     -+\n     -+  if (stat(path, &st) < 0)\n     -+    return;\n     -+\n     -+  file_ccsid = st.st_tag.ft_ccsid;\n     -+\n     -+  if (file_ccsid == FT_UNTAGGED) {\n     -+    die(\"File %s is untagged, set the correct file tag (using the chtag command).\", path);\n     -+  }\n     -+\n     -+  if (attr_ccsid != file_ccsid) {\n     -+    if (file_ccsid == 1047 && attr_ccsid == 819) {\n     -+      *autoconvertToASCII = 1;\n     -+      return;\n     -+    }\n     -+    // Allow tag mixing of 819 and 1208\n     -+    if ((file_ccsid == 819 || file_ccsid == 1208) && (attr_ccsid == 1208 || attr_ccsid == 819)) {\n     -+      return;\n     -+    }\n     -+    // Don't check for binary files, just add them\n     -+    if (attr_ccsid == FT_BINARY)\n     -+      return;\n     -+\n     -+    char attr_csname[_XOPEN_PATH_MAX] = {0};\n     -+    char file_csname[_XOPEN_PATH_MAX] = {0};\n     -+    if (attr_ccsid != FT_BINARY) {\n     -+      __toCSName(attr_ccsid, attr_csname);\n     -+    } else {\n     -+      snprintf(attr_csname, _XOPEN_PATH_MAX, \"%s\", \"binary\");\n     -+    }\n     -+    if (file_ccsid != FT_BINARY) {\n     -+      __toCSName(file_ccsid, file_csname);\n     -+    } else {\n     -+      snprintf(file_csname, _XOPEN_PATH_MAX, \"%s\", \"binary\");\n     -+    }\n     -+    die(\"%s added file: file tag (%s) does not match working-tree-encoding (%s)\", path, file_csname, attr_csname);\n     -+  }\n     -+}\n     -+#endif\n     -+\n     -+\n     -+\n     - int index_path(struct index_state *istate, struct object_id *oid,\n     - \t       const char *path, struct stat *st, unsigned flags)\n     - {\n     -@@ object-file.c: int index_path(struct index_state *istate, struct object_id *oid,\n     - \tstruct strbuf sb = STRBUF_INIT;\n     - \tint rc = 0;\n     - \n     -+#ifdef __MVS__\n     -+\tstruct conv_attrs ca;\n     -+\tint autocvtToASCII;\n     -+#endif\n     -+\n     - \tswitch (st->st_mode & S_IFMT) {\n     - \tcase S_IFREG:\n     -+#ifdef __MVS__\n     -+    validate_codeset(istate, path, &autocvtToASCII);\n     -+#endif\n     - \t\tfd = open(path, O_RDONLY);\n     - \t\tif (fd < 0)\n     - \t\t\treturn error_errno(\"open(\\\"%s\\\")\", path);\n     -+\n     -+#ifdef __MVS__\n     -+   if (!autocvtToASCII)\n     -+     __disableautocvt(fd);\n     -+#endif\n     -+\n     - \t\tif (index_fd(istate, oid, fd, st, OBJ_BLOB, path, flags) < 0)\n     - \t\t\treturn error(_(\"%s: failed to insert into database\"),\n     - \t\t\t\t     path);\n     -\n       ## read-cache.c ##\n      @@ read-cache.c: static int ce_compare_data(struct index_state *istate,\n       \tint fd = git_open_cloexec(ce->name, O_RDONLY);\n       \n       \tif (fd >= 0) {\n     -+#ifdef __MVS__\n     -+    __disableautocvt(fd);\n     -+#endif\n     ++\t#ifdef __MVS__\n     ++\t\t/*\n     ++\t\t * Since the data is in binary format,\n     ++\t\t * we need to set the z/OS file tag to\n     ++\t\t * binary to disable autoconversion\n     ++\t\t */\n     ++\t\t__disableautocvt(fd);\n     ++\t#endif\n       \t\tstruct object_id oid;\n       \t\tif (!index_fd(istate, &oid, fd, st, OBJ_BLOB, ce->name, 0))\n       \t\t\tmatch = !oideq(&oid, &ce->oid);\n     -\n     - ## utf8.c ##\n     -@@ utf8.c: char *reencode_string_len(const char *in, size_t insz,\n     - #endif\n     - \t}\n     - \n     -+#ifdef __MVS__\n     -+  //HACK: For backwards compat, ISO8859-1 really means utf-8 in the z/OS world\n     -+  if (strcasecmp(\"ISO8859-1\", in_encoding) == 0) {\n     -+    in_encoding = \"UTF-8\";\n     -+    out_encoding = \"UTF-8\";\n     -+  }\n     -+  if (strcasecmp(\"ISO8859-1\", out_encoding) == 0) {\n     -+    in_encoding = \"UTF-8\";\n     -+    out_encoding = \"UTF-8\";\n     -+  }\n     -+#endif\n     - \tconv = iconv_open(out_encoding, in_encoding);\n     - \tif (conv == (iconv_t) -1) {\n     - \t\tin_encoding = fallback_encoding(in_encoding);\n  3:  e31be0d764f <  -:  ----------- spaces and errors fix Handled git pipeline errors\n  4:  7bace397b4a <  -:  ----------- fixes for build errors Handled git pipeline errorse\n  5:  3b6d1f80668 <  -:  ----------- fixes for build errors\n  6:  3c9b02e18d2 <  -:  ----------- spaces and errors fix Handled git pipeline errors\n  7:  8165196f869 <  -:  ----------- spaces and errors fix Handled git pipeline errors\n  8:  9fb74d92e3f <  -:  ----------- platform_name fix Handled git pipeline errors\n  9:  8fa15ac45f7 <  -:  ----------- strncpy fix Handled git pipeline errors\n 10:  63479fe3696 <  -:  ----------- strncpy fix Handled git pipeline errors\n 11:  25271363e57 <  -:  ----------- strncpy fix Handled git pipeline errors\n 12:  06658ebad10 <  -:  ----------- Handled git pipeline errors - Memory leak\n 13:  804624950ae <  -:  ----------- Handled git pipeline errors - z/OS enable\n\n\n builtin/archive.c     | 9 +++++++++\n builtin/hash-object.c | 8 ++++++++\n combine-diff.c        | 8 ++++++++\n copy.c                | 7 +++++++\n fetch-negotiator.h    | 4 ++--\n fetch-pack.c          | 4 ++--\n git-compat-util.h     | 8 ++++++++\n negotiator/default.c  | 4 ++--\n negotiator/noop.c     | 4 ++--\n negotiator/skipping.c | 4 ++--\n read-cache.c          | 8 ++++++++\n 11 files changed, 58 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/archive.c b/builtin/archive.c\nindex 90761fdfee0..3b1b258e383 100644\n--- a/builtin/archive.c\n+++ b/builtin/archive.c\n@@ -14,6 +14,15 @@\n static void create_output_file(const char *output_file)\n {\n \tint output_fd = xopen(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);\n+#ifdef __MVS__\n+\t/*\n+\t * Since the data is in binary format,\n+\t * we need to set the z/OS file tag\n+\t * to binary to disable autoconversion\n+\t */\n+\tif (__setfdbinary(output_fd))\n+\t\tdie_errno(_(\"could not tag archive file '%s'\"), output_file);\n+#endif\n \tif (output_fd != 1) {\n \t\tif (dup2(output_fd, 1) < 0)\n \t\t\tdie_errno(_(\"could not redirect output\"));\ndiff --git a/builtin/hash-object.c b/builtin/hash-object.c\nindex 5ffec99dcea..f43450db02d 100644\n--- a/builtin/hash-object.c\n+++ b/builtin/hash-object.c\n@@ -62,6 +62,14 @@ static void hash_object(const char *path, const char *type, const char *vpath,\n {\n \tint fd;\n \tfd = xopen(path, O_RDONLY);\n+#ifdef __MVS__\n+\t/*\n+\t * Since the data being read is in binary format,\n+\t * we need to disable autoconversion for z/OS\n+\t */\n+\tif (__setfdbinary(fd))\n+\t\tdie_errno(\"Cannot set to binary '%s'\", path);\n+#endif\n \thash_fd(fd, type, vpath, flags, literally);\n }\n \ndiff --git a/combine-diff.c b/combine-diff.c\nindex f90f4424829..3230b660371 100644\n--- a/combine-diff.c\n+++ b/combine-diff.c\n@@ -1082,6 +1082,14 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,\n \t\t\tssize_t done;\n \t\t\tint is_file, i;\n \n+\t\t#ifdef __MVS__\n+\t\t\t/*\n+\t\t\t * Disable implicit autconversion on z/os,\n+\t\t\t * rely on conversion from iconv\n+\t\t\t */\n+\t\t\t__disableautocvt(fd);\n+\t\t#endif\n+\n \t\t\telem->mode = canon_mode(st.st_mode);\n \t\t\t/* if symlinks don't work, assume symlink if all parents\n \t\t\t * are symlinks\ndiff --git a/copy.c b/copy.c\nindex 23d84c6c1db..f5b9828b1c9 100644\n--- a/copy.c\n+++ b/copy.c\n@@ -14,6 +14,13 @@ int copy_fd(int ifd, int ofd)\n \t\tif (write_in_full(ofd, buffer, len) < 0)\n \t\t\treturn COPY_WRITE_ERROR;\n \t}\n+\t#ifdef __MVS__\n+\t\t/*\n+\t\t * This is to ensure that file tags are copied\n+\t\t * from source to destination\n+\t\t */\n+\t\t__copyfdccsid(ifd, ofd);\n+\t#endif\n \treturn 0;\n }\n \ndiff --git a/fetch-negotiator.h b/fetch-negotiator.h\nindex e348905a1f0..71d44102fdc 100644\n--- a/fetch-negotiator.h\n+++ b/fetch-negotiator.h\n@@ -14,7 +14,7 @@ struct repository;\n  * Then, when \"have\" lines are required, call next(). Call ack() to report what\n  * the server tells us.\n  *\n- * Once negotiation is done, call release(). The negotiator then cannot be used\n+ * Once negotiation is done, call release_negotiator(). The negotiator then cannot be used\n  * (unless reinitialized with fetch_negotiator_init()).\n  */\n struct fetch_negotiator {\n@@ -47,7 +47,7 @@ struct fetch_negotiator {\n \t */\n \tint (*ack)(struct fetch_negotiator *, struct commit *);\n \n-\tvoid (*release)(struct fetch_negotiator *);\n+\tvoid (*release_negotiator)(struct fetch_negotiator *);\n \n \t/* internal use */\n \tvoid *data;\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex 26999e3b659..c1f2e714f8e 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -1232,7 +1232,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,\n \n  all_done:\n \tif (negotiator)\n-\t\tnegotiator->release(negotiator);\n+\t\tnegotiator->release_negotiator(negotiator);\n \treturn ref;\n }\n \n@@ -1853,7 +1853,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,\n \t\tdie(\"fsck failed\");\n \n \tif (negotiator)\n-\t\tnegotiator->release(negotiator);\n+\t\tnegotiator->release_negotiator(negotiator);\n \n \toidset_clear(&common);\n \treturn ref;\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 3e7a59b5ff1..be4516fa64e 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -223,7 +223,15 @@ struct strbuf;\n #include <sys/stat.h>\n #include <fcntl.h>\n #include <stddef.h>\n+#ifdef __MVS__\n+\t#define release stdlib_release\n+\t#define fetch stdlib_fetch\n+#endif\n #include <stdlib.h>\n+#ifdef __MVS__\n+\t#undef fetch\n+\t#undef release\n+#endif\n #include <stdarg.h>\n #include <string.h>\n #ifdef HAVE_STRINGS_H\ndiff --git a/negotiator/default.c b/negotiator/default.c\nindex 9a5b6963272..b1f9f153372 100644\n--- a/negotiator/default.c\n+++ b/negotiator/default.c\n@@ -174,7 +174,7 @@ static int ack(struct fetch_negotiator *n, struct commit *c)\n \treturn known_to_be_common;\n }\n \n-static void release(struct fetch_negotiator *n)\n+static void release_negotiator(struct fetch_negotiator *n)\n {\n \tclear_prio_queue(&((struct negotiation_state *)n->data)->rev_list);\n \tFREE_AND_NULL(n->data);\n@@ -187,7 +187,7 @@ void default_negotiator_init(struct fetch_negotiator *negotiator)\n \tnegotiator->add_tip = add_tip;\n \tnegotiator->next = next;\n \tnegotiator->ack = ack;\n-\tnegotiator->release = release;\n+\tnegotiator->release_negotiator = release_negotiator;\n \tnegotiator->data = CALLOC_ARRAY(ns, 1);\n \tns->rev_list.compare = compare_commits_by_commit_date;\n \ndiff --git a/negotiator/noop.c b/negotiator/noop.c\nindex de39028ab7f..b2d555e0fec 100644\n--- a/negotiator/noop.c\n+++ b/negotiator/noop.c\n@@ -30,7 +30,7 @@ static int ack(struct fetch_negotiator *n UNUSED, struct commit *c UNUSED)\n \treturn 0;\n }\n \n-static void release(struct fetch_negotiator *n UNUSED)\n+static void release_negotiator (struct fetch_negotiator *n UNUSED)\n {\n \t/* nothing to release */\n }\n@@ -41,6 +41,6 @@ void noop_negotiator_init(struct fetch_negotiator *negotiator)\n \tnegotiator->add_tip = add_tip;\n \tnegotiator->next = next;\n \tnegotiator->ack = ack;\n-\tnegotiator->release = release;\n+\tnegotiator->release_negotiator = release_negotiator;\n \tnegotiator->data = NULL;\n }\ndiff --git a/negotiator/skipping.c b/negotiator/skipping.c\nindex 5b91520430c..783b3f27e63 100644\n--- a/negotiator/skipping.c\n+++ b/negotiator/skipping.c\n@@ -243,7 +243,7 @@ static int ack(struct fetch_negotiator *n, struct commit *c)\n \treturn known_to_be_common;\n }\n \n-static void release(struct fetch_negotiator *n)\n+static void release_negotiator(struct fetch_negotiator *n)\n {\n \tclear_prio_queue(&((struct data *)n->data)->rev_list);\n \tFREE_AND_NULL(n->data);\n@@ -256,7 +256,7 @@ void skipping_negotiator_init(struct fetch_negotiator *negotiator)\n \tnegotiator->add_tip = add_tip;\n \tnegotiator->next = next;\n \tnegotiator->ack = ack;\n-\tnegotiator->release = release;\n+\tnegotiator->release_negotiator = release_negotiator;\n \tnegotiator->data = CALLOC_ARRAY(data, 1);\n \tdata->rev_list.compare = compare;\n \ndiff --git a/read-cache.c b/read-cache.c\nindex 080bd39713b..b7189c58144 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -205,6 +205,14 @@ static int ce_compare_data(struct index_state *istate,\n \tint fd = git_open_cloexec(ce->name, O_RDONLY);\n \n \tif (fd >= 0) {\n+\t#ifdef __MVS__\n+\t\t/*\n+\t\t * Since the data is in binary format,\n+\t\t * we need to set the z/OS file tag to\n+\t\t * binary to disable autoconversion\n+\t\t */\n+\t\t__disableautocvt(fd);\n+\t#endif\n \t\tstruct object_id oid;\n \t\tif (!index_fd(istate, &oid, fd, st, OBJ_BLOB, ce->name, 0))\n \t\t\tmatch = !oideq(&oid, &ce->oid);\n\nbase-commit: 564d0252ca632e0264ed670534a51d18a689ef5d\n-- \ngitgitgadget\n"},{"id":"485356","messageId":"CAPig+cQ8eEU0TOoBf2KavTyf0OLhNtmOzs8+WqZy9JMXa=ydPQ@mail.gmail.com","threadId":"60509","inReplyTo":"pull.1537.v2.git.git.1701699574054.gitgitgadget@gmail.com","subject":"Re: [PATCH v2] This PR enables a successful git build on z/OS.","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2023-12-04T21:46:42Z","receivedAt":"2023-12-04T21:46:54Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, Dec 4, 2023 at 9:19 AM Haritha via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n> Rename functions like \"release\" and \"fetch\"\n> due to conflict in z/OS standard C libraries.\n> Also disables autoconversion facility on z/OS\n> and relies on iconv.\n> New files created in binary format are also\n> tagged as binary.\n>\n> Signed-off-by: Haritha D <harithamma.d@ibm.com>\n> ---\n>     Enabling z/OS workflow for git\n>\n>     z/OS is an IBM mainframe operating system, also known as OS/390. Our\n>     team has been actively involved in porting Git to z/OS and we have made\n>     significant modifications to facilitate this process. The patch below is\n>     the initial configuration for z/OS. I also have few follow up changes\n>     and I will send that after these changes are approved. Please let me\n>     know if there are any concerns.\n\nIt's fairly unlikely that this patch will be accepted as-is. Please\nsee brian's[1] and Junio's[2] valuable review comments in response to\nyour v1. They contain important suggestions which will give you a\nbetter chance of landing these changes.\n\nGenerally speaking, the patch's commit message lacks sufficient detail\nto allow a reviewer (or future reader) to understand why the changes\nare being made. Moreover, this single patch seems to be addressing at\nleast three separate issues, hence should be split into three or more\npatches, each standalone and tackling a single issue, and each easily\ndigested by a reviewer. The commit message of each patch should fully\nexplain and justify the changes made by the patch, keeping in mind\nthat most reviewers probably aren't familiar with z/OS, thus will need\nextra hand-holding. More below...\n\n[1]: https://lore.kernel.org/git/ZVKrWSv7JguKTSYw@tapette.crustytoothpaste.net/\n[2]: https://lore.kernel.org/git/xmqqcywd2m9i.fsf@gitster.g/\n\n> diff --git a/builtin/archive.c b/builtin/archive.c\n> @@ -14,6 +14,15 @@\n>  static void create_output_file(const char *output_file)\n>  {\n>         int output_fd = xopen(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);\n> +#ifdef __MVS__\n> +       /*\n> +        * Since the data is in binary format,\n> +        * we need to set the z/OS file tag\n> +        * to binary to disable autoconversion\n> +        */\n> +       if (__setfdbinary(output_fd))\n> +               die_errno(_(\"could not tag archive file '%s'\"), output_file);\n> +#endif\n\nAs mentioned in an earlier review, the project generally doesn't want\n#ifdef's littering the code and prefer that this sort of\nplatform-specific specialization be wrapped up in its own \"compat\"\nfile/function. For instance, perhaps you could create a\nplatform-specific specialization of xopen() and then `#define xopen`\nto reference your specialized version. Your custom xopen() might first\ncall the xopen() which Git defines and then perform whatever extra\nspecial work is needed for your platform. That way, you would not have\nto muck around either in the code which calls xopen() or in the\nGit-supplied xopen(). See, for example, how git-compat-util.h\noverriedes certain functions, such as stat(), fstat(), etc. using an\n#undefine/#define dance.\n\n> diff --git a/combine-diff.c b/combine-diff.c\n> @@ -1082,6 +1082,14 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,\n> +               #ifdef __MVS__\n> +                       /*\n> +                        * Disable implicit autconversion on z/os,\n> +                        * rely on conversion from iconv\n> +                        */\n> +                       __disableautocvt(fd);\n> +               #endif\n>                         elem->mode = canon_mode(st.st_mode);\n\nSimilar comment. Try to find an abstraction which allows you to\nperform this specialization in a way which does not require #ifdef's\nwithin the main source code if possible.\n\n> diff --git a/fetch-negotiator.h b/fetch-negotiator.h\n> @@ -47,7 +47,7 @@ struct fetch_negotiator {\n> -       void (*release)(struct fetch_negotiator *);\n> +       void (*release_negotiator)(struct fetch_negotiator *);> diff --git a/fetch-pack.c b/fetch-pack.c\n> @@ -1232,7 +1232,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,\n>         if (negotiator)\n> -               negotiator->release(negotiator);\n> +               negotiator->release_negotiator(negotiator);\n>         return ref;\n>  }\n> diff --git a/git-compat-util.h b/git-compat-util.h\n> @@ -223,7 +223,15 @@ struct strbuf;\n> +#ifdef __MVS__\n> +       #define release stdlib_release\n> +       #define fetch stdlib_fetch\n> +#endif\n>  #include <stdlib.h>\n> +#ifdef __MVS__\n> +       #undef fetch\n> +       #undef release\n> +#endif\n\nSo, the problem is that z/OS is polluting the C namespace or the\npreprocessor namespace with names \"release\" and \"fetch\"? When we've\nrun across this problem on other platforms, we modify\ngit-compat-util.h or some other files in compat/ to suppress the\npollution introduced by the platform headers rather than \"fixing\" the\nGit source code. For instance, if \"release\" and \"fetch\" are macros on\nz/OS, then you may be able to simply #undef them after pulling in\nwhichever z/OS header defines them. If they are actual system\nfunctions (rather than macros), you may be able to employ the\n#undef/#define dance to rename them to something else, such as\n\"zos_release\" and \"zos_fetch\" _before_ including the system header\nwhich declares those functions.\n\n> diff --git a/read-cache.c b/read-cache.c\n> @@ -205,6 +205,14 @@ static int ce_compare_data(struct index_state *istate,\n>         int fd = git_open_cloexec(ce->name, O_RDONLY);\n>         if (fd >= 0) {\n> +       #ifdef __MVS__\n> +               /*\n> +                * Since the data is in binary format,\n> +                * we need to set the z/OS file tag to\n> +                * binary to disable autoconversion\n> +                */\n> +               __disableautocvt(fd);\n> +       #endif\n\nSame comment as above about encapsulating this in a platform-specific\nspecialization function in compat/ rather than polluting the code with\n#ifdef.\n"},{"id":"485359","messageId":"ea020e16-7d07-4fa0-84b1-5d2f76a6fe34@web.de","threadId":"60509","inReplyTo":"CAPig+cQ8eEU0TOoBf2KavTyf0OLhNtmOzs8+WqZy9JMXa=ydPQ@mail.gmail.com","subject":"Re: [PATCH v2] This PR enables a successful git build on z/OS.","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2023-12-05T20:58:25Z","receivedAt":"2023-12-05T20:58:43Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 04.12.23 um 22:46 schrieb Eric Sunshine:\n> On Mon, Dec 4, 2023 at 9:19 AM Haritha via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>> diff --git a/fetch-negotiator.h b/fetch-negotiator.h\n>> @@ -47,7 +47,7 @@ struct fetch_negotiator {\n>> -       void (*release)(struct fetch_negotiator *);\n>> +       void (*release_negotiator)(struct fetch_negotiator *);> diff --git a/fetch-pack.c b/fetch-pack.c\n>> @@ -1232,7 +1232,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,\n>>         if (negotiator)\n>> -               negotiator->release(negotiator);\n>> +               negotiator->release_negotiator(negotiator);\n>>         return ref;\n>>  }\n>> diff --git a/git-compat-util.h b/git-compat-util.h\n>> @@ -223,7 +223,15 @@ struct strbuf;\n>> +#ifdef __MVS__\n>> +       #define release stdlib_release\n>> +       #define fetch stdlib_fetch\n>> +#endif\n>>  #include <stdlib.h>\n>> +#ifdef __MVS__\n>> +       #undef fetch\n>> +       #undef release\n>> +#endif\n>\n> So, the problem is that z/OS is polluting the C namespace or the\n> preprocessor namespace with names \"release\" and \"fetch\"? When we've\n> run across this problem on other platforms, we modify\n> git-compat-util.h or some other files in compat/ to suppress the\n> pollution introduced by the platform headers rather than \"fixing\" the\n> Git source code. For instance, if \"release\" and \"fetch\" are macros on\n> z/OS, then you may be able to simply #undef them after pulling in\n> whichever z/OS header defines them. If they are actual system\n> functions (rather than macros), you may be able to employ the\n> #undef/#define dance to rename them to something else, such as\n> \"zos_release\" and \"zos_fetch\" _before_ including the system header\n> which declares those functions.\n\nI assume that [1] and [2] link to the documentation of these functions.\nBoth pages include the following paragraph:\n\n   \"To avoid infringing on the user's name space, this nonstandard\n    function has two names. One name is prefixed with two underscore\n    characters, and one name is not. The name without the prefix\n    underscore characters is exposed only when using the runtime library\n    extensions.\"\n\n[3] defines \"runtime library extensions\" and mentions the macro __EXT\nand LANGLVL(EXTENDED).  Do you need those extensions?  If you don't then\nperhaps turning them off avoids the name collisions without needing to\nchange the code?\n\nRené\n\n\n[1] https://www.ibm.com/docs/en/zos/3.1.0?topic=functions-fetch-get-load-module\n[2] https://www.ibm.com/docs/en/zos/3.1.0?topic=functions-release-delete-load-module\n[3] https://www.ibm.com/docs/en/zos/3.1.0?topic=reference-zos-cc-compiler-feature#compiler_feature__ext_lib_func\n\n"}]}