Git development
 help / color / mirror / Atom feed
* [PATCH] git pull silently overwrites local directory with symlink due to .gitignore "dir/"
@ 2026-09-07  8:19 AIKSXD ax
  2026-09-07 19:41 ` brian m. carlson
  0 siblings, 1 reply; 2+ messages in thread
From: AIKSXD ax @ 2026-09-07  8:19 UTC (permalink / raw)
  To: git@vger.kernel.org

Hello,I would like to report a issue in Git that can cause silent data loss on user machines. The problem occurs when a '.gitignore' pattern ending with a slash (e.g. 'dir/') is used to ignore a directory, but a symbolic link with the same name will be committed. Later, when another user pulls the repository, Git silently replaces their local directory with that symlink, destroying all data inside it without any hints.

OS: Linux(Git 2.43.0) & Windows(Git 2.53.0.windows.2) both reproduced

Concrete example (from a real incident):
1. We had a repository with a symlink named 'dataset' pointing to a large data directory located outside the repo:

 ➜  experiment git:(main) ✗ ll
        total 0
        lrwxrwxrwx 1 ax ax 10 Sep  7 14:11 dataset -> ../dataset
        -rw-r--r-- 1 ax ax  0 Sep  7 14:17 train.py

➜  experiment git:(main) ✗ cat .gitignore
        dataset/

➜  experiment git:(main) ✗ git add . && git commit -m "feat: ..." && git push
        [main 6a9dca8] feat: ...
        1 file changed, 1 insertion(+)
        create mode 120000 dataset

-------------
2. On another machine, the same repository had a real directory named 'dataset' containing important data. After `git pull`, Git replaced that directory with the symlink without any warning:

➜  experiment git:(main) du -h -d 0 dataset
        64M     dataset

➜  experiment git:(main) ll
        total 4.0K
        drwxr-xr-x 3 ax ax 4.0K Sep  7 14:32 dataset
        -rw-r--r-- 1 ax ax    0 Sep  7 14:31 train.py

➜  experiment git:(main) git pull
        remote: Enumerating objects: 4, done.
        remote: Counting objects: 100% (4/4), done.
        remote: Compressing objects: 100% (2/2), done.
        remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0 (from 0)
        Unpacking objects: 100% (3/3), 292 bytes | 292.00 KiB/s, done.
        From github.com:aiksxd/experiment
           0bdcba7..6a9dca8  main       -> origin/main
        Updating 0bdcba7..6a9dca8
        Fast-forward
         dataset | 1 +
         1 file changed, 1 insertion(+)
         create mode 120000 dataset

➜  experiment git:(main) ll
        total 0
        lrwxrwxrwx 1 ax ax 10 Sep  7 14:38 dataset -> ../dataset
        -rw-r--r-- 1 ax ax  0 Sep  7 14:31 train.py

➜  experiment git:(main) du -h -d 0 dataset
        0       dataset

-----------
- The symlink is tracked and committed because the trailing-slash ignore rule have no effect on files.
- On pull, Git silently replaces the local directory with the symlink, causing irreversible data loss.
This is unacceptable behavior; Git should never overwrite a local directory with a symlink without explicit user confirmation.

Impact:
This issue can result in the loss of hundreds of gigabytes of local data, as users often keep large datasets or other important directories with the same name as an ignored symlink. The data loss is silent and occurs during a routine 'git pull'( I don’t know why so much free space showed up on my computer that day).

My options:
The pattern 'dataset/' should also ignore a symlink with that name, so it never enters the repository in the first place.
If such a symlink is committed (accidentally or otherwise), Git must detect the conflict when pulling to a machine that has a real directory at the same path, and refuse to overwrite it without prompting.

Thank you for your time and for maintaining Git.

Best regards,
aiksxd@126.com

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-09-07 19:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-07  8:19 [PATCH] git pull silently overwrites local directory with symlink due to .gitignore "dir/" AIKSXD ax
2026-09-07 19:41 ` brian m. carlson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox