简体   繁体   中英

Git restore file deleted in local branch

I always create a new branch when building a feature. I have done so this time and committed my work to the new branch. However, I noticed that somehow I deleted a file and that was committed as well. So now my feature branch is missing a file that is still in master.

How can I restore the file?

I got the hash of the commit where the files were deleted, and tried:

git checkout 1f1d3f76bac0bf6e13ceee5bb3df69f8389fc73f -- /path/to/MyMissingFile

but git said pathspec did not match any files known to git . I confirmed that both the filename and the commit was correct using git log --diff-filter=D --summary to print the commit and filenames where the deletion occurred.

The proper command, with Git 2.23+, would be to use git restore , which replaces the confusing git checkout command .

 git restore -s master -- /path/to/MyMissingFile

That would restore on the working tree only the file as present in the "source" ( -s ) branch master .

To restore both working tree and index:

git restore -s master -SW -- /path/to/MyMissingFile

( -SW : short for --staged --worktree )

If you only restore the working tree, then a git diff , as illustrated here , will diff between the index (which still reflect the file being deleted) and the working tree.
By restoring the working tree and the index, you add directly the restored file, to then be committed.

The problem with

git checkout 1f1d3f76bac0bf6e13ceee5bb3df69f8389fc73f -- /path/to/MyMissingFile

is, presumably based on what you said, it's the hash of the commit that deleted the file - so the file isn't there. But the file is in that commit's parent. You can use an abbreviated hash, by the way, and then tacking ^ or ~ onto the end will get the commit's parent. So

git checkout 1f1d3f76ba^ -- /path/to/MyMissingFile

should work. (There would be a potential bit of room for error here if the commit in question is a merge, in that you'd need to make sure you were reaching into the correct parent; but it sounds like that doesn't apply here.)

Switching to the newer restore command is also an option (and probably not a bad idea), as someone else mentioned; but that isn't really the issue at hand.

As you seem to have discovered, you also could reach over into master (or any other branch where the file still exists) and grab the file from there. I don't recommend this, though (especially if you've already gone to the trouble of finding the commit where the file was deleted), because (a) any changes to the file on your branch before its deletion are lost, and (b) any changes to the file on master may be prematurely picked up on your branch. Maybe you know those problems don't apply this time, but it's a bad habit. Next time maybe there's a change you forgot about.

我可以通过简单地从 master 分支检出文件,然后将它们提交到我的特性分支来解决这个问题:

git checkout master -- /path/to/MyMissingFile

The easy way is to use git revert.

  1. Find the commit hash where you made the mistake
  2. Run git revert [commit-hash]

And you'll have your file back

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