git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Sparse checkout inconsistency with non-folder paths between cone mode and full matching (2.5.0)

From
FBFinn Bryant <finnbryant@gmail.com>
Date
Jan 30, 2020, 15:25 UTC
Message-ID
<CADSBhNbbO=aq-Oo2MpzDMN2VAX4m6f9Jb-eCtVVX1NfWKE9zJw@mail.gmail.com>
Hi,

With cone mode enabled for a sparse checkout, a pattern like the following is accepted:

/* !/*/ /a_file_or_folder/

As the name suggests, a_file_or_folder might be a file, or might be a directory. If it's a directory, then this is a "valid" recursive match for the directory and everything works as expected. But if the path leads to an ordinary file, it appears that cone mode will *exclude* the file from the worktree (ie, it'll have the skip-worktree flag set). This seems bizarre and unexpected behaviour.

My suspicion is that cone mode is supposed to be a pure subset of full pattern matching, such that if cone mode is ever disabled, the sparseness of the worktree will be unchanged. Clearly, this scenario is breaking that pattern.

I think the correct behaviour is that recursive matches for a potential directory do not have any effect on a non-directory file with the same name. Alternatively, you could forbid any patterns which match non-directory files instead (and downgrade to full pattern matching), though I'd not be a fan of this, since it'd mean the validity of a cone-mode sparse configuration file is dependent on the contents of the repo, and is thus much harder to ascertain (scripts can't simply prove if it's a valid cone mode file by parsing it, they'd need to have access to any repo it may be applied to, and inspect the type of any matching file/folder paths, and its validity could be changed simply by replacing a folder with a file in the repo).

If matching behaviour with full pattern mode is a non-goal for cone mode, I'd still question the logic of this behaviour, though I suppose it does have the benefit of (accidentally?) adding support for excluding individual files from a sparse checkout, which I imagine some could find useful. Personally I'd prefer that was instead added with a more sane syntax, if needed.

Full test case:
$ git init test_repo
Initialized empty Git repository in [path]/test_repo/.git/
$ cd test_repo/
$ touch some_file a_file_or_folder
$ git add some_file a_file_or_folder
$ git commit -m "some files"
[master (root-commit) 80d5918] some files
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a_file_or_folder
 create mode 100644 some_file
$ git sparse-checkout init --cone
$ git read-tree -mu HEAD
$ ls -1
a_file_or_folder
some_file
$ git sparse-checkout set a_file_or_folder
$ git read-tree -mu HEAD
$ ls -1
some_file
$ cat .git/info/sparse-checkout
/*
!/*/
/a_file_or_folder/
$

Right now I'm trying to integrate cone mode with my company's existing manifest infrastructure, which doesn't differentiate between files and folders, so this is forcing me to perform a lot of repo checks to confirm we aren't accidentally excluding files we were supposed to include. Just in case you needed another example of why this behaviour is unhelpful.

Next: Derrick Stolee
Message 1 of 5 in “Sparse checkout inconsistency with non-folder paths between cone mode and full matching (2.5.0)”
  1. Finn BryantJan 30, 2020
  2. Derrick StoleeJan 30, 2020
  3. Derrick StoleeJan 30, 2020
  4. Finn BryantJan 31, 2020
  5. Elijah NewrenJan 31, 2020

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.