1

After creating branch Y from working branch X, I deleted some files to reduce visual noise by not seeing those files around on the FS, while working on branch Y. These files are being changed in branch X.

here is the scenario:

A - B [origin/master]
     \
      C - D - G - H [origin/X]
           \
            E - F [Y]

Changes from branch Y are also pushed to origin/Y

Already raised a PR request on branch Y for review.


How to rewrite the commit history in origin/Y to get a file back?

overexchange
  • 15,768
  • 30
  • 152
  • 347
  • 1
    Possible duplicate of [How to undelete a file previously deleted in git's history?](https://stackoverflow.com/questions/3150394/how-to-undelete-a-file-previously-deleted-in-gits-history) – eftshift0 Jul 21 '19 at 03:34
  • @eftshift0 Branch `Y` is already on PR request on latest commit. Is this query not different from attached? – overexchange Jul 21 '19 at 03:52
  • that part is not explained there... but the recipe to get the files back is still the same.... now, when you get your corrected branch, then you do: `git push -f origin Y`. After you have force-pushed the branch, the PR should update on github or bitbucket. – eftshift0 Jul 21 '19 at 03:55
  • @eftshift0 I have the `parent of the commit that deleted the file` say `id1`. What is `id of the previous commit` in step 2 below? I have more than one file deleted after `id1` – overexchange Jul 21 '19 at 04:22
  • The parent ID is the id you use to run the `git checkout -- ` command. – eftshift0 Jul 21 '19 at 04:24

2 Answers2

1

As @eftshift0 mentioned in the comments, you might find this answer useful. It shows that you can restore the lost file and rewrite the git history with the following:

git rebase -i <id of the commit with the files before they were deleted>
git checkout <id of the commit previous to the one you're currently on> <filename>
git commit --amend
git rebase --continue
git tag -d originalHead

Nevertheless, there is value in keeping the git history unaltered, so another option to recover the lost file without changing git history can be found at this answer, which says this:

git checkout <id of the commit with the files before they were deleted> <filename>

In addition, if you want to recover multiple files this answer shows some ways to do that, which could for example be running the git checkout command multiple times.

AbsoluteSpace
  • 710
  • 2
  • 11
  • 21
  • `previous commit` would be the commit that was previous to the commit where the files disappeared. In addition, if you want to recover multiple files this [answer](https://stackoverflow.com/a/28555154/10576762) shows some ways to do that. I will update my answer. – AbsoluteSpace Jul 21 '19 at 04:23
  • From the directory am running these commands, there are two files deleted in subdirectory `dir1`. – overexchange Jul 21 '19 at 04:26
  • Does this also maintain the new files created in latest commit? – overexchange Jul 21 '19 at 04:28
  • It should. Take a look at `git status`. – eftshift0 Jul 21 '19 at 04:29
  • `git checkout` will maintain the new files in the latest commit unless you checkout a file that you've modified in your current branch. – AbsoluteSpace Jul 21 '19 at 04:29
  • In your answer, Is `id of the commit with the files before they were deleted` in step 1 same as `id of the commit previous to the one without the files` in step 2? – overexchange Jul 21 '19 at 04:30
  • Not necessarily, my bad on the confusing wording. `id of the commit with the files before they were deleted` is the id of the parent commit that deleted the files, but `id of the commit previous to the one without the files` is just the commit before the one you're currently working on. I've updated the post to make step 2 a little more clear. – AbsoluteSpace Jul 21 '19 at 04:32
  • What is the idea about checkout to `id of commit previous to the one am currently on` in step 2? why not the commit that am currently on ? – overexchange Jul 21 '19 at 04:35
  • probably `HEAD` will work just as well on checkout... but I didn't want to add some pepper to a recipe that has been already tried and tested (from what you can see on all the upvotes). – eftshift0 Jul 21 '19 at 04:38
  • @eftshift0 Am following second approach, but I see commit history changing – overexchange Jul 21 '19 at 04:51
1

I will give you a simple recipe as a fallback, just in case. Suppose your branch is called A, and you deleted files on A~3 (that would be, 3 revisions behind A):

git checkout A~3 # we set ourselves on the revision where the files where deleted
git checkout HEAD~1 -- file1 file2 file3 # get back the files from the previous revision
git commit --amend --no-edit # commit new revision with the deleted files back in place
git cherry-pick A~3..A # replay revisions after this new revision
# if you like the results:
git branch -f A # set the branch on this new position
git checkout A
git push -f origin A

That should work

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • I see [this approach](https://stackoverflow.com/a/3150424/3317808) more simple... Because in my case one file is deleted an one file is renamed and modified. But this is changing my commit history. – overexchange Jul 21 '19 at 05:02
  • Commit history is gonna change... at least the content of the revisions... even if you keep the same line of revisions with comment/author, you are rewriting history. – eftshift0 Jul 21 '19 at 05:04
  • So, I want to apply [this approach](https://stackoverflow.com/a/3150424/3317808) on the commit am currently on. But isn't this going to require a new commit after applying this aproach and then push those changes? Because I have a PR request that is on current commit? – overexchange Jul 21 '19 at 05:08
  • So, what you want is to create a new additional revision where you get the files back? Sure, it's possible.... not the most elegant way to handle it, but possible.... and sure, you will need a new commit after the checkout of the deleted files. – eftshift0 Jul 21 '19 at 05:14
  • After commit history changes, does `git push -u origin Y` create any issue? because commit history is changed in local branch `Y`? – overexchange Jul 21 '19 at 05:15
  • If you didn't rewrite history and only added a revision to get the files back? There should be no problem. – eftshift0 Jul 21 '19 at 05:19
  • I will just add a new commit(revision) to get the files back. But before that, how do I deal with PR request that is on current commit? Does that PR request stop me creating new commit(revision) and push? – overexchange Jul 21 '19 at 05:21
  • github and bitbucket (if you are using them) will reflect the update of the PR when you push into the branch that was used to create the PR. – eftshift0 Jul 21 '19 at 05:23
  • Being on current commit, after following [this approach](https://stackoverflow.com/questions/3150394/how-to-undelete-a-file-previously-deleted-in-gits-history/3150424#3150424), commit history is changing. `git push ` may not work ... How to make `origin/Y` in sync with local `Y`? – overexchange Jul 21 '19 at 05:33
  • what do you mean? If you didn't rewrite the history of Y and you only added a revision, push will not fail. It will fail if you rewrote history. – eftshift0 Jul 21 '19 at 05:41
  • My bad... commit history did not change. `git push` went fine – overexchange Jul 21 '19 at 05:47
  • Now... can I rebase with parent branch? Because I have files back after creating a new revision with [this approach](https://stackoverflow.com/a/3150424/3317808)? – overexchange Jul 21 '19 at 20:30