1

I have done the following:

  1. Cloning a repo
  2. git push origin --delete Branch_Name

and branch is deleted.

Is there any way I can restore this? I did not checkout this branch before deletion so there is no local copy.


git reflog is useless I guess cause I did not checkout the branch and I also don't know the commit_id of last commit on this branch

torek
  • 448,244
  • 59
  • 642
  • 775
Atef Hares
  • 4,715
  • 3
  • 29
  • 61

3 Answers3

2

Generally, the only way to recover from this is to find a repository—often one used by a colleague / friend / co-worker—who has the right commit(s), or to use the server's backups (your server does have backups made and tested regularly, right? Right?!? ). The reason for this is:

  • Server-side Git repositories have reflogs disabled by default.
  • Even if not, deleting the server's branch name with git push --delete deletes any relevant reflog the server had.
  • It deletes your own remote-tracking branch as well: your origin/branch is gone, along with any reflog you had for that.

The branch-name deletion may not have triggered a git gc in the server (this is not predictable) and definitely did not trigger one in your own repository (this, fortunately, is), so if you know the right hash ID, you can run:

git push origin <hash>:refs/heads/branch

but you usually don't know the right hash ID: that information was in the branch name on the server (gone now), your remote-tracking name (gone now), and any relevant reflogs in your and/or the server's repository (all of which are gone now).

That information does exist in any colleague's clone, provided that they (a) have run git fetch origin relatively recently and (b) have not run git fetch origin in such a way that their Git also deleted the information. This is the only reason I know of that one might not want to set fetch.prune to true: it causes your own Git repository to retain stale remote-tracking names, in case one of your colleagues executes this particular stunt.

Since responsible server sites make regular backups, though, you can always recover the information from a backup.

torek
  • 448,244
  • 59
  • 642
  • 775
1

If you did Step 2 not long after Step 1, you can try git push origin origin/[Branch_Name]:refs/heads/[Branch_Name] to recreate the branch from the most possible commit.

ElpieKay
  • 27,194
  • 6
  • 32
  • 53
  • yes, I did the exact sequence.. clone then delete. just tried this command but it says, `error: src refspec branch_name does not match any.` – Atef Hares Jul 26 '21 at 12:17
  • @ATEF try `refs/remotes/origin/branch_name:/refs/heads/branch_name` instead. – j6t Jul 26 '21 at 12:57
  • @ATEF Suppose the branch is `foo` and try `git push origin origin/foo:refs/heads/foo` or `git push origin refs/remotes/origin/foo:refs/heads/foo`. – ElpieKay Jul 26 '21 at 14:05
  • not working guys :(. anyway, thank you I ended up asking if anyone has a local copy and we found one. thanks a lot – Atef Hares Jul 26 '21 at 15:28
1

Is there any other developer who has a local copy of the branch? If any, ask her/him to push that branch.

Details:

The local repository keeps the latest commit object for that branch, but it's difficult to identify the commit because the information about the commit-branch relationship has been lost by git push origin --delete [Branch_Name]. However, if you can find the commit from the list of commit objects, you can checkout and regenerate the branch.

In many cases it's faster to ask other developers to push the branch from their repository, if any.

Yoichi Nakayama
  • 704
  • 6
  • 9
  • 1
    ended up doing that yeah but I hoped to find a better solution – Atef Hares Jul 26 '21 at 15:29
  • The relation between [Branch_Name] and the latest commit in that branch will be lost by `git push origin --delete [Branch_Name]` from your local repository and the remote repository. On the other hand, the commit object should remain in your local repository, and you can checkout the one and re-create the branch if you can identify it by some commit information. – Yoichi Nakayama Jul 26 '21 at 21:43
  • To list up objects in your repository, you can use `git cat-file --batch-check --batch-all-objects`. Reference: https://stackoverflow.com/questions/7348698/how-to-list-all-git-objects-in-the-database – Yoichi Nakayama Jul 26 '21 at 21:45
  • Thank you. appreciate your support. – Atef Hares Jul 27 '21 at 09:40
  • I learned that `git fsck` can be used for this purpose. You can use it to extract commits that are no longer referenced. – Yoichi Nakayama Aug 09 '21 at 06:19