简体   繁体   中英

git status showing existing files have been deleted

Running git status I see a number of files marked deleted :

On branch my-branch
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    deleted:    nta/executor/.gitignore
    deleted:    nta/executor/NTA_EXECUTOR_README.md
    deleted:    nta/pom.xml
    ...

though these files still exist in the file system. I tried using the suggested method to unstage these changes, for example

git restore --staged nta/executor/.gitignore

This worked on some of the files, but many others remain listed as deleted .

A number of other SO questions describe similar problems:

but the methods described therein have not solved my particular problem. I have tried

git reset <file>
git reset --hard <file>  # fatal: Cannot do hard reset with paths.
git reset -- <file>
git checkout -- <file>

with no luck. Any other ideas?


Additionally

If it helps, here's a description of the probably stupid thing I did to get here:

I wanted to stage a number of files called foo in various directories:

git add */*/foo

This ended up adding many more foo s than I expected. So I attempted to backtrack:

git restore --staged  */*/foo

And suddenly a ton of non- foo files were listed as deleted

(and now you know the rest of the story)

In my case, there were some pathnames which didn't harm Linux' git, but unfortunately broke Windows' git. Anaconda is doing backups in the background and uses : in the filename. So there were Windows-bad filenames , git didn't clone anything from remote to Windows local and listed all files in the list of changed files to commit with "deleted:" - because my local folder was of course empty.

I just had to search these files from Anaconda / Jupyter Notebook in Ubuntu, rename or delete them, commit and push again to get my git-archive to Windows OS.

Realization from this experience is, that when there is a commit in Linux with filenames incompatible to the OS you're cloning to, git will correctly add those not-cloned files as immediate local changes to the index - even in an initial cloned archive.

Removing them from the changes-list was - for me - only possible with changing the filenames somewhere else outside Windows.

Hope this answer will help someone else...

Based on comments , it looks like there might be some sort of bug in your version of Git. A simple git reset (with no arguments at all) should have undone the problem, but in fact you had to remove the index file first, then reset:

rm .git/index
git reset

This git reset will re-build the index file from scratch, now that it's missing. This should be unnecessary. (Note also that the location of the index file depends on whether this is an added work-tree from git worktree add ; the above assumes it's not.)

(One potential possible cause for this is that Windows has modes in which it refuses to let a program write to a file. 1 But that should show up as an error when running git reset . It might also prevent removing the file, in which case rm.git/index would fail too. So it's not at all clear what is going on here.)

Original answer below.


1 Windows has something called "mandatory file locks". Programs cannot avoid these locks. Linux in general has only advisory file locking, although there are some Linux file systems that have extra features. See, eg, How do I make Windows file-locking more like UNIX file-locking?


As matt said in a comment , this means that you've had Git delete the index copy of these files. Therefore, comparing the HEAD commit to the proposed next commit, the difference will be—if you actually commit right now—that those files won't be in the next commit, ie, between those two commits, you've deleted the files.

To put one file back, follow the instructions that git status printed:

 (use "git restore --staged <file>..." to unstage)

ie, run:

git restore --staged nta/executor/.gitignore

to copy the HEAD copy of nta/executor/.gitignore back into Git's index. Now the HEAD copy and the index's proposed-next-commit copy match, and git status will no longer mention the file. Repeat for each file as needed.

If you prefer, you can en-masse overwrite the entire index (the entire proposed next commit) from the current commit with:

git reset

(or git reset --mixed , but --mixed is the default).

If you've carefully copied some particular file into the index, this will overwrite that carefully-copied file in the index, and you may have to re-copy it carefully again, to get the effect you so carefully set up. But usually, we tend to copy whatever we have in our work-trees, into the index, so wiping out the index copy this way is not a big deal.

I tried using the suggested method to unstage these changes... This worked on some of the files, but many others remain listed as deleted.

We could use more detail on this, such as an actual cut-and-paste of the before-and-after git status (or parts of it) and the chosen git restore command. It definitely should go back to the state it had in the HEAD commit, after which git status should be quiet about it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM