git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Alex C. Reed, IV" <acreed4@gmail.com>
To: git@vger.kernel.org
Subject: [BUG] git-stash fails when tracked file is replaced with directory
Date: Wed, 19 Oct 2016 11:34:09 -0400	[thread overview]
Message-ID: <CAGDUdtnUT+_G9bHOYVw_5i-+r9vJHFSjP=Zg2HzA=cQfOkKfwA@mail.gmail.com> (raw)

When a file is deleted from Git and replaced with a directory+file(s),
git-stash has two unexpected behaviors.  This is tested against
versions 2.8.1 and 2.10.1:


1) Old file is removed from index and newly-added directory+file(s)
are added to index.
In this scenario, 'git stash' fails with the message:

    error: <directory>: is a directory - add individual files instead
    fatal: Unable to process path <directory>
    Cannot save the current work tree state

The expected result would be that Git properly records the state
currently stored in index.


2) Old file is removed and new-added directory+file(s) are present
only in worktree, but not added to the index.
In this scenario, 'git stash -u' works fine, but 'git stash apply'
fails with the message:

    fatal: cannot create directory at '<directory>': File exists
    Could not restore untracked files from stash

The expected result would be that Git removes 'file' and replaces with
the untracked contents recorded in the original stash.


It is worth noting that Git does properly handle the scenario where
the stash operation of (1) is replaced with a commit to a temporary
branch, so this quirk seems to be restricted to stashes only.


I found a similar issue reported 22 April 2016 titled "possible bug of
git stash deleting uncommitted files in corner case".  The thread-view
of the message is here:

    http://marc.info/?t=146132568600002&r=1&w=2


Here's a quick-and-dirty bash script to re-create all three scenarios
(1, 2, and 'commit to branch'):

===== BEGIN stash-test.sh
#!/bin/bash

set -x
export GIT_TRACE=1

setup() {
  repo=$1

  # Prepare repo
  rm -rf $repo
  git init $repo
  cd $repo

  # Add initial file (symlink to external assets)
  ln -fs /external/dir dir
  git add dir
  git commit -m "Add symlink to /external/dir"

  # Replace symlink with local copy of assets
  rm dir
  mkdir -p dir
  touch dir/local_copy_of_dir_files
}

{
  ( setup stash-test-unstaged
    git stash -u
    git stash apply )

  ( setup stash-test-staged
    git add .
    git stash )

  ( setup stash-test-commit
    git add .
    git co -b stash-branch
    git commit -m "commit to branch instead of stash" )

} 2>&1 | tee stash-test.log
===== END stash-test.sh


Thanks,
-Alex Reed

                 reply	other threads:[~2016-10-19 15:34 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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='CAGDUdtnUT+_G9bHOYVw_5i-+r9vJHFSjP=Zg2HzA=cQfOkKfwA@mail.gmail.com' \
    --to=acreed4@gmail.com \
    --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).