2

I have a repository that belongs only to me but allows me to manage a project across multiple machines with versioning. Somehow, at some point I committed in such a way that some important includes were deleted, but I did not notice until I needed them today. So I am trying to figure out how to take the versions of those files from the last commit where I know they are correct and pull them into the current master. There are a couple of questions on here that seem like they should answer this, but the answers seem to be describing something else.

I can check out from the correct commit and I read about rebasing, but I am hesitant to do anything without asking those with more experience.

Kirk S.
  • 151
  • 6
  • 1
    `git show ${commithash}:${file} > oldfile` to save the the file from the old commit in a file named "oldfile". I wouldn't rebase or you have to force push. Unless you haven't pushed any changed until the evil commit or you are the only developer. – Cubimon Aug 12 '19 at 11:53
  • Thanks! What if it is a few directories? Does this work to rebuilt a whole directory that is not there anymore? – Kirk S. Aug 12 '19 at 11:57
  • @Cubimon reset or checkout can also be used to accomplish this. Maybe cat-file if you get the tree and blob – D. Ben Knoble Aug 12 '19 at 12:01
  • @Cubimon This should be an answer. – harmonica141 Aug 12 '19 at 12:16
  • @KirkS. Git only deals in files, not in folders. If the last file in a directory is deleted, the directory will cease to exist in git. Vice versa as soon as you create a file in a new (non-tracked) subdirectory, git will know this directory as part of its scope. – harmonica141 Aug 12 '19 at 12:18
  • 1
    Possible duplicate of [How can I reset or revert a file to a specific revision?](https://stackoverflow.com/questions/215718/how-can-i-reset-or-revert-a-file-to-a-specific-revision) – phd Aug 12 '19 at 12:50
  • https://stackoverflow.com/search?q=%5Bgit%5D+file+from+old+commit – phd Aug 12 '19 at 12:50

2 Answers2

1

You can use git checkout to put back the deleted files into your working directory.

Assuming you already know which commit deleted the files, you can say:

git checkout <commit-ish>^ -- <deleted-path>

where:

  • commit-ish is a reference to the commit in question
  • ^ references that commit's parent
  • deleted-path is the path of the file or directory that you want to restore

For example, assuming a12b34 is the SHA-1 of the commit that deleted the foo directory, you would say:

git checkout a12b34^ -- path/to/foo 

In short, this commands tells Git to get the files in the specified path as they were before the commit that deleted them, and put them back in the working directory.

Enrico Campidoglio
  • 56,676
  • 12
  • 126
  • 154
  • Thanks. When you say ^ references the parent, does that mean I need to replace it with sometime? I think I did not understand that part. Also, once I have checked out these directories, does that mean I can then commit them to the current master? – Kirk S. Aug 12 '19 at 12:19
  • @KirkS. `^` is a reference to a commit's parent. You want to get the files _before_ they were deleted, so assuming `123abc` is the SHA-1 of the commit that deleted the files, you want to get them from the commit that came before it (aka. the parent) so you say `123abc^`. Yes, after you've checked out the files, you can commit them again to the current branch. – Enrico Campidoglio Aug 12 '19 at 12:23
  • Thanks. This was exactly what was needed! – Kirk S. Aug 13 '19 at 19:59
1
git log --summary --diff-filter=D

Let's say you find out the exact commit hash as abcde12345 where this important file was deleted.

git checkout $commit~1 path/to/file.ext

Where $commit is the value of the commit you've found abcde12345

Shravan40
  • 8,922
  • 6
  • 28
  • 48