{"thread":{"id":"63238","subject":"Update symlinks after changing core.symlinks","startedAt":"2025-04-02T07:18:58Z","lastAt":"2025-04-10T19:29:59Z","messageCount":6,"participants":["Andrej Zhilenkov","brian m. carlson"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"515484","messageId":"CAArAzAoU9qDj+yLi3pA6wFYdTAk0UvQk4omSWM1RL4D9w5fw_w@mail.gmail.com","threadId":"63238","inReplyTo":null,"subject":"Update symlinks after changing core.symlinks","fromName":"Andrej Zhilenkov","fromEmail":"azhilenkov@gmail.com","sentAt":"2025-04-02T07:18:45Z","receivedAt":"2025-04-02T07:18:58Z","isPatch":false,"sender":{"key":"azhilenkov@gmail.com","avatar":null},"body":"Hello! Is there a direct way to update symlinks in repo after changing\ncore.symlinks?\nE.g. update plain files, if it was false, with symlinks or vice versa.\n\nI've tried `checkout` and `reset` but they have no effect in this case\n(see the snippet below). The only two things that are working:\n- checking out a commit before the symlink was introduced and then\nchecking out any commit after (need to know that special commit to\nmake it work for those specific symlinks, not practical)\n- removing symlinked files and checking them out specifically (need to\neither have a list or somehow search for those files to reset)\n\nIs this the way to do it or is there an alternative?\n\nSnippet output:\n```\nUsing temporary directory: /tmp/tmp.gynGH2VcB1\nChecking symlink status after creation:\nlrwxrwxrwx 1 root root 12 Apr  2 07:12 symlink.txt -> original.txt\nChecking symlink status after checkout:\nlrwxrwxrwx 1 root root 12 Apr  2 07:12 symlink.txt -> original.txt\nChecking symlink status after reset:\nlrwxrwxrwx 1 root root 12 Apr  2 07:12 symlink.txt -> original.txt\nChecking symlink status after removal and checkout:\n-rw-r--r-- 1 root root 12 Apr  2 07:12 symlink.txt\n```\n\nSnippet:\n```\n%%shell\nset -e\n\n# Create a temporary directory\nTMP_DIR=$(mktemp -d)\ncd \"$TMP_DIR\"\necho \"Using temporary directory: $TMP_DIR\"\n\n# Initialize a new Git repository\ngit init -q\ngit config user.name \"Test User\"\ngit config user.email \"test@example.com\"\n\n# Create and commit a regular file\necho \"Hello World\" > original.txt\ngit add original.txt\ngit commit -qm \"Add original file\"\n\n# Add a symlink to the original file and commit\nln -s original.txt symlink.txt\ngit add symlink.txt\ngit commit -qm \"Add symlink to original file\"\n\necho \"Checking symlink status after creation:\"\nls -l symlink.txt\n\n# Ensure core.symlinks is set to false\ngit config core.symlinks false\n\n# Checkout just the symlink file from the master branch\ngit checkout -- symlink.txt\necho \"Checking symlink status after checkout:\"\nls -l symlink.txt\n\n# Try resetting just the symlink file\ngit reset -- symlink.txt\necho \"Checking symlink status after reset:\"\nls -l symlink.txt\n\n# Remove the symlink and re-checkout it\nrm symlink.txt\necho \"Checking symlink status after removal and checkout:\"\ngit checkout -- symlink.txt\nls -l symlink.txt\n\n# Cleanup\ncd ..\nrm -rf \"$TMP_DIR\"\n```\n"},{"id":"515543","messageId":"Z-29LsgDvcS0qY5a@tapette.crustytoothpaste.net","threadId":"63238","inReplyTo":"CAArAzAoU9qDj+yLi3pA6wFYdTAk0UvQk4omSWM1RL4D9w5fw_w@mail.gmail.com","subject":"Re: Update symlinks after changing core.symlinks","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2025-04-02T22:41:50Z","receivedAt":"2025-04-02T22:41:53Z","isPatch":false,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2025-04-02 at 07:18:45, Andrej Zhilenkov wrote:\n> Hello! Is there a direct way to update symlinks in repo after changing\n> core.symlinks?\n> E.g. update plain files, if it was false, with symlinks or vice versa.\n> \n> I've tried `checkout` and `reset` but they have no effect in this case\n> (see the snippet below). The only two things that are working:\n> - checking out a commit before the symlink was introduced and then\n> checking out any commit after (need to know that special commit to\n> make it work for those specific symlinks, not practical)\n> - removing symlinked files and checking them out specifically (need to\n> either have a list or somehow search for those files to reset)\n> \n> Is this the way to do it or is there an alternative?\n\nWe don't have a way to do this because `core.symlinks` is intended as a\nhint from Git to itself about whether the file system and operating\nsystem support symlinks that's determined when the repository is\ncreated.  It's not intended that users modify it, much like\n`core.filemode` or `core.ignorecase`.\n\nWhat is your particular use case that requires changing this value?\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"},{"id":"515616","messageId":"Z-8K9ZIt4j_UMNZm@tapette.crustytoothpaste.net","threadId":"63238","inReplyTo":"Z-29LsgDvcS0qY5a@tapette.crustytoothpaste.net","subject":"Re: Update symlinks after changing core.symlinks","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2025-04-03T22:25:57Z","receivedAt":"2025-04-03T22:25:59Z","isPatch":false,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2025-04-02 at 22:41:50, brian m. carlson wrote:\n> On 2025-04-02 at 07:18:45, Andrej Zhilenkov wrote:\n> > Hello! Is there a direct way to update symlinks in repo after changing\n> > core.symlinks?\n> > E.g. update plain files, if it was false, with symlinks or vice versa.\n> > \n> > I've tried `checkout` and `reset` but they have no effect in this case\n> > (see the snippet below). The only two things that are working:\n> > - checking out a commit before the symlink was introduced and then\n> > checking out any commit after (need to know that special commit to\n> > make it work for those specific symlinks, not practical)\n> > - removing symlinked files and checking them out specifically (need to\n> > either have a list or somehow search for those files to reset)\n> > \n> > Is this the way to do it or is there an alternative?\n> \n> We don't have a way to do this because `core.symlinks` is intended as a\n> hint from Git to itself about whether the file system and operating\n> system support symlinks that's determined when the repository is\n> created.  It's not intended that users modify it, much like\n> `core.filemode` or `core.ignorecase`.\n> \n> What is your particular use case that requires changing this value?\n\nI'll also just mention that this seems to be a particular variant of a\nuse case I've seen elsewhere, which is to force Git to re-check out\nevery object (or at least re-evaluate which objects need to be checked\nout).\n\nNotably, in Git LFS, it's possible to have the small pointer files in\nthe tree or the large objects.  Going from the former to the latter can\nbe done with `git lfs checkout`, but there isn't a good way to go back\nfrom the latter to the former.  `git checkout` and `git read-tree` don't\nseem to work properly.  I think blowing the index away is possible, but\nthat's obviously less good for lots of reasons.  A simple re-evaluation\nof the smudge filter on each filtered object during a commit would work,\nthough.\n\nSo if there's a good use case for the symlink change, such a feature\nmight be more generally useful.  I don't plan to implement such a\nfeature, but I would welcome such a change.  I am still curious about\nthe reason for changing `core.symlinks`, though.\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"},{"id":"515635","messageId":"CAArAzAr+YPwVXJo8mjkyQG8uWv=wt89tYyp6TL-rNzvwVYm9YA@mail.gmail.com","threadId":"63238","inReplyTo":"Z-8K9ZIt4j_UMNZm@tapette.crustytoothpaste.net","subject":"Re: Update symlinks after changing core.symlinks","fromName":"Andrej Zhilenkov","fromEmail":"azhilenkov@gmail.com","sentAt":"2025-04-04T05:51:21Z","receivedAt":"2025-04-04T05:51:33Z","isPatch":false,"sender":{"key":"azhilenkov@gmail.com","avatar":null},"body":"> On 2025-04-02 at 22:41:50, brian m. carlson wrote:\n> > What is your particular use case that requires changing this value?\n\nHi, thank you for your reply.\n\nJust recently started working with symlinks in git and I've found that\nin Git for Windows they are disabled by default\n(https://gitforwindows.org/symbolic-links.html).\nIt's possible to just change the setting in system config or override\nit in global config, but it's probably safe to assume that the average\nWindows user will have them disabled.\nAnd if your repo needs them, it's probably more reasonable to ask the\nuser to enable symlinks in a local config, not global.\nSo, you can enable them during clone `git clone -c core.symlinks=true`\nbut I guess as a user (and symlinks not being used very often) you\ntypically learn about repo having symlinks and you needing them after\nrepo was cloned.\nSo this is the use case I've found for `git checkout` or some other\ncommand refreshing files based on current `core.symlinks` value.\nWithout this feature you would need to have a script where you list\nall symlinks, remove them with `rm` / `del` and only then you can\ncheck them out.\n\nMaybe there are similar cases but on Unix when users would want\n`core.symlinks` disabled globally and be enabled on a per-repo basis\nbut I can't imagine why.\n"},{"id":"515637","messageId":"Z--Kz4jsRzm4VSZd@tapette.crustytoothpaste.net","threadId":"63238","inReplyTo":"CAArAzAr+YPwVXJo8mjkyQG8uWv=wt89tYyp6TL-rNzvwVYm9YA@mail.gmail.com","subject":"Re: Update symlinks after changing core.symlinks","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2025-04-04T07:31:27Z","receivedAt":"2025-04-04T07:31:29Z","isPatch":false,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2025-04-04 at 05:51:21, Andrej Zhilenkov wrote:\n> Just recently started working with symlinks in git and I've found that\n> in Git for Windows they are disabled by default\n> (https://gitforwindows.org/symbolic-links.html).\n\nYes, that's true.  On Windows, symlinks require elevated privileges to\ncreate by default unless you're in Developer Mode (which I highly\nrecommend for Git users and developers).  That's the main reason they're\ndisabled by default: because they simply can't be created in many cases.\n\n> It's possible to just change the setting in system config or override\n> it in global config, but it's probably safe to assume that the average\n> Windows user will have them disabled.\n\nI think it depends.  If you're working in software development, you\nreally should have them enabled and many users will, but I agree some\nusers may not (say, because they're in a corporate environment and\nthey're not permitted).\n\n> And if your repo needs them, it's probably more reasonable to ask the\n> user to enable symlinks in a local config, not global.\n\nAh, there I disagree.  I think if you have privileges to create\nsymlinks, you probably want them to always be enabled, and if not, you\ndon't really have a choice and they'll be disabled.  My experience with\nusing repositories with symbolic links is that typically they don't\nfunction at all (or, if the maintainer has taken great care, only with\ngreatly reduced functionality) if the symlinks are missing.  I think\nGit's repository is by far the exception here.\n\n> Maybe there are similar cases but on Unix when users would want\n> `core.symlinks` disabled globally and be enabled on a per-repo basis\n> but I can't imagine why.\n\nI have certainly seen cases on Unix systems where symlinks didn't work.\nFor instance, they don't work on FAT-based file systems, and I have also\nseen a Linux distro that tried to restrict symlink creation to work only\nwhen the creating user owned the destination file, which breaks Git's\nsymlink functionality (I quickly demonstrated this \"security\" feature\ncould be trivially bypassed).\n\nHowever, I don't think there's generally a situation in which you'd\n_want_ it to be disabled globally.\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"},{"id":"515968","messageId":"CAArAzArGWE8S2gjvueS+fQ9c56mbzrRV5=0V8SaSX1NUMSXDSg@mail.gmail.com","threadId":"63238","inReplyTo":"Z--Kz4jsRzm4VSZd@tapette.crustytoothpaste.net","subject":"Re: Update symlinks after changing core.symlinks","fromName":"Andrej Zhilenkov","fromEmail":"azhilenkov@gmail.com","sentAt":"2025-04-10T19:29:46Z","receivedAt":"2025-04-10T19:29:59Z","isPatch":false,"sender":{"key":"azhilenkov@gmail.com","avatar":null},"body":"> Ah, there I disagree.  I think if you have privileges to create\n> symlinks, you probably want them to always be enabled, and if not, you\n> don't really have a choice and they'll be disabled.  My experience with\n> using repositories with symbolic links is that typically they don't\n> function at all (or, if the maintainer has taken great care, only with\n> greatly reduced functionality) if the symlinks are missing.  I think\n> Git's repository is by far the exception here.\n\nI personally agree that everyone should just enable them globally if\nthey can. Still, maybe it's just me, but I don't like proposing global\nchanges to users when they need it just for some repo.\n\nAnd also, I keep seeing Windows users having `git config --local\ncore.symlinks` set to `false` (God knows why - in theory Git for\nWindows suppose to set `--system core.symlinks` to `false`, `--local`\nshouldn't be affected by this) and just setting `--local` helps\ncovering those cases too.\n"}]}