git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Christian Spanier <cspanier@boxie.eu>
To: git@vger.kernel.org
Subject: bug: git pull may delete untracked files in submodule without notice
Date: Fri, 3 May 2019 10:02:35 +0200	[thread overview]
Message-ID: <2e321dbe-42a3-7516-52aa-4bc50a3c403e@boxie.eu> (raw)

Hi,

I found a bug where Git may delete untracked files without notice in 
certain situations. This bug effects Git 2.21.0 both on Linux and Windows.
In summary this happens when git pull merges a commit that replaces a 
submodule folder with a symlink. Any files within the folder are deleted 
without notice.
Check out the script below for details.

This happend on some developer's machine and deleted a repository 
containing about 200GiB of files and tons of uncommited local scripts, 
log files and whatever, just because some other dev accidentally 
commited a temporary change.

Greetings,
Christian Spanier

##### PREPARATION #####

# New empty repository #1
mkdir rep1
cd rep1
git init --bare .
cd ..

# New empty repository #2
mkdir rep2
cd rep2
git init --bare .
cd ..

# Clone repository #1 and create initial commit
git clone rep1 clone_rep1_user1
cd clone_rep1_user1
touch README
git add README
git commit -m "initial commit"
git push
cd ..

# Clone repository #2 and create initial commit
git clone rep2 clone_rep2
cd clone_rep2
touch README
git add README
git commit -m "initial commit"
git push
cd ..

# Add repository #2 as a submodule to repository #1
cd clone_rep1_user1
git submodule add ../rep2
git commit -m "add submodule"
git push
cd ..

# User 2 also clones repository #1 and #2 recursively
git clone --recursive rep1 clone_rep1_user2

# User 2 starts working in his folder and adds an important local file 
which is
# not yet committed inside the submodule folder.
cd clone_rep1_user2/rep2
echo "important work" > uncommitted_file
cd ../../

# Meanwhile, user 1 temporarily switch out folder /clone_rep1_user1/rep2 
with a
# symbolic link to a different folder (for whatever reason, maybe a copy 
of an
# older version or anything).
mkdir rep2_alternative
cd clone_rep1_user1
mv rep2 ../rep2_backup
ln -s ../rep2_alternative rep2
# On Windows this can be done with 'mklink /D rep2 ../rep2_alternative',
# which requires admin privileges. The bug is not reproducible when
# using a directory junction with 'mklink /D /J ...'.

# He does some work on rep1 but then accidently adds the symbolic link 
to his
# next commit and pushes the changes. Notice the typechange of rep2.
echo "some" > work
git status
# On branch master
# Your branch is up to date with 'origin/master'.
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working 
directory)
#
#         typechange: rep2
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#         work
#
# no changes added to commit (use "git add" and/or "git commit -a")
git add .
git commit -m "do some work"
git push
cd ..

# NOW THE BUG:

# User 2 pulls the changes and loses his important work in
# rep2/uncommitted_file because Git replaces the folder with a symlink
# without checking for modified or uncommited files!
# He should get an error in this case!
cd clone_rep1_user2
git pull
cat rep2/uncommitted_file
# cat: rep2/uncommitted_file: Not a directory
# "important work" in rep2/uncommitted_file is gone :(

             reply	other threads:[~2019-05-03 10:02 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-03  8:02 Christian Spanier [this message]
2019-05-03 10:28 ` bug: git pull may delete untracked files in submodule without notice Duy Nguyen
2019-05-03 15:10   ` Phillip Wood

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2e321dbe-42a3-7516-52aa-4bc50a3c403e@boxie.eu \
    --to=cspanier@boxie.eu \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).