{"thread":{"id":"64928","subject":"[PATCH 0/4] trace2: add macOS and Windows process ancestry tracing","startedAt":"2026-02-05T16:05:13Z","lastAt":"2026-02-14T00:30:39Z","messageCount":25,"participants":["Matthew John Cheetham via GitGitGadget","Kristoffer Haugsbakk","Derrick Stolee","Matthew John Cheetham","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"535250","messageId":"pull.2040.git.1770307510.gitgitgadget@gmail.com","threadId":"64928","inReplyTo":null,"subject":"[PATCH 0/4] trace2: add macOS and Windows process ancestry tracing","fromName":"Matthew John Cheetham via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-05T16:05:06Z","receivedAt":"2026-02-05T16:05:13Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"In 353d3d77 (trace2: collect Windows-specific process information)\nWindows-specific process ancestry information was added as a data_json event\nto TRACE2. Furthermore in 2f732bf1 (tr2: log parent process name) similar\nfunctionality was added for Linux-based systems, using procfs.\n\nLet's teach Git on macOS to also gather process ancestry information, and\nemit it as a cmd_ancestry TRACE2 event.\n\nFurthermore, let's refactor the Windows implementation to align with the\nLinux and macOS versions - by emitting the ancestry information as a\ncmd_ancestry event. We keep the older, custom data_json event type on\nWindows for compatibility for consumers of the TRACE2 data that use the\nolder event.\n\nThanks, Matthew\n\nMatthew John Cheetham (4):\n  trace2: add macOS process ancestry tracing\n  build: include procinfo.c impl for macOS\n  trace2: refactor Windows process ancestry trace2 event\n  trace2: emit cmd_ancestry data for Windows\n\n compat/darwin/procinfo.c                 | 99 ++++++++++++++++++++++++\n compat/win32/trace2_win32_process_info.c | 58 ++++++++------\n config.mak.uname                         |  2 +\n contrib/buildsystems/CMakeLists.txt      |  2 +\n meson.build                              |  2 +\n 5 files changed, 138 insertions(+), 25 deletions(-)\n create mode 100644 compat/darwin/procinfo.c\n\n\nbase-commit: 9a2fb147f2c61d0cab52c883e7e26f5b7948e3ed\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-2040%2Fmjcheetham%2Ftrace2-macos-ancestry-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2040/mjcheetham/trace2-macos-ancestry-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/2040\n-- \ngitgitgadget\n"},{"id":"535251","messageId":"c786a038f31f0d3b5f612e9124e3dfb23e56a027.1770307510.git.gitgitgadget@gmail.com","threadId":"64928","inReplyTo":"pull.2040.git.1770307510.gitgitgadget@gmail.com","subject":"[PATCH 2/4] build: include procinfo.c impl for macOS","fromName":"Matthew John Cheetham via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-05T16:05:08Z","receivedAt":"2026-02-05T16:05:16Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"From: Matthew John Cheetham <mjcheetham@outlook.com>\n\nInclude an implementation of trace2_collect_process_info for macOS.\n\nSigned-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n---\n config.mak.uname                    | 2 ++\n contrib/buildsystems/CMakeLists.txt | 2 ++\n meson.build                         | 2 ++\n 3 files changed, 6 insertions(+)\n\ndiff --git a/config.mak.uname b/config.mak.uname\nindex 1691c6ae6e..baa5018461 100644\n--- a/config.mak.uname\n+++ b/config.mak.uname\n@@ -148,6 +148,8 @@ ifeq ($(uname_S),Darwin)\n \tHAVE_NS_GET_EXECUTABLE_PATH = YesPlease\n \tCSPRNG_METHOD = arc4random\n \tUSE_ENHANCED_BASIC_REGULAR_EXPRESSIONS = YesPlease\n+\tHAVE_PLATFORM_PROCINFO = YesPlease\n+\tCOMPAT_OBJS += compat/darwin/procinfo.o\n \n \t# Workaround for `gettext` being keg-only and not even being linked via\n \t# `brew link --force gettext`, should be obsolete as of\ndiff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt\nindex edb0fc04ad..d489f0cada 100644\n--- a/contrib/buildsystems/CMakeLists.txt\n+++ b/contrib/buildsystems/CMakeLists.txt\n@@ -274,6 +274,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\n elseif(CMAKE_SYSTEM_NAME STREQUAL \"Linux\")\n \tadd_compile_definitions(PROCFS_EXECUTABLE_PATH=\"/proc/self/exe\" HAVE_DEV_TTY )\n \tlist(APPEND compat_SOURCES unix-socket.c unix-stream-server.c compat/linux/procinfo.c)\n+elseif(CMAKE_SYSTEM_NAME STREQUAL \"Darwin\")\n+\tlist(APPEND compat_SOURCES compat/darwin/procinfo.c)\n endif()\n \n if(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\ndiff --git a/meson.build b/meson.build\nindex 1f95a06edb..32d470e4f7 100644\n--- a/meson.build\n+++ b/meson.build\n@@ -1292,6 +1292,8 @@ if host_machine.system() == 'linux'\n   libgit_sources += 'compat/linux/procinfo.c'\n elif host_machine.system() == 'windows'\n   libgit_sources += 'compat/win32/trace2_win32_process_info.c'\n+elif host_machine.system() == 'darwin'\n+  libgit_sources += 'compat/darwin/procinfo.c'\n else\n   libgit_sources += 'compat/stub/procinfo.c'\n endif\n-- \ngitgitgadget\n\n"},{"id":"535252","messageId":"d99a30a1a77f0f23468dba987da08b32dd9a92fa.1770307510.git.gitgitgadget@gmail.com","threadId":"64928","inReplyTo":"pull.2040.git.1770307510.gitgitgadget@gmail.com","subject":"[PATCH 1/4] trace2: add macOS process ancestry tracing","fromName":"Matthew John Cheetham via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-05T16:05:07Z","receivedAt":"2026-02-05T16:05:16Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"From: Matthew John Cheetham <mjcheetham@outlook.com>\n\nIn 353d3d77 (trace2: collect Windows-specific process information)\nWindows-specific process ancestry information was added as a data_json\nevent to TRACE2. Furthermore in 2f732bf1 (tr2: log parent process name)\nsimilar functionality was added for Linux-based systems, using procfs.\n\nTeach Git to also log process ancestry on macOS using the sysctl with\nKERN_PROC to get process information (PPID and process name).\nLike the Linux implementation, we use the cmd_ancestry TRACE2 event\nrather than using a data_json event and creating another custom data\npoint.\n\nSigned-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n---\n compat/darwin/procinfo.c | 99 ++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 99 insertions(+)\n create mode 100644 compat/darwin/procinfo.c\n\ndiff --git a/compat/darwin/procinfo.c b/compat/darwin/procinfo.c\nnew file mode 100644\nindex 0000000000..e0d76d81ec\n--- /dev/null\n+++ b/compat/darwin/procinfo.c\n@@ -0,0 +1,99 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n+#include \"git-compat-util.h\"\n+#include \"strbuf.h\"\n+#include \"strvec.h\"\n+#include \"trace2.h\"\n+#include <sys/sysctl.h>\n+\n+/*\n+ * An arbitrarily chosen value to limit the depth of the ancestor chain.\n+ */\n+#define NR_PIDS_LIMIT 10\n+\n+/*\n+ * Get the process name and parent PID for a given PID using sysctl().\n+ * Returns 0 on success, -1 on failure.\n+ */\n+static int get_proc_info(pid_t pid, struct strbuf *name, pid_t *ppid)\n+{\n+\tint mib[4];\n+\tstruct kinfo_proc proc;\n+\tsize_t size = sizeof(proc);\n+\n+\tmib[0] = CTL_KERN;\n+\tmib[1] = KERN_PROC;\n+\tmib[2] = KERN_PROC_PID;\n+\tmib[3] = pid;\n+\n+\tif (sysctl(mib, 4, &proc, &size, NULL, 0) < 0)\n+\t\treturn -1;\n+\n+\tif (size == 0)\n+\t\treturn -1;\n+\n+\tstrbuf_addstr(name, proc.kp_proc.p_comm);\n+\t*ppid = proc.kp_eproc.e_ppid;\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * Recursively push process names onto the ancestry array.\n+ * We guard against cycles by limiting the depth to NR_PIDS_LIMIT.\n+ */\n+static void push_ancestry_name(struct strvec *names, pid_t pid, int depth)\n+{\n+\tstruct strbuf name = STRBUF_INIT;\n+\tpid_t ppid;\n+\n+\tif (depth >= NR_PIDS_LIMIT)\n+\t\treturn;\n+\n+\tif (pid <= 0)\n+\t\treturn;\n+\n+\tif (get_proc_info(pid, &name, &ppid) < 0)\n+\t\tgoto cleanup;\n+\n+\tstrvec_push(names, name.buf);\n+\n+\t/*\n+\t * Recurse to the parent process. Stop if ppid is 0 or 1\n+\t * (init/launchd) or if we've reached ourselves (cycle).\n+\t */\n+\tif (ppid > 1 && ppid != pid)\n+\t\tpush_ancestry_name(names, ppid, depth + 1);\n+\n+cleanup:\n+\tstrbuf_release(&name);\n+}\n+\n+void trace2_collect_process_info(enum trace2_process_info_reason reason)\n+{\n+\tstruct strvec names = STRVEC_INIT;\n+\n+\tif (!trace2_is_enabled())\n+\t\treturn;\n+\n+\tswitch (reason) {\n+\tcase TRACE2_PROCESS_INFO_STARTUP:\n+\t\tpush_ancestry_name(&names, getppid(), 0);\n+\t\tif (names.nr)\n+\t\t\ttrace2_cmd_ancestry(names.v);\n+\n+\t\tstrvec_clear(&names);\n+\t\tbreak;\n+\n+\tcase TRACE2_PROCESS_INFO_EXIT:\n+\t\t/*\n+\t\t * The Windows version of this calls its\n+\t\t * get_peak_memory_info() here. We may want to insert\n+\t\t * similar process-end statistics here in the future.\n+\t\t */\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tBUG(\"trace2_collect_process_info: unknown reason '%d'\", reason);\n+\t}\n+}\n-- \ngitgitgadget\n\n"},{"id":"535253","messageId":"7ccd0a9a6d89decaa5856494a184c71bc0d678e9.1770307510.git.gitgitgadget@gmail.com","threadId":"64928","inReplyTo":"pull.2040.git.1770307510.gitgitgadget@gmail.com","subject":"[PATCH 3/4] trace2: refactor Windows process ancestry trace2 event","fromName":"Matthew John Cheetham via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-05T16:05:09Z","receivedAt":"2026-02-05T16:05:18Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"From: Matthew John Cheetham <mjcheetham@outlook.com>\n\nIn 353d3d77 (trace2: collect Windows-specific process information) we\nadded process ancestry information for Windows to TRACE2 via a data_json\nevent. It was only later in 2f732bf1 (tr2: log parent process name) that\nthe specific cmd_ancestry event was added to TRACE2.\n\nIn a future commit we will emit the ancestry information with the newer\ncmd_ancestry TRACE2 event. Right now, we rework this implementation of\ntrace2_collect_process_info to separate the calculation of ancestors\nfrom building and emiting the JSON array via a data_json event.\n\nSigned-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n---\n compat/win32/trace2_win32_process_info.c | 50 ++++++++++++------------\n 1 file changed, 25 insertions(+), 25 deletions(-)\n\ndiff --git a/compat/win32/trace2_win32_process_info.c b/compat/win32/trace2_win32_process_info.c\nindex f147da706a..aceea05430 100644\n--- a/compat/win32/trace2_win32_process_info.c\n+++ b/compat/win32/trace2_win32_process_info.c\n@@ -3,6 +3,7 @@\n #include \"../../git-compat-util.h\"\n #include \"../../json-writer.h\"\n #include \"../../repository.h\"\n+#include \"../../strvec.h\"\n #include \"../../trace2.h\"\n #include \"lazyload.h\"\n #include <psapi.h>\n@@ -32,12 +33,7 @@ static int find_pid(DWORD pid, HANDLE hSnapshot, PROCESSENTRY32 *pe32)\n }\n \n /*\n- * Accumulate JSON array of our parent processes:\n- *     [\n- *         exe-name-parent,\n- *         exe-name-grand-parent,\n- *         ...\n- *     ]\n+ * Accumulate array of our parent process names.\n  *\n  * Note: we only report the filename of the process executable; the\n  *       only way to get its full pathname is to use OpenProcess()\n@@ -73,7 +69,7 @@ static int find_pid(DWORD pid, HANDLE hSnapshot, PROCESSENTRY32 *pe32)\n  * simple and avoid the alloc/realloc overhead.  It is OK if we\n  * truncate the search and return a partial answer.\n  */\n-static void get_processes(struct json_writer *jw, HANDLE hSnapshot)\n+static void get_processes(struct strvec *names, HANDLE hSnapshot)\n {\n \tPROCESSENTRY32 pe32;\n \tDWORD pid;\n@@ -82,19 +78,19 @@ static void get_processes(struct json_writer *jw, HANDLE hSnapshot)\n \n \tpid = GetCurrentProcessId();\n \twhile (find_pid(pid, hSnapshot, &pe32)) {\n-\t\t/* Only report parents. Omit self from the JSON output. */\n+\t\t/* Only report parents. Omit self from the output. */\n \t\tif (nr_pids)\n-\t\t\tjw_array_string(jw, pe32.szExeFile);\n+\t\t\tstrvec_push(names, pe32.szExeFile);\n \n \t\t/* Check for cycle in snapshot. (Yes, it happened.) */\n \t\tfor (k = 0; k < nr_pids; k++)\n \t\t\tif (pid == pid_list[k]) {\n-\t\t\t\tjw_array_string(jw, \"(cycle)\");\n+\t\t\t\tstrvec_push(names, \"(cycle)\");\n \t\t\t\treturn;\n \t\t\t}\n \n \t\tif (nr_pids == NR_PIDS_LIMIT) {\n-\t\t\tjw_array_string(jw, \"(truncated)\");\n+\t\t\tstrvec_push(names, \"(truncated)\");\n \t\t\treturn;\n \t\t}\n \n@@ -105,24 +101,14 @@ static void get_processes(struct json_writer *jw, HANDLE hSnapshot)\n }\n \n /*\n- * Emit JSON data for the current and parent processes.  Individual\n- * trace2 targets can decide how to actually print it.\n+ * Collect the list of parent process names.\n  */\n-static void get_ancestry(void)\n+static void get_ancestry(struct strvec *names)\n {\n \tHANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\n \n \tif (hSnapshot != INVALID_HANDLE_VALUE) {\n-\t\tstruct json_writer jw = JSON_WRITER_INIT;\n-\n-\t\tjw_array_begin(&jw, 0);\n-\t\tget_processes(&jw, hSnapshot);\n-\t\tjw_end(&jw);\n-\n-\t\ttrace2_data_json(\"process\", the_repository, \"windows/ancestry\",\n-\t\t\t\t &jw);\n-\n-\t\tjw_release(&jw);\n+\t\tget_processes(names, hSnapshot);\n \t\tCloseHandle(hSnapshot);\n \t}\n }\n@@ -176,13 +162,27 @@ static void get_peak_memory_info(void)\n \n void trace2_collect_process_info(enum trace2_process_info_reason reason)\n {\n+\tstruct strvec names = STRVEC_INIT;\n+\n \tif (!trace2_is_enabled())\n \t\treturn;\n \n \tswitch (reason) {\n \tcase TRACE2_PROCESS_INFO_STARTUP:\n \t\tget_is_being_debugged();\n-\t\tget_ancestry();\n+\t\tget_ancestry(&names);\n+\t\tif (names.nr) {\n+\t\t\tstruct json_writer jw = JSON_WRITER_INIT;\n+\t\t\tjw_array_begin(&jw, 0);\n+\t\t\tfor (size_t i = 0; i < names.nr; i++)\n+\t\t\t\tjw_array_string(&jw, names.v[i]);\n+\t\t\tjw_end(&jw);\n+\t\t\ttrace2_data_json(\"process\", the_repository,\n+\t\t\t\t\t \"windows/ancestry\", &jw);\n+\t\t\tjw_release(&jw);\n+\t\t}\n+\n+\t\tstrvec_clear(&names);\n \t\treturn;\n \n \tcase TRACE2_PROCESS_INFO_EXIT:\n-- \ngitgitgadget\n\n"},{"id":"535254","messageId":"a06344dc753698ece37f8d066b0a51931b7fa16f.1770307510.git.gitgitgadget@gmail.com","threadId":"64928","inReplyTo":"pull.2040.git.1770307510.gitgitgadget@gmail.com","subject":"[PATCH 4/4] trace2: emit cmd_ancestry data for Windows","fromName":"Matthew John Cheetham via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-05T16:05:10Z","receivedAt":"2026-02-05T16:05:19Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"From: Matthew John Cheetham <mjcheetham@outlook.com>\n\nSince 2f732bf1 (tr2: log parent process name) it is now possible to emit\na specific process ancestry event in TRACE2. We should emit the Windows\nprocess ancestry data with the correct event type.\n\nTo not break existing consumers of the data_json \"windows/ancestry\"\nevent, we continue to emit the ancestry data as a JSON event.\n\nSigned-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n---\n compat/win32/trace2_win32_process_info.c | 8 ++++++++\n 1 file changed, 8 insertions(+)\n\ndiff --git a/compat/win32/trace2_win32_process_info.c b/compat/win32/trace2_win32_process_info.c\nindex aceea05430..6a6a396078 100644\n--- a/compat/win32/trace2_win32_process_info.c\n+++ b/compat/win32/trace2_win32_process_info.c\n@@ -172,6 +172,11 @@ void trace2_collect_process_info(enum trace2_process_info_reason reason)\n \t\tget_is_being_debugged();\n \t\tget_ancestry(&names);\n \t\tif (names.nr) {\n+\t\t\t/*\n+\t\t\t  Emit the ancestry data as a data_json event to\n+\t\t\t  maintain compatibility for consumers of the older\n+\t\t\t  \"windows/ancestry\" event.\n+\t\t\t */\n \t\t\tstruct json_writer jw = JSON_WRITER_INIT;\n \t\t\tjw_array_begin(&jw, 0);\n \t\t\tfor (size_t i = 0; i < names.nr; i++)\n@@ -180,6 +185,9 @@ void trace2_collect_process_info(enum trace2_process_info_reason reason)\n \t\t\ttrace2_data_json(\"process\", the_repository,\n \t\t\t\t\t \"windows/ancestry\", &jw);\n \t\t\tjw_release(&jw);\n+\n+\t\t\t/* Emit the ancestry data with the new event. */\n+\t\t\ttrace2_cmd_ancestry(names.v);\n \t\t}\n \n \t\tstrvec_clear(&names);\n-- \ngitgitgadget\n"},{"id":"535256","messageId":"8775e4d7-4793-413d-a0ff-c1d325ed04e5@app.fastmail.com","threadId":"64928","inReplyTo":"a06344dc753698ece37f8d066b0a51931b7fa16f.1770307510.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 4/4] trace2: emit cmd_ancestry data for Windows","fromName":"Kristoffer Haugsbakk","fromEmail":"kristofferhaugsbakk@fastmail.com","sentAt":"2026-02-05T16:19:12Z","receivedAt":"2026-02-05T16:19:33Z","isPatch":true,"sender":{"key":"kristofferhaugsbakk@fastmail.com","avatar":null},"body":"On Thu, Feb 5, 2026, at 17:05, Matthew John Cheetham via GitGitGadget wrote:\n> From: Matthew John Cheetham <mjcheetham@outlook.com>\n>\n> Since 2f732bf1 (tr2: log parent process name) it is now possible to emit\n\nThe usual way to refer to commits is to use `git show -s\n--pretty=reference`. (Or maybe with `--abbrev=8` as well\nwhich seems to be the case here.) That also adds the date.\nSee `SubmittingPatches`.\n\n> a specific process ancestry event in TRACE2. We should emit the Windows\n> process ancestry data with the correct event type.\n>\n> To not break existing consumers of the data_json \"windows/ancestry\"\n> event, we continue to emit the ancestry data as a JSON event.\n>\n> Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n> ---\n>[snip]\n"},{"id":"535537","messageId":"7390e189-16ac-43b3-a63c-a8b942d5934b@gmail.com","threadId":"64928","inReplyTo":"d99a30a1a77f0f23468dba987da08b32dd9a92fa.1770307510.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 1/4] trace2: add macOS process ancestry tracing","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2026-02-09T14:36:06Z","receivedAt":"2026-02-09T14:36:09Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 2/5/2026 11:05 AM, Matthew John Cheetham via GitGitGadget wrote:\n> Teach Git to also log process ancestry on macOS using the sysctl with\n> KERN_PROC to get process information (PPID and process name).\n> Like the Linux implementation, we use the cmd_ancestry TRACE2 event\n> rather than using a data_json event and creating another custom data\n> point.\n\n> +#define USE_THE_REPOSITORY_VARIABLE\n\nIf we are creating a new file, then it would be best if we avoid this\nmacro, which is intended for older code to still work until it can be\nfixed.\n\nBut also it seems that you don't use the_repository anywhere, so this\ncan be deleted without consequence!\n\n> +/*\n> + * Recursively push process names onto the ancestry array.\n> + * We guard against cycles by limiting the depth to NR_PIDS_LIMIT.\n> + */\n> +static void push_ancestry_name(struct strvec *names, pid_t pid, int depth)\n> +{\n> +\tstruct strbuf name = STRBUF_INIT;\n> +\tpid_t ppid;\n> +\n> +\tif (depth >= NR_PIDS_LIMIT)\n> +\t\treturn;\n\nHere is the recursion limit check.\n\n> +\tif (pid <= 0)\n> +\t\treturn;\n> +\n> +\tif (get_proc_info(pid, &name, &ppid) < 0)\n> +\t\tgoto cleanup;\n> +\n> +\tstrvec_push(names, name.buf);\n\nThis is copying the buffer, which is why you release it later.\n\nQuestion: could we stop copying here and use strbuf_detach() at this\npoint? That would be a very minor improvement, so feel free to ignore!\n\nI took a look and rediscovered that strvecs do not have an option to not\ncopy. I'm thinking about string_list. I'm not sure if there is any value\nin converting your code just to avoid some string duplication at this\nscale.\n\n> +\t/*\n> +\t * Recurse to the parent process. Stop if ppid is 0 or 1\n> +\t * (init/launchd) or if we've reached ourselves (cycle).\n> +\t */\n> +\tif (ppid > 1 && ppid != pid)\n> +\t\tpush_ancestry_name(names, ppid, depth + 1);\n\nThis kind of tail recursion could be easily converted into a loop. I\nusually prefer loops to recursion when possible, in case we want to allow\nan unlimited number of parents in the future.\n\n> +cleanup:\n> +\tstrbuf_release(&name);\n> +}\n\nI got a little confused by the lack of a .h file, but that's probably due\nto the extra magic being done at compile time to pick this file on a per-\nplatform basis.\n\nIndeed, trace2_collect_process_info() is defined in trace2.h.\n\nThanks,\n-Stolee\n"},{"id":"535538","messageId":"9066e4d3-7671-4fd2-9a7a-5a0719ae24da@gmail.com","threadId":"64928","inReplyTo":"c786a038f31f0d3b5f612e9124e3dfb23e56a027.1770307510.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 2/4] build: include procinfo.c impl for macOS","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2026-02-09T14:37:27Z","receivedAt":"2026-02-09T14:37:29Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 2/5/2026 11:05 AM, Matthew John Cheetham via GitGitGadget wrote:\n>  config.mak.uname                    | 2 ++\n>  contrib/buildsystems/CMakeLists.txt | 2 ++\n>  meson.build                         | 2 ++\n\nSo many build systems!\n\nEach logic you included seems to be correct and matches the patterns from\nthe Linux case.\n\nThanks,\n-Stolee\n"},{"id":"535539","messageId":"1a282a1c-866e-49fc-b396-014921135cc4@gmail.com","threadId":"64928","inReplyTo":"7ccd0a9a6d89decaa5856494a184c71bc0d678e9.1770307510.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 3/4] trace2: refactor Windows process ancestry trace2 event","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2026-02-09T14:41:28Z","receivedAt":"2026-02-09T14:41:30Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 2/5/2026 11:05 AM, Matthew John Cheetham via GitGitGadget wrote:\n> diff --git a/compat/win32/trace2_win32_process_info.c b/compat/win32/trace2_win32_process_info.c\n...\n>  #include \"../../json-writer.h\"\n\nAre we able to delete this after your change?\n\n>  \tpid = GetCurrentProcessId();\n>  \twhile (find_pid(pid, hSnapshot, &pe32)) {\n> -\t\t/* Only report parents. Omit self from the JSON output. */\n> +\t\t/* Only report parents. Omit self from the output. */\n>  \t\tif (nr_pids)\n> -\t\t\tjw_array_string(jw, pe32.szExeFile);\n> +\t\t\tstrvec_push(names, pe32.szExeFile);\n>  \n>  \t\t/* Check for cycle in snapshot. (Yes, it happened.) */\n>  \t\tfor (k = 0; k < nr_pids; k++)\n>  \t\t\tif (pid == pid_list[k]) {\n> -\t\t\t\tjw_array_string(jw, \"(cycle)\");\n> +\t\t\t\tstrvec_push(names, \"(cycle)\");\n>  \t\t\t\treturn;\n>  \t\t\t}\n>  \n>  \t\tif (nr_pids == NR_PIDS_LIMIT) {\n> -\t\t\tjw_array_string(jw, \"(truncated)\");\n> +\t\t\tstrvec_push(names, \"(truncated)\");\n>  \t\t\treturn;\n>  \t\t}\n\nNice replacement of JSON with strvec logic.\n\n> @@ -105,24 +101,14 @@ static void get_processes(struct json_writer *jw, HANDLE hSnapshot)\n>  }\n>  \n>  /*\n> - * Emit JSON data for the current and parent processes.  Individual\n> - * trace2 targets can decide how to actually print it.\n> + * Collect the list of parent process names.\n>   */\n> -static void get_ancestry(void)\n> +static void get_ancestry(struct strvec *names)\n>  {\n>  \tHANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\n>  \n>  \tif (hSnapshot != INVALID_HANDLE_VALUE) {\n> -\t\tstruct json_writer jw = JSON_WRITER_INIT;\n> -\n> -\t\tjw_array_begin(&jw, 0);\n> -\t\tget_processes(&jw, hSnapshot);\n> -\t\tjw_end(&jw);\n> -\n> -\t\ttrace2_data_json(\"process\", the_repository, \"windows/ancestry\",\n> -\t\t\t\t &jw);\n> -\n> -\t\tjw_release(&jw);\n> +\t\tget_processes(names, hSnapshot);\n>  \t\tCloseHandle(hSnapshot);\n\nNice simplification!\n\n>  void trace2_collect_process_info(enum trace2_process_info_reason reason)\n>  {\n> +\tstruct strvec names = STRVEC_INIT;\n> +\n>  \tif (!trace2_is_enabled())\n>  \t\treturn;\n>  \n>  \tswitch (reason) {\n>  \tcase TRACE2_PROCESS_INFO_STARTUP:\n>  \t\tget_is_being_debugged();\n> -\t\tget_ancestry();\n> +\t\tget_ancestry(&names);\n> +\t\tif (names.nr) {\n> +\t\t\tstruct json_writer jw = JSON_WRITER_INIT;\n> +\t\t\tjw_array_begin(&jw, 0);\n> +\t\t\tfor (size_t i = 0; i < names.nr; i++)\n> +\t\t\t\tjw_array_string(&jw, names.v[i]);\n> +\t\t\tjw_end(&jw);\n> +\t\t\ttrace2_data_json(\"process\", the_repository,\n> +\t\t\t\t\t \"windows/ancestry\", &jw);\n> +\t\t\tjw_release(&jw);\n\nAh, you still have JSON logic at this point.\n\nI see that in your next patch you export the names vector itself _and_\nthis older JSON version. We should consider a future where we drop this\nJSON altogether, but it's nice to have both for a few versions so tool\nmakers have time to respond.\n\nThanks,\n-Stolee\n"},{"id":"535540","messageId":"86a56091-edb7-4f94-b894-63b987eb1ba9@gmail.com","threadId":"64928","inReplyTo":"a06344dc753698ece37f8d066b0a51931b7fa16f.1770307510.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 4/4] trace2: emit cmd_ancestry data for Windows","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2026-02-09T14:42:28Z","receivedAt":"2026-02-09T14:42:30Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 2/5/2026 11:05 AM, Matthew John Cheetham via GitGitGadget wrote:\n> To not break existing consumers of the data_json \"windows/ancestry\"\n> event, we continue to emit the ancestry data as a JSON event.\n\nThis is the important compatibility statement. When this merges, we should\nmake a claim that in two major versions we will drop this compatibility.\n\nThanks,\n-Stolee\n"},{"id":"535541","messageId":"56c1a7eb-a645-4453-8024-b320c1ebd55e@gmail.com","threadId":"64928","inReplyTo":"pull.2040.git.1770307510.gitgitgadget@gmail.com","subject":"Re: [PATCH 0/4] trace2: add macOS and Windows process ancestry tracing","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2026-02-09T14:48:23Z","receivedAt":"2026-02-09T14:48:25Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 2/5/2026 11:05 AM, Matthew John Cheetham via GitGitGadget wrote:\n> In 353d3d77 (trace2: collect Windows-specific process information)\n> Windows-specific process ancestry information was added as a data_json event\n> to TRACE2. Furthermore in 2f732bf1 (tr2: log parent process name) similar\n> functionality was added for Linux-based systems, using procfs.\n> \n> Let's teach Git on macOS to also gather process ancestry information, and\n> emit it as a cmd_ancestry TRACE2 event.\n\nThis is done in patches 1-2. I notice that there are no tests validating\nthat this works.\n\nI see that in t/t0210-trace2-normal.sh there is a scrub_normal() helper\nthat removes the cmd_ancestry event due to compatibility reasons.\n\nI'd be interested to see if we could enable these tests to demonstrate\nyour changes here. Of course, Windows, Linux, and macOS are not the _only_\nplatforms we support. They are the only ones we check in CI, though.\n\n> Furthermore, let's refactor the Windows implementation to align with the\n> Linux and macOS versions - by emitting the ancestry information as a\n> cmd_ancestry event. We keep the older, custom data_json event type on\n> Windows for compatibility for consumers of the TRACE2 data that use the\n> older event.\n\nI appreciate this compatibility approach. I mention in my patch-by-patch\nreview that we should eventually drop the old mechanism, say in two major\nversions.\n\nThe code looks good to me, just a question about the testing and some very\nminor nitpicks around recursion and strvecs.\n\nThanks,\n-Stolee\n"},{"id":"535545","messageId":"VI0PR03MB1163484F620092CD9CE36C836C065A@VI0PR03MB11634.eurprd03.prod.outlook.com","threadId":"64928","inReplyTo":"7390e189-16ac-43b3-a63c-a8b942d5934b@gmail.com","subject":"Re: [PATCH 1/4] trace2: add macOS process ancestry tracing","fromName":"Matthew John Cheetham","fromEmail":"mjcheetham@outlook.com","sentAt":"2026-02-09T15:13:07Z","receivedAt":"2026-02-09T15:13:12Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"On 09/02/2026 14:36, Derrick Stolee wrote:\n\n> On 2/5/2026 11:05 AM, Matthew John Cheetham via GitGitGadget wrote:\n>> Teach Git to also log process ancestry on macOS using the sysctl with\n>> KERN_PROC to get process information (PPID and process name).\n>> Like the Linux implementation, we use the cmd_ancestry TRACE2 event\n>> rather than using a data_json event and creating another custom data\n>> point.\n> \n>> +#define USE_THE_REPOSITORY_VARIABLE\n> \n> If we are creating a new file, then it would be best if we avoid this\n> macro, which is intended for older code to still work until it can be\n> fixed.\n> \n> But also it seems that you don't use the_repository anywhere, so this\n> can be deleted without consequence!\n\nYou are correct - I neglected to remove this macro when preparing to\nsubmit the series. I can remove on the next iteration.\n\n>> +/*\n>> + * Recursively push process names onto the ancestry array.\n>> + * We guard against cycles by limiting the depth to NR_PIDS_LIMIT.\n>> + */\n>> +static void push_ancestry_name(struct strvec *names, pid_t pid, int depth)\n>> +{\n>> +\tstruct strbuf name = STRBUF_INIT;\n>> +\tpid_t ppid;\n>> +\n>> +\tif (depth >= NR_PIDS_LIMIT)\n>> +\t\treturn;\n> \n> Here is the recursion limit check.\n> \n>> +\tif (pid <= 0)\n>> +\t\treturn;\n>> +\n>> +\tif (get_proc_info(pid, &name, &ppid) < 0)\n>> +\t\tgoto cleanup;\n>> +\n>> +\tstrvec_push(names, name.buf);\n> \n> This is copying the buffer, which is why you release it later.\n> \n> Question: could we stop copying here and use strbuf_detach() at this\n> point? That would be a very minor improvement, so feel free to ignore!\n> \n> I took a look and rediscovered that strvecs do not have an option to not\n> copy. I'm thinking about string_list. I'm not sure if there is any value\n> in converting your code just to avoid some string duplication at this\n> scale.\n> \n>> +\t/*\n>> +\t * Recurse to the parent process. Stop if ppid is 0 or 1\n>> +\t * (init/launchd) or if we've reached ourselves (cycle).\n>> +\t */\n>> +\tif (ppid > 1 && ppid != pid)\n>> +\t\tpush_ancestry_name(names, ppid, depth + 1);\n> \n> This kind of tail recursion could be easily converted into a loop. I\n> usually prefer loops to recursion when possible, in case we want to allow\n> an unlimited number of parents in the future.\n\nI had based this on the compat/linux/procinfo.c implementation which\nalso uses recursion to walk the parent processes (and also defines an\nupper limit to the number of processes to walk).\n\nIf I were to transform this to a loop, would we not also be wanting to\nupdate linux/procinfo.c too?\n\n>> +cleanup:\n>> +\tstrbuf_release(&name);\n>> +}\n> \n> I got a little confused by the lack of a .h file, but that's probably due\n> to the extra magic being done at compile time to pick this file on a per-\n> platform basis.\n> \n> Indeed, trace2_collect_process_info() is defined in trace2.h.\n> \n> Thanks,\n> -Stolee\n\nThanks,\nMatthew\n\n"},{"id":"535570","messageId":"xmqqo6lx6e5h.fsf@gitster.g","threadId":"64928","inReplyTo":"56c1a7eb-a645-4453-8024-b320c1ebd55e@gmail.com","subject":"Re: [PATCH 0/4] trace2: add macOS and Windows process ancestry tracing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-09T17:05:30Z","receivedAt":"2026-02-09T17:05:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Derrick Stolee <stolee@gmail.com> writes:\n\n>> Furthermore, let's refactor the Windows implementation to align with the\n>> Linux and macOS versions - by emitting the ancestry information as a\n>> cmd_ancestry event. We keep the older, custom data_json event type on\n>> Windows for compatibility for consumers of the TRACE2 data that use the\n>> older event.\n>\n> I appreciate this compatibility approach. I mention in my patch-by-patch\n> review that we should eventually drop the old mechanism, say in two major\n> versions.\n>\n> The code looks good to me, just a question about the testing and some very\n> minor nitpicks around recursion and strvecs.\n\nThanks for a prompt review (and thanks for the series author for\nwriting the patches, of course).\n\nWill mark as \"expecting a hopefully minor and final reroll\".\n"},{"id":"535635","messageId":"ce2887a1-1324-4ca7-aa1a-549baec7a770@gmail.com","threadId":"64928","inReplyTo":"VI0PR03MB1163484F620092CD9CE36C836C065A@VI0PR03MB11634.eurprd03.prod.outlook.com","subject":"Re: [PATCH 1/4] trace2: add macOS process ancestry tracing","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2026-02-10T04:15:39Z","receivedAt":"2026-02-10T04:15:41Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 2/9/2026 10:13 AM, Matthew John Cheetham wrote:\n> On 09/02/2026 14:36, Derrick Stolee wrote:\n\n>>> +    /*\n>>> +     * Recurse to the parent process. Stop if ppid is 0 or 1\n>>> +     * (init/launchd) or if we've reached ourselves (cycle).\n>>> +     */\n>>> +    if (ppid > 1 && ppid != pid)\n>>> +        push_ancestry_name(names, ppid, depth + 1);\n>>\n>> This kind of tail recursion could be easily converted into a loop. I\n>> usually prefer loops to recursion when possible, in case we want to allow\n>> an unlimited number of parents in the future.\n> \n> I had based this on the compat/linux/procinfo.c implementation which\n> also uses recursion to walk the parent processes (and also defines an\n> upper limit to the number of processes to walk).\n> \n> If I were to transform this to a loop, would we not also be wanting to\n> update linux/procinfo.c too?\n\nIf you're matching the structure in the Linux version, then keep it.\n\nIf it's worth fixing, then it would be worth fixing in both places at\na later time.\n \nThanks,\n-Stolee\n\n"},{"id":"535954","messageId":"pull.2040.v2.git.1771012500.gitgitgadget@gmail.com","threadId":"64928","inReplyTo":"pull.2040.git.1770307510.gitgitgadget@gmail.com","subject":"[PATCH v2 0/6] trace2: add macOS and Windows process ancestry tracing","fromName":"Matthew John Cheetham via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-13T19:54:54Z","receivedAt":"2026-02-13T19:55:04Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"In 353d3d77f4 (trace2: collect Windows-specific process information,\n2019-02-22) Windows-specific process ancestry information was added as a\ndata_json event to TRACE2. Furthermore in 2f732bf15e (tr2: log parent\nprocess name, 2021-07-21) similar functionality was added for Linux-based\nsystems, using procfs.\n\nLet's teach Git on macOS to also gather process ancestry information, and\nemit it as a cmd_ancestry TRACE2 event.\n\nFurthermore, let's refactor the Windows implementation to align with the\nLinux and macOS versions - by emitting the ancestry information as a\ncmd_ancestry event. We keep the older, custom data_json event type on\nWindows for compatibility for consumers of the TRACE2 data that use the\nolder event.\n\nFinally, we add tests of the cmd_ancestry events in the new t0213 test\nscript. Extend the trace2 test helper to allow us to execute commands with a\nknown process in the ancestry (\"test-tool\"); we use this to allow tests to\nfilter out the uncontrolled environment (how the test script was run, and on\nwhat system).\n\nThanks, Matthew\n\n\nUpdates in v2\n=============\n\n * On macOS do not filter out PPID 1 or 0, to match what the Linux\n   implementation does.\n   \n   Stopping before PID 1 and 0 means we do not emit the launchd init process\n   on macOS. The Linux implementation does not do this, nor does the Windows\n   implementation.\n\n * Add t0213-trace2-ancestry tests and extend the trace2 test helper.\n   \n   The tests use the \"400ancestry\" test helper to spawn child processes with\n   controlled trace2 environments. Verify that the process ancestry is being\n   correctly captured on platforms that support cmd_ancestry.\n\n * Drop USE_THE_REPOSITORY_VARIABLE macro as it was not required.\n\n * Updated commit messages to use more standard format to refer to existing\n   commits.\n\nMatthew John Cheetham (6):\n  trace2: add macOS process ancestry tracing\n  build: include procinfo.c impl for macOS\n  trace2: refactor Windows process ancestry trace2 event\n  trace2: emit cmd_ancestry data for Windows\n  test-tool: extend trace2 helper with 400ancestry\n  t0213: add trace2 cmd_ancestry tests\n\n compat/darwin/procinfo.c                 |  97 ++++++++++++\n compat/win32/trace2_win32_process_info.c |  58 ++++----\n config.mak.uname                         |   2 +\n contrib/buildsystems/CMakeLists.txt      |   2 +\n meson.build                              |   2 +\n t/helper/test-trace2.c                   |  59 ++++++++\n t/meson.build                            |   1 +\n t/t0210-trace2-normal.sh                 |   5 +-\n t/t0213-trace2-ancestry.sh               | 180 +++++++++++++++++++++++\n 9 files changed, 379 insertions(+), 27 deletions(-)\n create mode 100644 compat/darwin/procinfo.c\n create mode 100755 t/t0213-trace2-ancestry.sh\n\n\nbase-commit: 9a2fb147f2c61d0cab52c883e7e26f5b7948e3ed\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-2040%2Fmjcheetham%2Ftrace2-macos-ancestry-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2040/mjcheetham/trace2-macos-ancestry-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/2040\n\nRange-diff vs v1:\n\n 1:  d99a30a1a7 ! 1:  233f6cdd33 trace2: add macOS process ancestry tracing\n     @@ Metadata\n       ## Commit message ##\n          trace2: add macOS process ancestry tracing\n      \n     -    In 353d3d77 (trace2: collect Windows-specific process information)\n     -    Windows-specific process ancestry information was added as a data_json\n     -    event to TRACE2. Furthermore in 2f732bf1 (tr2: log parent process name)\n     -    similar functionality was added for Linux-based systems, using procfs.\n     +    In 353d3d77f4 (trace2: collect Windows-specific process information,\n     +    2019-02-22) Windows-specific process ancestry information was added as\n     +    a data_json event to TRACE2. Furthermore in 2f732bf15e (tr2: log\n     +    parent process name, 2021-07-21) similar functionality was added for\n     +    Linux-based systems, using procfs.\n      \n          Teach Git to also log process ancestry on macOS using the sysctl with\n          KERN_PROC to get process information (PPID and process name).\n     @@ Commit message\n      \n       ## compat/darwin/procinfo.c (new) ##\n      @@\n     -+#define USE_THE_REPOSITORY_VARIABLE\n     -+\n      +#include \"git-compat-util.h\"\n      +#include \"strbuf.h\"\n      +#include \"strvec.h\"\n     @@ compat/darwin/procinfo.c (new)\n      +\tstrvec_push(names, name.buf);\n      +\n      +\t/*\n     -+\t * Recurse to the parent process. Stop if ppid is 0 or 1\n     -+\t * (init/launchd) or if we've reached ourselves (cycle).\n     ++\t * Recurse to the parent process. Stop if ppid not valid\n     ++\t * or if we've reached ourselves (cycle).\n      +\t */\n     -+\tif (ppid > 1 && ppid != pid)\n     ++\tif (ppid && ppid != pid)\n      +\t\tpush_ancestry_name(names, ppid, depth + 1);\n      +\n      +cleanup:\n 2:  c786a038f3 = 2:  546fcc3446 build: include procinfo.c impl for macOS\n 3:  7ccd0a9a6d ! 3:  2b02f62f0d trace2: refactor Windows process ancestry trace2 event\n     @@ Metadata\n       ## Commit message ##\n          trace2: refactor Windows process ancestry trace2 event\n      \n     -    In 353d3d77 (trace2: collect Windows-specific process information) we\n     -    added process ancestry information for Windows to TRACE2 via a data_json\n     -    event. It was only later in 2f732bf1 (tr2: log parent process name) that\n     -    the specific cmd_ancestry event was added to TRACE2.\n     +    In 353d3d77f4 (trace2: collect Windows-specific process information,\n     +    2019-02-22) we added process ancestry information for Windows to TRACE2\n     +    via a data_json event. It was only later in 2f732bf15e (tr2: log parent\n     +    process name, 2021-07-21) that the specific cmd_ancestry event was\n     +    added to TRACE2.\n      \n          In a future commit we will emit the ancestry information with the newer\n          cmd_ancestry TRACE2 event. Right now, we rework this implementation of\n 4:  a06344dc75 ! 4:  6b9054115e trace2: emit cmd_ancestry data for Windows\n     @@ Metadata\n       ## Commit message ##\n          trace2: emit cmd_ancestry data for Windows\n      \n     -    Since 2f732bf1 (tr2: log parent process name) it is now possible to emit\n     -    a specific process ancestry event in TRACE2. We should emit the Windows\n     -    process ancestry data with the correct event type.\n     +    Since 2f732bf15e (tr2: log parent process name, 2021-07-21) it is now\n     +    now possible to emit a specific process ancestry event in TRACE2. We\n     +    should emit the Windows process ancestry data with the correct event\n     +    type.\n      \n          To not break existing consumers of the data_json \"windows/ancestry\"\n          event, we continue to emit the ancestry data as a JSON event.\n -:  ---------- > 5:  b9a94291a6 test-tool: extend trace2 helper with 400ancestry\n -:  ---------- > 6:  6a5232540e t0213: add trace2 cmd_ancestry tests\n\n-- \ngitgitgadget\n"},{"id":"535955","messageId":"233f6cdd33efdd91dd5b4a68f7b02d53c32a0739.1771012500.git.gitgitgadget@gmail.com","threadId":"64928","inReplyTo":"pull.2040.v2.git.1771012500.gitgitgadget@gmail.com","subject":"[PATCH v2 1/6] trace2: add macOS process ancestry tracing","fromName":"Matthew John Cheetham via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-13T19:54:55Z","receivedAt":"2026-02-13T19:55:05Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"From: Matthew John Cheetham <mjcheetham@outlook.com>\n\nIn 353d3d77f4 (trace2: collect Windows-specific process information,\n2019-02-22) Windows-specific process ancestry information was added as\na data_json event to TRACE2. Furthermore in 2f732bf15e (tr2: log\nparent process name, 2021-07-21) similar functionality was added for\nLinux-based systems, using procfs.\n\nTeach Git to also log process ancestry on macOS using the sysctl with\nKERN_PROC to get process information (PPID and process name).\nLike the Linux implementation, we use the cmd_ancestry TRACE2 event\nrather than using a data_json event and creating another custom data\npoint.\n\nSigned-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n---\n compat/darwin/procinfo.c | 97 ++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 97 insertions(+)\n create mode 100644 compat/darwin/procinfo.c\n\ndiff --git a/compat/darwin/procinfo.c b/compat/darwin/procinfo.c\nnew file mode 100644\nindex 0000000000..c8954f02d7\n--- /dev/null\n+++ b/compat/darwin/procinfo.c\n@@ -0,0 +1,97 @@\n+#include \"git-compat-util.h\"\n+#include \"strbuf.h\"\n+#include \"strvec.h\"\n+#include \"trace2.h\"\n+#include <sys/sysctl.h>\n+\n+/*\n+ * An arbitrarily chosen value to limit the depth of the ancestor chain.\n+ */\n+#define NR_PIDS_LIMIT 10\n+\n+/*\n+ * Get the process name and parent PID for a given PID using sysctl().\n+ * Returns 0 on success, -1 on failure.\n+ */\n+static int get_proc_info(pid_t pid, struct strbuf *name, pid_t *ppid)\n+{\n+\tint mib[4];\n+\tstruct kinfo_proc proc;\n+\tsize_t size = sizeof(proc);\n+\n+\tmib[0] = CTL_KERN;\n+\tmib[1] = KERN_PROC;\n+\tmib[2] = KERN_PROC_PID;\n+\tmib[3] = pid;\n+\n+\tif (sysctl(mib, 4, &proc, &size, NULL, 0) < 0)\n+\t\treturn -1;\n+\n+\tif (size == 0)\n+\t\treturn -1;\n+\n+\tstrbuf_addstr(name, proc.kp_proc.p_comm);\n+\t*ppid = proc.kp_eproc.e_ppid;\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * Recursively push process names onto the ancestry array.\n+ * We guard against cycles by limiting the depth to NR_PIDS_LIMIT.\n+ */\n+static void push_ancestry_name(struct strvec *names, pid_t pid, int depth)\n+{\n+\tstruct strbuf name = STRBUF_INIT;\n+\tpid_t ppid;\n+\n+\tif (depth >= NR_PIDS_LIMIT)\n+\t\treturn;\n+\n+\tif (pid <= 0)\n+\t\treturn;\n+\n+\tif (get_proc_info(pid, &name, &ppid) < 0)\n+\t\tgoto cleanup;\n+\n+\tstrvec_push(names, name.buf);\n+\n+\t/*\n+\t * Recurse to the parent process. Stop if ppid not valid\n+\t * or if we've reached ourselves (cycle).\n+\t */\n+\tif (ppid && ppid != pid)\n+\t\tpush_ancestry_name(names, ppid, depth + 1);\n+\n+cleanup:\n+\tstrbuf_release(&name);\n+}\n+\n+void trace2_collect_process_info(enum trace2_process_info_reason reason)\n+{\n+\tstruct strvec names = STRVEC_INIT;\n+\n+\tif (!trace2_is_enabled())\n+\t\treturn;\n+\n+\tswitch (reason) {\n+\tcase TRACE2_PROCESS_INFO_STARTUP:\n+\t\tpush_ancestry_name(&names, getppid(), 0);\n+\t\tif (names.nr)\n+\t\t\ttrace2_cmd_ancestry(names.v);\n+\n+\t\tstrvec_clear(&names);\n+\t\tbreak;\n+\n+\tcase TRACE2_PROCESS_INFO_EXIT:\n+\t\t/*\n+\t\t * The Windows version of this calls its\n+\t\t * get_peak_memory_info() here. We may want to insert\n+\t\t * similar process-end statistics here in the future.\n+\t\t */\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tBUG(\"trace2_collect_process_info: unknown reason '%d'\", reason);\n+\t}\n+}\n-- \ngitgitgadget\n\n"},{"id":"535956","messageId":"546fcc3446508eb56312fa195483816d94ea0d41.1771012500.git.gitgitgadget@gmail.com","threadId":"64928","inReplyTo":"pull.2040.v2.git.1771012500.gitgitgadget@gmail.com","subject":"[PATCH v2 2/6] build: include procinfo.c impl for macOS","fromName":"Matthew John Cheetham via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-13T19:54:56Z","receivedAt":"2026-02-13T19:55:07Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"From: Matthew John Cheetham <mjcheetham@outlook.com>\n\nInclude an implementation of trace2_collect_process_info for macOS.\n\nSigned-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n---\n config.mak.uname                    | 2 ++\n contrib/buildsystems/CMakeLists.txt | 2 ++\n meson.build                         | 2 ++\n 3 files changed, 6 insertions(+)\n\ndiff --git a/config.mak.uname b/config.mak.uname\nindex 1691c6ae6e..baa5018461 100644\n--- a/config.mak.uname\n+++ b/config.mak.uname\n@@ -148,6 +148,8 @@ ifeq ($(uname_S),Darwin)\n \tHAVE_NS_GET_EXECUTABLE_PATH = YesPlease\n \tCSPRNG_METHOD = arc4random\n \tUSE_ENHANCED_BASIC_REGULAR_EXPRESSIONS = YesPlease\n+\tHAVE_PLATFORM_PROCINFO = YesPlease\n+\tCOMPAT_OBJS += compat/darwin/procinfo.o\n \n \t# Workaround for `gettext` being keg-only and not even being linked via\n \t# `brew link --force gettext`, should be obsolete as of\ndiff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt\nindex edb0fc04ad..d489f0cada 100644\n--- a/contrib/buildsystems/CMakeLists.txt\n+++ b/contrib/buildsystems/CMakeLists.txt\n@@ -274,6 +274,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\n elseif(CMAKE_SYSTEM_NAME STREQUAL \"Linux\")\n \tadd_compile_definitions(PROCFS_EXECUTABLE_PATH=\"/proc/self/exe\" HAVE_DEV_TTY )\n \tlist(APPEND compat_SOURCES unix-socket.c unix-stream-server.c compat/linux/procinfo.c)\n+elseif(CMAKE_SYSTEM_NAME STREQUAL \"Darwin\")\n+\tlist(APPEND compat_SOURCES compat/darwin/procinfo.c)\n endif()\n \n if(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\ndiff --git a/meson.build b/meson.build\nindex 1f95a06edb..32d470e4f7 100644\n--- a/meson.build\n+++ b/meson.build\n@@ -1292,6 +1292,8 @@ if host_machine.system() == 'linux'\n   libgit_sources += 'compat/linux/procinfo.c'\n elif host_machine.system() == 'windows'\n   libgit_sources += 'compat/win32/trace2_win32_process_info.c'\n+elif host_machine.system() == 'darwin'\n+  libgit_sources += 'compat/darwin/procinfo.c'\n else\n   libgit_sources += 'compat/stub/procinfo.c'\n endif\n-- \ngitgitgadget\n\n"},{"id":"535957","messageId":"2b02f62f0df7ad2ca5356813780577facf02a58d.1771012500.git.gitgitgadget@gmail.com","threadId":"64928","inReplyTo":"pull.2040.v2.git.1771012500.gitgitgadget@gmail.com","subject":"[PATCH v2 3/6] trace2: refactor Windows process ancestry trace2 event","fromName":"Matthew John Cheetham via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-13T19:54:57Z","receivedAt":"2026-02-13T19:55:08Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"From: Matthew John Cheetham <mjcheetham@outlook.com>\n\nIn 353d3d77f4 (trace2: collect Windows-specific process information,\n2019-02-22) we added process ancestry information for Windows to TRACE2\nvia a data_json event. It was only later in 2f732bf15e (tr2: log parent\nprocess name, 2021-07-21) that the specific cmd_ancestry event was\nadded to TRACE2.\n\nIn a future commit we will emit the ancestry information with the newer\ncmd_ancestry TRACE2 event. Right now, we rework this implementation of\ntrace2_collect_process_info to separate the calculation of ancestors\nfrom building and emiting the JSON array via a data_json event.\n\nSigned-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n---\n compat/win32/trace2_win32_process_info.c | 50 ++++++++++++------------\n 1 file changed, 25 insertions(+), 25 deletions(-)\n\ndiff --git a/compat/win32/trace2_win32_process_info.c b/compat/win32/trace2_win32_process_info.c\nindex f147da706a..aceea05430 100644\n--- a/compat/win32/trace2_win32_process_info.c\n+++ b/compat/win32/trace2_win32_process_info.c\n@@ -3,6 +3,7 @@\n #include \"../../git-compat-util.h\"\n #include \"../../json-writer.h\"\n #include \"../../repository.h\"\n+#include \"../../strvec.h\"\n #include \"../../trace2.h\"\n #include \"lazyload.h\"\n #include <psapi.h>\n@@ -32,12 +33,7 @@ static int find_pid(DWORD pid, HANDLE hSnapshot, PROCESSENTRY32 *pe32)\n }\n \n /*\n- * Accumulate JSON array of our parent processes:\n- *     [\n- *         exe-name-parent,\n- *         exe-name-grand-parent,\n- *         ...\n- *     ]\n+ * Accumulate array of our parent process names.\n  *\n  * Note: we only report the filename of the process executable; the\n  *       only way to get its full pathname is to use OpenProcess()\n@@ -73,7 +69,7 @@ static int find_pid(DWORD pid, HANDLE hSnapshot, PROCESSENTRY32 *pe32)\n  * simple and avoid the alloc/realloc overhead.  It is OK if we\n  * truncate the search and return a partial answer.\n  */\n-static void get_processes(struct json_writer *jw, HANDLE hSnapshot)\n+static void get_processes(struct strvec *names, HANDLE hSnapshot)\n {\n \tPROCESSENTRY32 pe32;\n \tDWORD pid;\n@@ -82,19 +78,19 @@ static void get_processes(struct json_writer *jw, HANDLE hSnapshot)\n \n \tpid = GetCurrentProcessId();\n \twhile (find_pid(pid, hSnapshot, &pe32)) {\n-\t\t/* Only report parents. Omit self from the JSON output. */\n+\t\t/* Only report parents. Omit self from the output. */\n \t\tif (nr_pids)\n-\t\t\tjw_array_string(jw, pe32.szExeFile);\n+\t\t\tstrvec_push(names, pe32.szExeFile);\n \n \t\t/* Check for cycle in snapshot. (Yes, it happened.) */\n \t\tfor (k = 0; k < nr_pids; k++)\n \t\t\tif (pid == pid_list[k]) {\n-\t\t\t\tjw_array_string(jw, \"(cycle)\");\n+\t\t\t\tstrvec_push(names, \"(cycle)\");\n \t\t\t\treturn;\n \t\t\t}\n \n \t\tif (nr_pids == NR_PIDS_LIMIT) {\n-\t\t\tjw_array_string(jw, \"(truncated)\");\n+\t\t\tstrvec_push(names, \"(truncated)\");\n \t\t\treturn;\n \t\t}\n \n@@ -105,24 +101,14 @@ static void get_processes(struct json_writer *jw, HANDLE hSnapshot)\n }\n \n /*\n- * Emit JSON data for the current and parent processes.  Individual\n- * trace2 targets can decide how to actually print it.\n+ * Collect the list of parent process names.\n  */\n-static void get_ancestry(void)\n+static void get_ancestry(struct strvec *names)\n {\n \tHANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\n \n \tif (hSnapshot != INVALID_HANDLE_VALUE) {\n-\t\tstruct json_writer jw = JSON_WRITER_INIT;\n-\n-\t\tjw_array_begin(&jw, 0);\n-\t\tget_processes(&jw, hSnapshot);\n-\t\tjw_end(&jw);\n-\n-\t\ttrace2_data_json(\"process\", the_repository, \"windows/ancestry\",\n-\t\t\t\t &jw);\n-\n-\t\tjw_release(&jw);\n+\t\tget_processes(names, hSnapshot);\n \t\tCloseHandle(hSnapshot);\n \t}\n }\n@@ -176,13 +162,27 @@ static void get_peak_memory_info(void)\n \n void trace2_collect_process_info(enum trace2_process_info_reason reason)\n {\n+\tstruct strvec names = STRVEC_INIT;\n+\n \tif (!trace2_is_enabled())\n \t\treturn;\n \n \tswitch (reason) {\n \tcase TRACE2_PROCESS_INFO_STARTUP:\n \t\tget_is_being_debugged();\n-\t\tget_ancestry();\n+\t\tget_ancestry(&names);\n+\t\tif (names.nr) {\n+\t\t\tstruct json_writer jw = JSON_WRITER_INIT;\n+\t\t\tjw_array_begin(&jw, 0);\n+\t\t\tfor (size_t i = 0; i < names.nr; i++)\n+\t\t\t\tjw_array_string(&jw, names.v[i]);\n+\t\t\tjw_end(&jw);\n+\t\t\ttrace2_data_json(\"process\", the_repository,\n+\t\t\t\t\t \"windows/ancestry\", &jw);\n+\t\t\tjw_release(&jw);\n+\t\t}\n+\n+\t\tstrvec_clear(&names);\n \t\treturn;\n \n \tcase TRACE2_PROCESS_INFO_EXIT:\n-- \ngitgitgadget\n\n"},{"id":"535958","messageId":"6b9054115eddeb08d0e429f1ec45093691dd84d3.1771012500.git.gitgitgadget@gmail.com","threadId":"64928","inReplyTo":"pull.2040.v2.git.1771012500.gitgitgadget@gmail.com","subject":"[PATCH v2 4/6] trace2: emit cmd_ancestry data for Windows","fromName":"Matthew John Cheetham via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-13T19:54:58Z","receivedAt":"2026-02-13T19:55:10Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"From: Matthew John Cheetham <mjcheetham@outlook.com>\n\nSince 2f732bf15e (tr2: log parent process name, 2021-07-21) it is now\nnow possible to emit a specific process ancestry event in TRACE2. We\nshould emit the Windows process ancestry data with the correct event\ntype.\n\nTo not break existing consumers of the data_json \"windows/ancestry\"\nevent, we continue to emit the ancestry data as a JSON event.\n\nSigned-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n---\n compat/win32/trace2_win32_process_info.c | 8 ++++++++\n 1 file changed, 8 insertions(+)\n\ndiff --git a/compat/win32/trace2_win32_process_info.c b/compat/win32/trace2_win32_process_info.c\nindex aceea05430..6a6a396078 100644\n--- a/compat/win32/trace2_win32_process_info.c\n+++ b/compat/win32/trace2_win32_process_info.c\n@@ -172,6 +172,11 @@ void trace2_collect_process_info(enum trace2_process_info_reason reason)\n \t\tget_is_being_debugged();\n \t\tget_ancestry(&names);\n \t\tif (names.nr) {\n+\t\t\t/*\n+\t\t\t  Emit the ancestry data as a data_json event to\n+\t\t\t  maintain compatibility for consumers of the older\n+\t\t\t  \"windows/ancestry\" event.\n+\t\t\t */\n \t\t\tstruct json_writer jw = JSON_WRITER_INIT;\n \t\t\tjw_array_begin(&jw, 0);\n \t\t\tfor (size_t i = 0; i < names.nr; i++)\n@@ -180,6 +185,9 @@ void trace2_collect_process_info(enum trace2_process_info_reason reason)\n \t\t\ttrace2_data_json(\"process\", the_repository,\n \t\t\t\t\t \"windows/ancestry\", &jw);\n \t\t\tjw_release(&jw);\n+\n+\t\t\t/* Emit the ancestry data with the new event. */\n+\t\t\ttrace2_cmd_ancestry(names.v);\n \t\t}\n \n \t\tstrvec_clear(&names);\n-- \ngitgitgadget\n\n"},{"id":"535959","messageId":"b9a94291a6238bfe8d4fd05d479b4d6d8ab6efc1.1771012500.git.gitgitgadget@gmail.com","threadId":"64928","inReplyTo":"pull.2040.v2.git.1771012500.gitgitgadget@gmail.com","subject":"[PATCH v2 5/6] test-tool: extend trace2 helper with 400ancestry","fromName":"Matthew John Cheetham via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-13T19:54:59Z","receivedAt":"2026-02-13T19:55:11Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"From: Matthew John Cheetham <mjcheetham@outlook.com>\n\nAdd a new test helper \"400ancestry\" to the trace2 test-tool that\nspawns a child process with a controlled trace2 environment, capturing\nonly the child's trace2 output (including cmd_ancestry events) in\nisolation.\n\nThe helper clears all inherited GIT_TRACE2* variables in the child\nand enables only the requested target (normal, perf, or event),\ndirecting output to a specified file. This gives the test suite a\nreliable way to capture cmd_ancestry events: the child always sees\n\"test-tool\" as its immediate parent in the process ancestry, providing\na predictable value to verify in tests.\n\nSigned-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n---\n t/helper/test-trace2.c | 59 ++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 59 insertions(+)\n\ndiff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c\nindex 415df078c1..3b12f4173e 100644\n--- a/t/helper/test-trace2.c\n+++ b/t/helper/test-trace2.c\n@@ -466,6 +466,63 @@ static int ut_303redact_def_param(int argc, const char **argv)\n \treturn 0;\n }\n \n+/*\n+ * Run a child process with specific trace2 environment settings so that\n+ * we can capture its trace2 output (including cmd_ancestry) in isolation.\n+ *\n+ * test-tool trace2 400ancestry <target> <output_file> [<child_command_line>]\n+ *\n+ * <target> is one of: normal, perf, event\n+ *\n+ * For example:\n+ *     test-tool trace2 400ancestry normal out.normal test-tool trace2 001return 0\n+ *\n+ * The child process inherits a controlled trace2 environment where only\n+ * the specified target is directed to <output_file>. The parent's trace2\n+ * environment variables are cleared in the child so that only the child's\n+ * events are captured.\n+ *\n+ * This is used by t0213-trace2-ancestry.sh to test cmd_ancestry events.\n+ * The child process will see \"test-tool\" as its immediate parent in the\n+ * process ancestry, giving us a predictable value to verify.\n+ */\n+static int ut_400ancestry(int argc, const char **argv)\n+{\n+\tstruct child_process cmd = CHILD_PROCESS_INIT;\n+\tconst char *target;\n+\tconst char *outfile;\n+\tint result;\n+\n+\tif (argc < 3)\n+\t\tdie(\"expect <target> <output_file> <child_command_line>\");\n+\n+\ttarget = argv[0];\n+\toutfile = argv[1];\n+\targv += 2;\n+\targc -= 2;\n+\n+\t/* Clear all trace2 environment variables in the child. */\n+\tstrvec_push(&cmd.env, \"GIT_TRACE2=\");\n+\tstrvec_push(&cmd.env, \"GIT_TRACE2_PERF=\");\n+\tstrvec_push(&cmd.env, \"GIT_TRACE2_EVENT=\");\n+\tstrvec_push(&cmd.env, \"GIT_TRACE2_BRIEF=1\");\n+\n+\t/* Set only the requested target. */\n+\tif (!strcmp(target, \"normal\"))\n+\t\tstrvec_pushf(&cmd.env, \"GIT_TRACE2=%s\", outfile);\n+\telse if (!strcmp(target, \"perf\"))\n+\t\tstrvec_pushf(&cmd.env, \"GIT_TRACE2_PERF=%s\", outfile);\n+\telse if (!strcmp(target, \"event\"))\n+\t\tstrvec_pushf(&cmd.env, \"GIT_TRACE2_EVENT=%s\", outfile);\n+\telse\n+\t\tdie(\"invalid target '%s', expected: normal, perf, event\",\n+\t\t    target);\n+\n+\tstrvec_pushv(&cmd.args, argv);\n+\tresult = run_command(&cmd);\n+\texit(result);\n+}\n+\n /*\n  * Usage:\n  *     test-tool trace2 <ut_name_1> <ut_usage_1>\n@@ -497,6 +554,8 @@ static struct unit_test ut_table[] = {\n \t{ ut_301redact_child_start, \"301redact_child_start\", \"<argv...>\" },\n \t{ ut_302redact_exec,        \"302redact_exec\",        \"<exe> <argv...>\" },\n \t{ ut_303redact_def_param,   \"303redact_def_param\",   \"<key> <value>\" },\n+\n+\t{ ut_400ancestry,           \"400ancestry\",           \"<target> <output_file> [<child_command_line>]\" },\n };\n /* clang-format on */\n \n-- \ngitgitgadget\n\n"},{"id":"535960","messageId":"6a5232540ed8f7138b03cf3df9b7009f54188d97.1771012500.git.gitgitgadget@gmail.com","threadId":"64928","inReplyTo":"pull.2040.v2.git.1771012500.gitgitgadget@gmail.com","subject":"[PATCH v2 6/6] t0213: add trace2 cmd_ancestry tests","fromName":"Matthew John Cheetham via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-13T19:55:00Z","receivedAt":"2026-02-13T19:55:13Z","isPatch":true,"sender":{"key":"mjcheetham@outlook.com","avatar":"https://avatars.githubusercontent.com/u/5658207?v=4"},"body":"From: Matthew John Cheetham <mjcheetham@outlook.com>\n\nAdd a new test script t0213-trace2-ancestry.sh that verifies\ncmd_ancestry events across all three trace2 output formats (normal,\nperf, and event).\n\nThe tests use the \"400ancestry\" test helper to spawn child processes\nwith controlled trace2 environments. Git alias resolution (which\nspawns a child git process) creates a predictable multi-level process\ntree. Filter functions extract cmd_ancestry events from each format,\ntruncating the ancestor list at the outermost \"test-tool\" so that only\nthe controlled portion of the tree is verified, regardless of the test\nrunner environment.\n\nA runtime prerequisite (TRACE2_ANCESTRY) is used to detect whether the\nplatform has a real procinfo implementation; platforms with only the\nstub are skipped.\n\nWe must pay attention to an extra ancestor on Windows (MINGW) when\nrunning without the bin-wrappers (such as we do in CI). In this\nsituation we see an extra \"sh.exe\" ancestor after \"test-tool.exe\".\n\nAlso update the comment in t0210-trace2-normal.sh to reflect that\nancestry testing now has its own dedicated test script.\n\nSigned-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n---\n t/meson.build              |   1 +\n t/t0210-trace2-normal.sh   |   5 +-\n t/t0213-trace2-ancestry.sh | 180 +++++++++++++++++++++++++++++++++++++\n 3 files changed, 184 insertions(+), 2 deletions(-)\n create mode 100755 t/t0213-trace2-ancestry.sh\n\ndiff --git a/t/meson.build b/t/meson.build\nindex a5531df415..551c3036c0 100644\n--- a/t/meson.build\n+++ b/t/meson.build\n@@ -131,6 +131,7 @@ integration_tests = [\n   't0210-trace2-normal.sh',\n   't0211-trace2-perf.sh',\n   't0212-trace2-event.sh',\n+  't0213-trace2-ancestry.sh',\n   't0300-credentials.sh',\n   't0301-credential-cache.sh',\n   't0302-credential-store.sh',\ndiff --git a/t/t0210-trace2-normal.sh b/t/t0210-trace2-normal.sh\nindex 96c68f65df..7e1e7af862 100755\n--- a/t/t0210-trace2-normal.sh\n+++ b/t/t0210-trace2-normal.sh\n@@ -74,8 +74,9 @@ scrub_normal () {\n \t#      This line is only emitted when RUNTIME_PREFIX is defined,\n \t#      so just omit it for testing purposes.\n \t#\n-\t#   4. 'cmd_ancestry' is not implemented everywhere, so for portability's\n-\t#      sake, skip it when parsing normal.\n+\t#   4. 'cmd_ancestry' output depends on how the test is run and\n+\t#      is not relevant to the features we are testing here.\n+\t#      Ancestry tests are covered in t0213-trace2-ancestry.sh instead.\n \tsed \\\n \t\t-e 's/elapsed:[0-9]*\\.[0-9][0-9]*\\([eE][-+]\\{0,1\\}[0-9][0-9]*\\)\\{0,1\\}/elapsed:_TIME_/g' \\\n \t\t-e \"s/^start '[^']*' \\(.*\\)/start _EXE_ \\1/\" \\\ndiff --git a/t/t0213-trace2-ancestry.sh b/t/t0213-trace2-ancestry.sh\nnew file mode 100755\nindex 0000000000..a2b9536da8\n--- /dev/null\n+++ b/t/t0213-trace2-ancestry.sh\n@@ -0,0 +1,180 @@\n+#!/bin/sh\n+\n+test_description='test trace2 cmd_ancestry event'\n+\n+. ./test-lib.sh\n+\n+# Turn off any inherited trace2 settings for this test.\n+sane_unset GIT_TRACE2 GIT_TRACE2_PERF GIT_TRACE2_EVENT\n+sane_unset GIT_TRACE2_BRIEF\n+sane_unset GIT_TRACE2_CONFIG_PARAMS\n+\n+# Add t/helper directory to PATH so that we can use a relative\n+# path to run nested instances of test-tool.exe (see 004child).\n+# This helps with HEREDOC comparisons later.\n+TTDIR=\"$GIT_BUILD_DIR/t/helper/\" && export TTDIR\n+PATH=\"$TTDIR:$PATH\" && export PATH\n+\n+# The 400ancestry helper spawns a child process so that the child\n+# sees \"test-tool\" in its process ancestry.  We capture only the\n+# child's trace2 output to a file.\n+#\n+# The tests use git commands that spawn child git processes (e.g.,\n+# alias resolution) to create a controlled multi-level process tree.\n+# Because cmd_ancestry walks the real process tree, processes will\n+# also report ancestors above \"test-tool\" that depend on the test\n+# runner environment (e.g., bash, make, tmux).  The filter functions\n+# below truncate the ancestry at \"test-tool\", discarding anything\n+# above it, so only the controlled portion is verified.\n+#\n+# On platforms without a real procinfo implementation (the stub),\n+# no cmd_ancestry event is emitted.  We detect this at runtime and\n+# skip the format-specific tests accordingly.\n+\n+# Determine if cmd_ancestry is supported on this platform.\n+test_expect_success 'detect cmd_ancestry support' '\n+\ttest_when_finished \"rm -f trace.detect\" &&\n+\tGIT_TRACE2_BRIEF=1 GIT_TRACE2=\"$(pwd)/trace.detect\" \\\n+\t\ttest-tool trace2 001return 0 &&\n+\tif grep -q \"^cmd_ancestry\" trace.detect\n+\tthen\n+\t\ttest_set_prereq TRACE2_ANCESTRY\n+\tfi\n+'\n+\n+# Filter functions for each trace2 target format.\n+#\n+# Each extracts cmd_ancestry events, strips format-specific syntax,\n+# and truncates the ancestor list at the outermost \"test-tool\"\n+# (or \"test-tool.exe\" on Windows), discarding any higher-level\n+# (uncontrolled) ancestors.\n+#\n+# Output is a space-separated list of ancestor names, one line per\n+# cmd_ancestry event, with the immediate parent listed first:\n+#\n+#   test-tool                          (or: test-tool.exe)\n+#   git test-tool                      (or: git.exe test-tool.exe)\n+#   git test-tool test-tool            (or: git.exe test-tool.exe test-tool.exe)\n+\n+if test_have_prereq MINGW\n+then\n+\tTT=test-tool$X\n+else\n+\tTT=test-tool\n+fi\n+\n+filter_ancestry_normal () {\n+\tsed -n '/^cmd_ancestry/{\n+\t\ts/^cmd_ancestry //\n+\t\ts/ <- / /g\n+\t\ts/\\(.*'\"$TT\"'\\) .*/\\1/\n+\t\tp\n+\t}'\n+}\n+\n+filter_ancestry_perf () {\n+\tsed -n '/cmd_ancestry/{\n+\t\ts/.*ancestry:\\[//\n+\t\ts/\\]//\n+\t\ts/\\(.*'\"$TT\"'\\) .*/\\1/\n+\t\tp\n+\t}'\n+}\n+\n+filter_ancestry_event () {\n+\tsed -n '/\"cmd_ancestry\"/{\n+\t\ts/.*\"ancestry\":\\[//\n+\t\ts/\\].*//\n+\t\ts/\"//g\n+\t\ts/,/ /g\n+\t\ts/\\(.*'\"$TT\"'\\) .*/\\1/\n+\t\tp\n+\t}'\n+}\n+\n+# On Windows (MINGW) when running with the bin-wrappers, we also see \"sh.exe\" in\n+# the ancestry. We must therefore account for this expected ancestry element in\n+# the expected output of the tests.\n+if test_have_prereq MINGW && test -z \"$no_bin_wrappers\"; then\n+\tSH_TT=\"sh$X $TT\"\n+else\n+\tSH_TT=\"$TT\"\n+fi\n+\n+# Git alias resolution spawns the target command as a child process.\n+# Using \"git -c alias.xyz=version xyz\" creates a two-level chain:\n+#\n+#   test-tool (400ancestry)\n+#     -> git (resolves alias xyz -> version)\n+#          -> git (version)\n+#\n+# Both git processes are instrumented and emit cmd_ancestry.  After\n+# filtering out ancestors above test-tool, we get:\n+#\n+#   test-tool                 (from git alias resolver)\n+#   git test-tool             (from git version)\n+\n+test_expect_success TRACE2_ANCESTRY 'normal: git alias chain, 2 levels' '\n+\ttest_when_finished \"rm -f trace.normal actual expect\" &&\n+\ttest-tool trace2 400ancestry normal \"$(pwd)/trace.normal\" \\\n+\t\tgit -c alias.xyz=version xyz &&\n+\tfilter_ancestry_normal <trace.normal >actual &&\n+\tcat >expect <<-EOF &&\n+\t$SH_TT\n+\tgit$X $SH_TT\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success TRACE2_ANCESTRY 'perf: git alias chain, 2 levels' '\n+\ttest_when_finished \"rm -f trace.perf actual expect\" &&\n+\ttest-tool trace2 400ancestry perf \"$(pwd)/trace.perf\" \\\n+\t\tgit -c alias.xyz=version xyz &&\n+\tfilter_ancestry_perf <trace.perf >actual &&\n+\tcat >expect <<-EOF &&\n+\t$SH_TT\n+\tgit$X $SH_TT\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success TRACE2_ANCESTRY 'event: git alias chain, 2 levels' '\n+\ttest_when_finished \"rm -f trace.event actual expect\" &&\n+\ttest-tool trace2 400ancestry event \"$(pwd)/trace.event\" \\\n+\t\tgit -c alias.xyz=version xyz &&\n+\tfilter_ancestry_event <trace.event >actual &&\n+\tcat >expect <<-EOF &&\n+\t$SH_TT\n+\tgit$X $SH_TT\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+# Use 004child to add a test-tool layer, creating a three-level chain:\n+#\n+#   test-tool (400ancestry)\n+#     -> test-tool (004child)\n+#          -> git (resolves alias xyz -> version)\n+#               -> git (version)\n+#\n+# Three instrumented processes emit cmd_ancestry.  After filtering:\n+#\n+#   test-tool                  (from test-tool 004child)\n+#   test-tool test-tool        (from git alias resolver)\n+#   git test-tool test-tool    (from git version)\n+\n+test_expect_success TRACE2_ANCESTRY 'normal: deeper chain, 3 levels' '\n+\ttest_when_finished \"rm -f trace.normal actual expect\" &&\n+\ttest-tool trace2 400ancestry normal \"$(pwd)/trace.normal\" \\\n+\t\ttest-tool trace2 004child \\\n+\t\t\tgit -c alias.xyz=version xyz &&\n+\tfilter_ancestry_normal <trace.normal >actual &&\n+\tcat >expect <<-EOF &&\n+\t$TT\n+\t$SH_TT $TT\n+\tgit$X $SH_TT $TT\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_done\n-- \ngitgitgadget\n"},{"id":"535961","messageId":"xmqqy0kwl6w9.fsf@gitster.g","threadId":"64928","inReplyTo":"546fcc3446508eb56312fa195483816d94ea0d41.1771012500.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 2/6] build: include procinfo.c impl for macOS","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-13T20:34:30Z","receivedAt":"2026-02-13T20:34:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Matthew John Cheetham via GitGitGadget\" <gitgitgadget@gmail.com>\nwrites:\n\n> From: Matthew John Cheetham <mjcheetham@outlook.com>\n>\n> Include an implementation of trace2_collect_process_info for macOS.\n>\n> Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n> ---\n>  config.mak.uname                    | 2 ++\n>  contrib/buildsystems/CMakeLists.txt | 2 ++\n>  meson.build                         | 2 ++\n>  3 files changed, 6 insertions(+)\n\nLooking good.  I wondered if the first two steps should be a single\npatch (as the tree will be with a totally unused file until the\nsecond patch is applied), but this organization will give better\nchances for the second patch to be viewed by folks who are good at\nbuild infrastructure who are not necessarily interested in macOS\nspecific programming, so it probably is better presented this way.\n\n>\n> diff --git a/config.mak.uname b/config.mak.uname\n> index 1691c6ae6e..baa5018461 100644\n> --- a/config.mak.uname\n> +++ b/config.mak.uname\n> @@ -148,6 +148,8 @@ ifeq ($(uname_S),Darwin)\n>  \tHAVE_NS_GET_EXECUTABLE_PATH = YesPlease\n>  \tCSPRNG_METHOD = arc4random\n>  \tUSE_ENHANCED_BASIC_REGULAR_EXPRESSIONS = YesPlease\n> +\tHAVE_PLATFORM_PROCINFO = YesPlease\n> +\tCOMPAT_OBJS += compat/darwin/procinfo.o\n>  \n>  \t# Workaround for `gettext` being keg-only and not even being linked via\n>  \t# `brew link --force gettext`, should be obsolete as of\n> diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt\n> index edb0fc04ad..d489f0cada 100644\n> --- a/contrib/buildsystems/CMakeLists.txt\n> +++ b/contrib/buildsystems/CMakeLists.txt\n> @@ -274,6 +274,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\n>  elseif(CMAKE_SYSTEM_NAME STREQUAL \"Linux\")\n>  \tadd_compile_definitions(PROCFS_EXECUTABLE_PATH=\"/proc/self/exe\" HAVE_DEV_TTY )\n>  \tlist(APPEND compat_SOURCES unix-socket.c unix-stream-server.c compat/linux/procinfo.c)\n> +elseif(CMAKE_SYSTEM_NAME STREQUAL \"Darwin\")\n> +\tlist(APPEND compat_SOURCES compat/darwin/procinfo.c)\n>  endif()\n>  \n>  if(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\n> diff --git a/meson.build b/meson.build\n> index 1f95a06edb..32d470e4f7 100644\n> --- a/meson.build\n> +++ b/meson.build\n> @@ -1292,6 +1292,8 @@ if host_machine.system() == 'linux'\n>    libgit_sources += 'compat/linux/procinfo.c'\n>  elif host_machine.system() == 'windows'\n>    libgit_sources += 'compat/win32/trace2_win32_process_info.c'\n> +elif host_machine.system() == 'darwin'\n> +  libgit_sources += 'compat/darwin/procinfo.c'\n>  else\n>    libgit_sources += 'compat/stub/procinfo.c'\n>  endif\n"},{"id":"535962","messageId":"xmqqtsvkl6sm.fsf@gitster.g","threadId":"64928","inReplyTo":"2b02f62f0df7ad2ca5356813780577facf02a58d.1771012500.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 3/6] trace2: refactor Windows process ancestry trace2 event","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-13T20:36:41Z","receivedAt":"2026-02-13T20:36:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Matthew John Cheetham via GitGitGadget\" <gitgitgadget@gmail.com>\nwrites:\n\n> From: Matthew John Cheetham <mjcheetham@outlook.com>\n>\n> In 353d3d77f4 (trace2: collect Windows-specific process information,\n> 2019-02-22) we added process ancestry information for Windows to TRACE2\n> via a data_json event. It was only later in 2f732bf15e (tr2: log parent\n> process name, 2021-07-21) that the specific cmd_ancestry event was\n> added to TRACE2.\n>\n> In a future commit we will emit the ancestry information with the newer\n> cmd_ancestry TRACE2 event. Right now, we rework this implementation of\n> trace2_collect_process_info to separate the calculation of ancestors\n> from building and emiting the JSON array via a data_json event.\n>\n> Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n> ---\n>  compat/win32/trace2_win32_process_info.c | 50 ++++++++++++------------\n>  1 file changed, 25 insertions(+), 25 deletions(-)\n\nLooks quite straight-forward refactoring that even I (without Win32\nspecific knowledge) can follow with ease.  Nicely done.\n\n>\n> diff --git a/compat/win32/trace2_win32_process_info.c b/compat/win32/trace2_win32_process_info.c\n> index f147da706a..aceea05430 100644\n> --- a/compat/win32/trace2_win32_process_info.c\n> +++ b/compat/win32/trace2_win32_process_info.c\n> @@ -3,6 +3,7 @@\n>  #include \"../../git-compat-util.h\"\n>  #include \"../../json-writer.h\"\n>  #include \"../../repository.h\"\n> +#include \"../../strvec.h\"\n>  #include \"../../trace2.h\"\n>  #include \"lazyload.h\"\n>  #include <psapi.h>\n> @@ -32,12 +33,7 @@ static int find_pid(DWORD pid, HANDLE hSnapshot, PROCESSENTRY32 *pe32)\n>  }\n>  \n>  /*\n> - * Accumulate JSON array of our parent processes:\n> - *     [\n> - *         exe-name-parent,\n> - *         exe-name-grand-parent,\n> - *         ...\n> - *     ]\n> + * Accumulate array of our parent process names.\n>   *\n>   * Note: we only report the filename of the process executable; the\n>   *       only way to get its full pathname is to use OpenProcess()\n> @@ -73,7 +69,7 @@ static int find_pid(DWORD pid, HANDLE hSnapshot, PROCESSENTRY32 *pe32)\n>   * simple and avoid the alloc/realloc overhead.  It is OK if we\n>   * truncate the search and return a partial answer.\n>   */\n> -static void get_processes(struct json_writer *jw, HANDLE hSnapshot)\n> +static void get_processes(struct strvec *names, HANDLE hSnapshot)\n>  {\n>  \tPROCESSENTRY32 pe32;\n>  \tDWORD pid;\n> @@ -82,19 +78,19 @@ static void get_processes(struct json_writer *jw, HANDLE hSnapshot)\n>  \n>  \tpid = GetCurrentProcessId();\n>  \twhile (find_pid(pid, hSnapshot, &pe32)) {\n> -\t\t/* Only report parents. Omit self from the JSON output. */\n> +\t\t/* Only report parents. Omit self from the output. */\n>  \t\tif (nr_pids)\n> -\t\t\tjw_array_string(jw, pe32.szExeFile);\n> +\t\t\tstrvec_push(names, pe32.szExeFile);\n>  \n>  \t\t/* Check for cycle in snapshot. (Yes, it happened.) */\n>  \t\tfor (k = 0; k < nr_pids; k++)\n>  \t\t\tif (pid == pid_list[k]) {\n> -\t\t\t\tjw_array_string(jw, \"(cycle)\");\n> +\t\t\t\tstrvec_push(names, \"(cycle)\");\n>  \t\t\t\treturn;\n>  \t\t\t}\n>  \n>  \t\tif (nr_pids == NR_PIDS_LIMIT) {\n> -\t\t\tjw_array_string(jw, \"(truncated)\");\n> +\t\t\tstrvec_push(names, \"(truncated)\");\n>  \t\t\treturn;\n>  \t\t}\n>  \n> @@ -105,24 +101,14 @@ static void get_processes(struct json_writer *jw, HANDLE hSnapshot)\n>  }\n>  \n>  /*\n> - * Emit JSON data for the current and parent processes.  Individual\n> - * trace2 targets can decide how to actually print it.\n> + * Collect the list of parent process names.\n>   */\n> -static void get_ancestry(void)\n> +static void get_ancestry(struct strvec *names)\n>  {\n>  \tHANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\n>  \n>  \tif (hSnapshot != INVALID_HANDLE_VALUE) {\n> -\t\tstruct json_writer jw = JSON_WRITER_INIT;\n> -\n> -\t\tjw_array_begin(&jw, 0);\n> -\t\tget_processes(&jw, hSnapshot);\n> -\t\tjw_end(&jw);\n> -\n> -\t\ttrace2_data_json(\"process\", the_repository, \"windows/ancestry\",\n> -\t\t\t\t &jw);\n> -\n> -\t\tjw_release(&jw);\n> +\t\tget_processes(names, hSnapshot);\n>  \t\tCloseHandle(hSnapshot);\n>  \t}\n>  }\n> @@ -176,13 +162,27 @@ static void get_peak_memory_info(void)\n>  \n>  void trace2_collect_process_info(enum trace2_process_info_reason reason)\n>  {\n> +\tstruct strvec names = STRVEC_INIT;\n> +\n>  \tif (!trace2_is_enabled())\n>  \t\treturn;\n>  \n>  \tswitch (reason) {\n>  \tcase TRACE2_PROCESS_INFO_STARTUP:\n>  \t\tget_is_being_debugged();\n> -\t\tget_ancestry();\n> +\t\tget_ancestry(&names);\n> +\t\tif (names.nr) {\n> +\t\t\tstruct json_writer jw = JSON_WRITER_INIT;\n> +\t\t\tjw_array_begin(&jw, 0);\n> +\t\t\tfor (size_t i = 0; i < names.nr; i++)\n> +\t\t\t\tjw_array_string(&jw, names.v[i]);\n> +\t\t\tjw_end(&jw);\n> +\t\t\ttrace2_data_json(\"process\", the_repository,\n> +\t\t\t\t\t \"windows/ancestry\", &jw);\n> +\t\t\tjw_release(&jw);\n> +\t\t}\n> +\n> +\t\tstrvec_clear(&names);\n>  \t\treturn;\n>  \n>  \tcase TRACE2_PROCESS_INFO_EXIT:\n"},{"id":"535964","messageId":"xmqqpl68l62h.fsf@gitster.g","threadId":"64928","inReplyTo":"6b9054115eddeb08d0e429f1ec45093691dd84d3.1771012500.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 4/6] trace2: emit cmd_ancestry data for Windows","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-13T20:52:22Z","receivedAt":"2026-02-13T20:52:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Matthew John Cheetham via GitGitGadget\" <gitgitgadget@gmail.com>\nwrites:\n\n> From: Matthew John Cheetham <mjcheetham@outlook.com>\n>\n> Since 2f732bf15e (tr2: log parent process name, 2021-07-21) it is now\n> now possible to emit a specific process ancestry event in TRACE2. We\n> should emit the Windows process ancestry data with the correct event\n> type.\n>\n> To not break existing consumers of the data_json \"windows/ancestry\"\n> event, we continue to emit the ancestry data as a JSON event.\n>\n> Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>\n> ---\n>  compat/win32/trace2_win32_process_info.c | 8 ++++++++\n>  1 file changed, 8 insertions(+)\n\nQuite straight-forward.  Given the way json event readers are\norganized, I suppose that existing readers will not choke on seeing\nthe same data twice?  Are we officially deprecating the \"old way\",\nor keeping both to serve two different audiences (i.e., those who\nhave been in the ecosystem long before this change and want to keep\nreading in the format they are used to, and those who are writing\ncross platform data analyzers that want to stick to a single\nformat)?  I do not think we need to decide it now, and if I were\nasked, I would probably vote for the latter, but just thinking\naloud.\n\nThanks.\n\n> diff --git a/compat/win32/trace2_win32_process_info.c b/compat/win32/trace2_win32_process_info.c\n> index aceea05430..6a6a396078 100644\n> --- a/compat/win32/trace2_win32_process_info.c\n> +++ b/compat/win32/trace2_win32_process_info.c\n> @@ -172,6 +172,11 @@ void trace2_collect_process_info(enum trace2_process_info_reason reason)\n>  \t\tget_is_being_debugged();\n>  \t\tget_ancestry(&names);\n>  \t\tif (names.nr) {\n> +\t\t\t/*\n> +\t\t\t  Emit the ancestry data as a data_json event to\n> +\t\t\t  maintain compatibility for consumers of the older\n> +\t\t\t  \"windows/ancestry\" event.\n> +\t\t\t */\n>  \t\t\tstruct json_writer jw = JSON_WRITER_INIT;\n>  \t\t\tjw_array_begin(&jw, 0);\n>  \t\t\tfor (size_t i = 0; i < names.nr; i++)\n> @@ -180,6 +185,9 @@ void trace2_collect_process_info(enum trace2_process_info_reason reason)\n>  \t\t\ttrace2_data_json(\"process\", the_repository,\n>  \t\t\t\t\t \"windows/ancestry\", &jw);\n>  \t\t\tjw_release(&jw);\n> +\n> +\t\t\t/* Emit the ancestry data with the new event. */\n> +\t\t\ttrace2_cmd_ancestry(names.v);\n>  \t\t}\n>  \n>  \t\tstrvec_clear(&names);\n"},{"id":"535992","messageId":"85375ced-a62b-4f1c-a1c8-4fc4ed09102d@gmail.com","threadId":"64928","inReplyTo":"pull.2040.v2.git.1771012500.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/6] trace2: add macOS and Windows process ancestry tracing","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2026-02-14T00:30:37Z","receivedAt":"2026-02-14T00:30:39Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 2/13/26 2:54 PM, Matthew John Cheetham via GitGitGadget wrote:\n> Updates in v2\n> =============\n> \n>   * On macOS do not filter out PPID 1 or 0, to match what the Linux\n>     implementation does.\n>     \n>     Stopping before PID 1 and 0 means we do not emit the launchd init process\n>     on macOS. The Linux implementation does not do this, nor does the Windows\n>     implementation.\n> \n>   * Add t0213-trace2-ancestry tests and extend the trace2 test helper.\n>     \n>     The tests use the \"400ancestry\" test helper to spawn child processes with\n>     controlled trace2 environments. Verify that the process ancestry is being\n>     correctly captured on platforms that support cmd_ancestry.\n> \n>   * Drop USE_THE_REPOSITORY_VARIABLE macro as it was not required.\n> \n>   * Updated commit messages to use more standard format to refer to existing\n>     commits.\n\nI took a look at the chnages and the new test code. Everything satisfies\nmy concerns from v1.\n\nThanks,\n-Stole\n\n"}]}