简体   繁体   中英

Git pull origin master deleted hidden files (from .gitignore)

When pulling from the Github repo, would it just merge files to the local Git, or its going to delete everything and just take the files from the remote repo?

Package.json and config.js were deleted after doing git pull origin master while they were ignored in the .gitignore.

Where can I find those files? Should I re-create them?

git pull is equivalent to git fetch + git merge . That means it does not simply override your local files. For reference, see doc here:

https://git-scm.com/docs/git-pull

Everything that was once in life committed can be retrieved. The command git reflog will print you the history of your changes locally. So you can do git checkout some_commit_hash to go back in history. See reference:

https://git-scm.com/docs/git-reflog

DISCLAIMER: Don't do git push -f to override the remote if you don't know 100% what you're doing.

Only under certain circumstances will git pull origin master remove a file from the work tree, and it should be the case that the file is recoverable under those circumstances. I think the crux of the question is here:

Package.json and config.js were deleted after doing git pull origin master while they were ignored in the .gitignore.

(emphasis addeD). But .gitignore has a very narrow function - it prevents untracked files from accidentally becoming tracked. It does not enable changes to tracked files to be ignored. If package.json and config.js were tracked files, and an upcoming commit on origin/master deletes them, adding them to .gitignore does not protect them from deletion when integrating those upcoming commits.

This can be a pain in the neck if you have a file in the repo, and then decide you want to add it to .gitignore and remove it from the repo, because even if you add the files to .gitignore , this does nothing until the commit that removes the files; and the commit that removes the files will... well... remove the files, before the .gitignore entry is effective.

But , for git to go along with deleting them from the work tree should mean that (1) you had not locally committed any changes to them (as this would cause a conflict), and (2) you did not have any locally-uncommitted changes to them (because git would warn you that you need to undo or stash local changes before overwriting them).

So you should be able to retrieve the files from an older commit.

git checkout master@{1} -- package.json config.js

would likely work (taking advantage of the reflog) right after the pull . Or if the reflog isn't in the right shape, substitute any expression that resolves to a commit that still has the files. (Maybe master^ ... it depends on what all is in the repo's history.)

And if that's what's going on, then it's a one-time annoyance. The files disappear when updating from a commit that had the file, to a commit that doesn't have the file. After that, the .gitignore entry really will keep the file untracked and further pulls will work around it (unless the file gets re-added to a later commit, but that's another story).

Here's some additional background if it helps:

git pull origin master is a shortcut for updating the local repo from origin (a remote), and then integrating the changes from origin s version of master (a branch) into the currently checked-out version.

The first step of any pull is a fetch . A fetch does two things:

It maps refs from the remote into the local repo according to a configuration value called a "refspec". That may sound like gibberish if you're not familiar with all the git lingo, but by default it just means that for each branch in the remote, a "remote tracking ref" is created in the local repo. For example, if origin has a branch called master , then you get a local ref called origin/master .

It also downloads enough objects from the remote to fill in the history of the updated/added refs, and adds those to the local database. To clarify, git has three types of storage. The files you work on are in the working tree. The are that contains history (commits), where interaction with remotes occurs, is the database. (And the index is a bridge between the two.) So a fetch only affects the database, and it only adds objects to the database. So far your working files are entirely uninvolved in the process.

The next thing fetch does is to integrate some changes into the commit you have checked out. You specified the origin s master branch as the source of changes to integrate, and by default the integration is done by simply merging - so that the result of integrating the changes appears in a new merge commit at the tip of your branch, and in the index, and in the work tree.

So this is where it's possible for a file to be removed, if the changes being merged include deletion of the file (and if there are no conflicting local changes).

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