Subject: [PATCH v4 0/4] fsmonitor: option to allow fsmonitor to run against network-mounted repos

From: "Eric DeCosta via GitGitGadget" <[email-masked]>
Date: Wed, 31 Aug 2022 16:09:00 +0000

cc: Johannes Schindelin [email-masked] cc: Jeff Hostetler
[email-masked] cc: Eric Sunshine [email-masked] cc: Torsten
Bögershausen [email-masked]

Allow fsmonitor to run against network-mounted repos on macOS.

There are four parts to this effort:

 1. Introduce two new configuration options
    
    fsmonitor.allowRemote - setting this to true overrides fsmonitor's
    default behavior of erroring out when enountering network file systems.
    Additionly, when true, the Unix domain socket (UDS) file used for IPC is
    located in $HOME rather than in the .git directory.
    
    fsmonitor.socketDir - allows for the UDS file to be located anywhere the
    user chooses rather $HOME.

 2. Using the values of above configuration options, locate the UDS file in
    the desired location with a unique name based on the SHA1 of the path of
    the .git folder.

 3. Ensure that both the working directory (.git directory) and the UDS file
    location are compatible with fsmonitor

 4. Normalize the paths returned by FSEvents to the real path for each
    affected file or directory

Eric DeCosta (4):
  fsmonitor: add two new config options, allowRemote and socketDir
  fsmonitor: generate unique Unix socket file name in the desired
    location
  fsmonitor: ensure filesystem and unix socket filesystem are compatible
  fsmonitor: normalize FSEvents event paths to the real path

 compat/fsmonitor/fsm-listen-darwin.c   | 11 ++--
 compat/fsmonitor/fsm-settings-darwin.c | 72 +++++++++++++++++++-------
 fsmonitor-ipc.c                        | 40 ++++++++++++--
 fsmonitor-ipc.h                        |  6 +++
 fsmonitor-settings.c                   | 67 +++++++++++++++++++++++-
 fsmonitor-settings.h                   |  4 ++
 6 files changed, 172 insertions(+), 28 deletions(-)

base-commit: 795ea8776befc95ea2becd8020c7a284677b4161
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1326%2Fedecosta-mw%2Ffsmonitor_macos-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1326/edecosta-mw/fsmonitor_macos-v4
Pull-Request: https://github.com/gitgitgadget/git/pull/1326

Range-diff vs v3:

 1:  cd16d8bb3d6 ! 1:  836a791e6b7 fsmonitor: macOS: allow fsmonitor to run against network-mounted repos
     @@ Metadata
      Author: Eric DeCosta <[email-masked]>
      
       ## Commit message ##
     -    fsmonitor: macOS: allow fsmonitor to run against network-mounted repos
     +    fsmonitor: add two new config options, allowRemote and socketDir
      
     -    Follow-on to the work done to allow Windows to work against
     -    network-mounted repos. Have macOS take advantage of the same
     -    configuration option, 'fsmonitor.allowRemote' that was introduced for
     -    Windows. Setting this option to true will override the default behavior
     -    (erroring-out) when a network-mounted repo is detected by fsmonitor.
     +    Introduce two new configuration options
      
     -    The added wrinkle being that the Unix domain socket (UDS) file used for
     -    IPC cannot be created in a network location; instead $HOME is used if
     -    'fsmonitor.allowRemote' is true.
     +       fsmonitor.allowRemote - setting this to true overrides fsmonitor's
     +       default behavior of erroring out when enountering network file
     +       systems. Additionly, when true, the Unix domain socket (UDS) file
     +       used for IPC is located in $HOME rather than in the .git directory.
      
     -    If $HOME is in a network location, allow the user to override this via
     -    the 'fsmonitor.socketDir' configuration option. There the user can
     -    specify any local directory for the location of the UDS file.
     +       fsmonitor.socketDir - allows for the UDS file to be located
     +       anywhere the user chooses rather $HOME.
      
          Signed-off-by: Eric DeCosta <[email-masked]>
      
     - ## fsmonitor-ipc.c ##
     -@@
     - #include "cache.h"
     --#include "fsmonitor.h"
     --#include "simple-ipc.h"
     - #include "fsmonitor-ipc.h"
     -+#include "fsmonitor-settings.h"
     - #include "run-command.h"
     - #include "strbuf.h"
     - #include "trace2.h"
     -@@ fsmonitor-ipc.c: int fsmonitor_ipc__is_supported(void)
     - 	return 1;
     - }
     - 
     --GIT_PATH_FUNC(fsmonitor_ipc__get_path, "fsmonitor--daemon.ipc")
     -+GIT_PATH_FUNC(fsmonitor_ipc__get_default_path, "fsmonitor--daemon.ipc")
     -+
     -+const char *fsmonitor_ipc__get_path(void)
     -+{
     -+#ifdef WIN32
     -+	return fsmonitor_ipc__get_default_path();
     -+#else
     -+	char *retval;
     -+	SHA_CTX sha1ctx;
     -+	const char *git_dir;
     -+	const char *sock_dir;
     -+	struct strbuf ipc_file = STRBUF_INIT;
     -+	unsigned char hash[SHA_DIGEST_LENGTH];
     -+
     -+	if (fsm_settings__get_allow_remote(the_repository) < 1)
     -+		return fsmonitor_ipc__get_default_path();
     -+
     -+	git_dir = get_git_dir();
     -+	sock_dir = fsm_settings__get_socket_dir(the_repository);
     -+
     -+	SHA1_Init(&sha1ctx);
     -+	SHA1_Update(&sha1ctx, git_dir, strlen(git_dir));
     -+	SHA1_Final(hash, &sha1ctx);
     -+
     -+	if (sock_dir && *sock_dir)
     -+		strbuf_addf(&ipc_file, "%s/.git-fsmonitor-%s",
     -+					sock_dir, hash_to_hex(hash));
     -+	else
     -+		strbuf_addf(&ipc_file, "~/.git-fsmonitor-%s", hash_to_hex(hash));
     -+	retval = interpolate_path(ipc_file.buf, 1);
     -+	if (!retval)
     -+		die(_("Invalid path: %s"), ipc_file.buf);
     -+	strbuf_release(&ipc_file);
     -+	return retval;
     -+#endif
     -+}
     - 
     - enum ipc_active_state fsmonitor_ipc__get_state(void)
     - {
     -
     - ## fsmonitor-ipc.h ##
     -@@ fsmonitor-ipc.h: int fsmonitor_ipc__is_supported(void);
     -  */
     - const char *fsmonitor_ipc__get_path(void);
     - 
     -+/*
     -+ * Returns the pathname to the default IPC named pipe or Unix domain
     -+ * socket.
     -+ */
     -+const char *fsmonitor_ipc__get_default_path(void);
     -+
     - /*
     -  * Try to determine whether there is a `git-fsmonitor--daemon` process
     -  * listening on the IPC pipe/socket.
     -
       ## fsmonitor-settings.c ##
      @@
       struct fsmonitor_settings {
 -:  ----------- > 2:  2cb026a6317 fsmonitor: generate unique Unix socket file name in the desired location
 2:  f977d140afa ! 3:  a3110f1e25a Check working directory and Unix domain socket file for compatability
     @@
       ## Metadata ##
     -Author: edecosta <[email-masked]>
     +Author: Eric DeCosta <[email-masked]>
      
       ## Commit message ##
     -    Check working directory and Unix domain socket file for compatability
     +    fsmonitor: ensure filesystem and unix socket filesystem are compatible
      
          Perform separate checks for the working directory and Unix domain socket
          (UDS) file location. The working directory may be located on a
     @@ Commit message
          file may never be located on a network-mounted file system; additionally
          it may not be located on FAT32 or NTFS file systems.
      
     -    Signed-off-by: edecosta <[email-masked]>
     +    Signed-off-by: Eric DeCosta <[email-masked]>
      
       ## compat/fsmonitor/fsm-settings-darwin.c ##
      @@
 -:  ----------- > 4:  56cabf3be3b fsmonitor: normalize FSEvents event paths to the real path

-- 
gitgitgadget