threads / discuss / 63238

Update symlinks after changing core.symlinks

Subject: Update symlinks after changing core.symlinks

## tl;dr

6 messages between Apr 2, 2025 and Apr 10, 2025.

replies: 5people: 2as markdown or json

Andrej Zhilenkov· Apr 2, 2025, 07:18 UTC · lore

Hello! Is there a direct way to update symlinks in repo after changing core.symlinks? E.g. update plain files, if it was false, with symlinks or vice versa.

I've tried `checkout` and `reset` but they have no effect in this case
(see the snippet below). The only two things that are working:
- checking out a commit before the symlink was introduced and then
checking out any commit after (need to know that special commit to
make it work for those specific symlinks, not practical)
- removing symlinked files and checking them out specifically (need to
either have a list or somehow search for those files to reset)
Is this the way to do it or is there an alternative?

Snippet output: ``` Using temporary directory: /tmp/tmp.gynGH2VcB1 Checking symlink status after creation: lrwxrwxrwx 1 root root 12 Apr 2 07:12 symlink.txt -> original.txt Checking symlink status after checkout: lrwxrwxrwx 1 root root 12 Apr 2 07:12 symlink.txt -> original.txt Checking symlink status after reset: lrwxrwxrwx 1 root root 12 Apr 2 07:12 symlink.txt -> original.txt Checking symlink status after removal and checkout: -rw-r--r-- 1 root root 12 Apr 2 07:12 symlink.txt ```

Snippet: ``` %%shell set -e

# Create a temporary directory TMP_DIR=$(mktemp -d) cd "$TMP_DIR" echo "Using temporary directory: $TMP_DIR"

# Initialize a new Git repository git init -q git config user.name "Test User" git config user.email "test@example.com"

# Create and commit a regular file echo "Hello World" > original.txt git add original.txt git commit -qm "Add original file"

# Add a symlink to the original file and commit ln -s original.txt symlink.txt git add symlink.txt git commit -qm "Add symlink to original file"

echo "Checking symlink status after creation:" ls -l symlink.txt

# Ensure core.symlinks is set to false git config core.symlinks false

# Checkout just the symlink file from the master branch git checkout -- symlink.txt echo "Checking symlink status after checkout:" ls -l symlink.txt

# Try resetting just the symlink file git reset -- symlink.txt echo "Checking symlink status after reset:" ls -l symlink.txt

# Remove the symlink and re-checkout it rm symlink.txt echo "Checking symlink status after removal and checkout:" git checkout -- symlink.txt ls -l symlink.txt

# Cleanup cd .. rm -rf "$TMP_DIR" ```

brian m. carlson· Apr 2, 2025, 22:41 UTC · re: Andrej Zhilenkov · lore

Re: Update symlinks after changing core.symlinks

On 2025-04-02 at 07:18:45, Andrej Zhilenkov wrote:
Show 13 quoted lines
> Hello! Is there a direct way to update symlinks in repo after changing
> core.symlinks?
> E.g. update plain files, if it was false, with symlinks or vice versa.
> 
> I've tried `checkout` and `reset` but they have no effect in this case
> (see the snippet below). The only two things that are working:
> - checking out a commit before the symlink was introduced and then
> checking out any commit after (need to know that special commit to
> make it work for those specific symlinks, not practical)
> - removing symlinked files and checking them out specifically (need to
> either have a list or somehow search for those files to reset)
> 
> Is this the way to do it or is there an alternative?

We don't have a way to do this because `core.symlinks` is intended as a hint from Git to itself about whether the file system and operating system support symlinks that's determined when the repository is created. It's not intended that users modify it, much like `core.filemode` or `core.ignorecase`.

What is your particular use case that requires changing this value?
-- 
brian m. carlson (they/them)
Toronto, Ontario, CA
brian m. carlson· Apr 3, 2025, 22:25 UTC · re: brian m. carlson · lore

Re: Update symlinks after changing core.symlinks

On 2025-04-02 at 22:41:50, brian m. carlson wrote:
Show 22 quoted lines
> On 2025-04-02 at 07:18:45, Andrej Zhilenkov wrote:
> > Hello! Is there a direct way to update symlinks in repo after changing
> > core.symlinks?
> > E.g. update plain files, if it was false, with symlinks or vice versa.
> > 
> > I've tried `checkout` and `reset` but they have no effect in this case
> > (see the snippet below). The only two things that are working:
> > - checking out a commit before the symlink was introduced and then
> > checking out any commit after (need to know that special commit to
> > make it work for those specific symlinks, not practical)
> > - removing symlinked files and checking them out specifically (need to
> > either have a list or somehow search for those files to reset)
> > 
> > Is this the way to do it or is there an alternative?
> 
> We don't have a way to do this because `core.symlinks` is intended as a
> hint from Git to itself about whether the file system and operating
> system support symlinks that's determined when the repository is
> created.  It's not intended that users modify it, much like
> `core.filemode` or `core.ignorecase`.
> 
> What is your particular use case that requires changing this value?

I'll also just mention that this seems to be a particular variant of a use case I've seen elsewhere, which is to force Git to re-check out every object (or at least re-evaluate which objects need to be checked out).

Notably, in Git LFS, it's possible to have the small pointer files in the tree or the large objects. Going from the former to the latter can be done with `git lfs checkout`, but there isn't a good way to go back from the latter to the former. `git checkout` and `git read-tree` don't seem to work properly. I think blowing the index away is possible, but that's obviously less good for lots of reasons. A simple re-evaluation of the smudge filter on each filtered object during a commit would work, though.

So if there's a good use case for the symlink change, such a feature might be more generally useful. I don't plan to implement such a feature, but I would welcome such a change. I am still curious about the reason for changing `core.symlinks`, though.

-- 
brian m. carlson (they/them)
Toronto, Ontario, CA
Andrej Zhilenkov· Apr 4, 2025, 05:51 UTC · re: brian m. carlson · lore

Re: Update symlinks after changing core.symlinks

> On 2025-04-02 at 22:41:50, brian m. carlson wrote:
> > What is your particular use case that requires changing this value?
Hi, thank you for your reply.

Just recently started working with symlinks in git and I've found that in Git for Windows they are disabled by default (https://gitforwindows.org/symbolic-links.html). It's possible to just change the setting in system config or override it in global config, but it's probably safe to assume that the average Windows user will have them disabled. And if your repo needs them, it's probably more reasonable to ask the user to enable symlinks in a local config, not global. So, you can enable them during clone `git clone -c core.symlinks=true` but I guess as a user (and symlinks not being used very often) you typically learn about repo having symlinks and you needing them after repo was cloned. So this is the use case I've found for `git checkout` or some other command refreshing files based on current `core.symlinks` value. Without this feature you would need to have a script where you list all symlinks, remove them with `rm` / `del` and only then you can check them out.

Maybe there are similar cases but on Unix when users would want `core.symlinks` disabled globally and be enabled on a per-repo basis but I can't imagine why.

brian m. carlson· Apr 4, 2025, 07:31 UTC · re: Andrej Zhilenkov · lore

Re: Update symlinks after changing core.symlinks

On 2025-04-04 at 05:51:21, Andrej Zhilenkov wrote:
> Just recently started working with symlinks in git and I've found that
> in Git for Windows they are disabled by default
> (https://gitforwindows.org/symbolic-links.html).

Yes, that's true. On Windows, symlinks require elevated privileges to create by default unless you're in Developer Mode (which I highly recommend for Git users and developers). That's the main reason they're disabled by default: because they simply can't be created in many cases.

> It's possible to just change the setting in system config or override
> it in global config, but it's probably safe to assume that the average
> Windows user will have them disabled.

I think it depends. If you're working in software development, you really should have them enabled and many users will, but I agree some users may not (say, because they're in a corporate environment and they're not permitted).

> And if your repo needs them, it's probably more reasonable to ask the
> user to enable symlinks in a local config, not global.

Ah, there I disagree. I think if you have privileges to create symlinks, you probably want them to always be enabled, and if not, you don't really have a choice and they'll be disabled. My experience with using repositories with symbolic links is that typically they don't function at all (or, if the maintainer has taken great care, only with greatly reduced functionality) if the symlinks are missing. I think Git's repository is by far the exception here.

> Maybe there are similar cases but on Unix when users would want
> `core.symlinks` disabled globally and be enabled on a per-repo basis
> but I can't imagine why.

I have certainly seen cases on Unix systems where symlinks didn't work. For instance, they don't work on FAT-based file systems, and I have also seen a Linux distro that tried to restrict symlink creation to work only when the creating user owned the destination file, which breaks Git's symlink functionality (I quickly demonstrated this "security" feature could be trivially bypassed).

However, I don't think there's generally a situation in which you'd _want_ it to be disabled globally.

-- 
brian m. carlson (they/them)
Toronto, Ontario, CA
Andrej Zhilenkov· Apr 10, 2025, 19:29 UTC · re: brian m. carlson · lore

Re: Update symlinks after changing core.symlinks

Show 7 quoted lines
> Ah, there I disagree.  I think if you have privileges to create
> symlinks, you probably want them to always be enabled, and if not, you
> don't really have a choice and they'll be disabled.  My experience with
> using repositories with symbolic links is that typically they don't
> function at all (or, if the maintainer has taken great care, only with
> greatly reduced functionality) if the symlinks are missing.  I think
> Git's repository is by far the exception here.

I personally agree that everyone should just enable them globally if they can. Still, maybe it's just me, but I don't like proposing global changes to users when they need it just for some repo.

And also, I keep seeing Windows users having `git config --local core.symlinks` set to `false` (God knows why - in theory Git for Windows suppose to set `--system core.symlinks` to `false`, `--local` shouldn't be affected by this) and just setting `--local` helps covering those cases too.

← back to recent threads