12

I've lost files added to git during "merge conflict" phase.

Step by step:

git pull
git status

Git informs me about "merge conflict", that's okay. Then I create a new file and add it to git.

vi test.txt
git add test.txt

After that, abort merge:

git merge --abort

I have not found the file "test.txt" neither in directory, nor via "git fsck", nor "git reflog". Is it possible to restore the file?

5 Answers 5

29

What have you tried with git fsck ?

see this SO question : Recover files that were added to the index but then removed by a git reset


The general answer is : the sequence of instructions you typed has removed the file from tracking (and from the disk), there is no guarantee that the content of your file can be retrieved.

However, git has a lot of safety mechanism, and one of them is : if some data is entered somewhere in the repo, it will not be deleted before two weeks.

(git has a garbage collection mechanism, see git help gc)


If you did indeed run git add test.txt at some point, and this action was recent enough, there should still be some trace of the content of the file stored within git :

git fsck --full --unreachable --no-reflog

in git parlance, a file is a blob :

git fsck --full --unreachable --no-reflog | grep blob

This should give you a list of internal git hashes :

unreachable blob 08bf360988858a012dab3af4e0b0ea5f370a2ae8
unreachable blob 21bf7ea93f9f9cc2b3ecbed0e5ed4fa45c75eb89
unreachable blob 08c12ef37075732cf4645269ab5687ba6ba68943
...

note that git add file.txt stores the file's content, not the file's name ...

If you remember a specific string in your file, you can try to narrow your research by using git grep <string> <hash> :

$ git fsck --full --unreachable --no-reflog | grep blob | awk '{ print $3 }' > list.txt
$ cat list.txt | while read blob; do
  if git grep -q "string" $blob; then
    echo $blob
  fi
done

You can then view the whole content of a blob using :

git show $blob

and hopefully find back the file you were looking for.

2
  • 2
    Saved me from losing important changes after aborting a merge! Commented Oct 14, 2020 at 20:04
  • 2
    This is gold. Saved me hours of work. Thank you!. Commented May 28, 2022 at 6:52
4

Sorry for my poor English.

Thanks reply#1. I restored my files!!!

I did like this:

git fsck --full --unreachable --no-reflog | grep blob | awk '{ print $3 }' > ~/Downloads/git.txt

Then I saved files and named folders with different keyword which I remember:

    # execute it in your git project
    cat ~/Downloads/git.txt | while read blob; do
      if git grep -q "keyword in your lost content" $blob; then
        echo $blob; git show $blob > ~/Downloads/git-above-keyword/$blob.ts
      fi
    done

If you lost much content, you should execute above command times with different keyword, then you will get many keyword folders.

I opened another vscode and opened each keyword folder, copied every $bold.ts code to my project file. Do it careful because $bold.ts maybe have repeat codes, you should distinguish the last code.

1
  • Hi! I'm here to say that your thread and your answer saved my life. Thank you! Commented May 19, 2020 at 23:49
1

Not that I knew of before editing this answer (the other solution rightly points to git fsck).

In case you come across the same situation, you should have made a git commit instead of a git merge --abort.

As @Muneer Bits put it, I advise you to read a bit on the git basics. The official site contains a lot of documentation, and examples. You can even try it online with an interactive tutorial. The point is, you can't lose your work if it has been commited or stashed. I strongly encourage you to read the advices git is outputting all the time (unless you have an old version, in which case you should upgrade too). These tips should have told you to mark the commit resolved by adding the file first, then finalize the merge by performing a git commit.

Merge commits are just special commits with two parents. That means they need to be committed at some point, be it automatically (if there is no conflict) or manually. When you aborted the merge, you reverted (reset) all your changes to the point you were before the merge. And thus you lost every change you made.

Possible solution (depending on your workflow):

git pull
#merge conflict, solve it manually
git add modified_files_for_merging
git commit
touch test.txt
git add test.txt
git commit

Note that the merge wasn't aborted.

Be also aware that merging is not always the best solution when pulling. You can also pull with rebase. But I strongly encourage you to become a bit more familiar with git before attempting risky things with your work. And, as always, the solution you choose in the end will depend on your workflow.

0

Another answers here are for linux. I wanted to restore all deleted files on windows, and there is windows batch magic, which you need to use in order to do it.

Commands looks like this:

git fsck --full --unreachable --no-reflog >log.txt

for /F "tokens=1,2,3 delims= " %a in (log.txt) do if %b == blob git show %c >%c.txt

If you use it in batch, remember to replace % with %%.

It will restore bunch of .txt files, which you will need to map to right files after restoring.

0

In addition to the very helpful answer by LeGEC I did the following to write all unsaved blob contents to files inside a temporary folder on my desktop:

$ mkdir ~/Desktop/gitrestore
$ git fsck --full --unreachable --no-reflog | grep blob | awk '{ print $3 }' > ~/Desktop/list.txt
$ cat ~/Desktop/list.txt | while read blob; do
  git show $blob > ~/Desktop/gitrestore/${blob}.txt
done

This will create a file for each blob inside the given folder you can then look through to hopefully find your contents:

$ ls -l ~/Desktop/gitrestore

01948bd18eb3de97e480a4cb50897676ecbe3f08.txt
1121eda575ef4941a8e7beffc36a5e6756a9acbe.txt
24f99b4de792d410d8f222bfa51dfc6c4b7fce2f.txt
...

Not the answer you're looking for? Browse other questions tagged or ask your own question.