I have some old changes I made, committed and pushed to remote (bitbucket) repo. These changes was not merged to any other branch. Branch itself was removed locally and from remote repo.
But, as I can see in bitbucket web, commits included to removed branch still there (in repo). I googled a lot, but did not find a way, how to retrieve commits of removed branch from remote. The only I can do is to see them in bitbucket web and get sha of commit there.
I saw some examples like
git checkout <sha>
or
git checkout -b <branch-name> <sha>
But always get the following error
fatal: reference is not a tree: <sha>
So, is it possible and how I can retrieve (fetch) these commits from remote, crate branch from them, merge to release branch?
To be more specific, I have created a repo, new branch, make a commit in this ne branch and remove branch:
Repo https://github.com/yurybond/stackowerflow-rocks
Link to (standalone) commit from removed branch https://github.com/yurybond/stackowerflow-rocks/commit/a1c1540abd453773b3ce6445d01e51ad336bbe84
The question is still the same: How to retreive commit (a1c1540abd453773b3ce6445d01e51ad336bbe84) that belongs to removed branch?
Git fetch commands and optionsFetch all of the branches from the repository. This also downloads all of the required commits and files from the other repository. Same as the above command, but only fetch the specified branch. The --dry-run option will perform a demo run of the command.
You'll still have your locally cached versions of those branches (which is actually good) but git branch -a will still list them as remote branches. Your local copies of deleted branches are not removed by this.
git fetch --prune is the best utility for cleaning outdated branches. It will connect to a shared remote repository remote and fetch all remote branch refs. It will then delete remote refs that are no longer in use on the remote repository.
You can manually download missing
commits in mbox
format and apply them manually with git am
. For
example:
github
(repository you linked to):
$ wget https://github.com/yurybond/stackowerflow-rocks/commit/a1c1540abd453773b3ce6445d01e51ad336bbe84.patch && git am a1c1540abd453773b3ce6445d01e51ad336bbe84.patch
gitlab
:
$ wget https://git.weboob.org/weboob/devel/commit/bba7e1b8ffb0743b57f202cf9cdb43fda209fa43.patch && git am bba7e1b8ffb0743b57f202cf9cdb43fda209fa43.patch
bitbucket
:
$ wget https://bitbucket.org/Kasreyn/linux-3-9-rc3-moxart/commits/434e8f69db2c3effdc8741139adb722a68dfcccd/raw -O 434e8f69db2c3effdc8741139adb722a68dfcccd.patch && git am 434e8f69db2c3effdc8741139adb722a68dfcccd.patch
Notice that git am
will not only apply textual patch but will also
recreate a whole commit on the current branch.
If you removed a branch from the remote repository there is no way to
get it back from the remote reposityr. However, normally you still
might be able to restore a removed branch locally thanks to git reflog
. See the following
example.
First, create a new non-bare repository:
$ git init
Initialized empty Git repository in /tmp/reflog-test/.git/
Add file
and create a new commit on master
branch:
$ touch file
$ git add .
$ git commit -m 'Initial commit'
[master (root-commit) 81fc76d] Initial commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file
Switch to a new branch creatively named new-branch
:
$ git checkout -b new-branch
Switched to a new branch 'new-branch'
Modify file
and commit changes:
$ echo new-branch >> file
$ git commit -am 'commit on new-branch'
[new-branch 9c457c6] commit on new-branch
1 file changed, 1 insertion(+)
Switch back to master
:
$ git checkout -
Switched to branch 'master'
$ git branch
* master
new-branch
Remove new-branch
$ git branch -D new-branch
Deleted branch new-branch (was 9c457c6).
It's gone:
$ git branch
* master
$ git log new-branch
fatal: ambiguous argument 'new-branch': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
However, you should still be able to reference the commit:
$ git show --stat 9c457c6
commit 9c457c69de8a54376a2614ca8cfc0f515c64676c
Author: Arkadiusz Drabczyk <[email protected]>
Date: Tue Apr 3 10:43:49 2018 +0200
commit on new-branch
file | 1 +
1 file changed, 1 insertion(+)
Even though it can't be found on any branch. The following command returns nothing:
$ git branch --contains 9c457c6
Reflog
shows all actions one did in a repository:
$ git reflog
dbc721a HEAD@{0}: checkout: moving from new-branch to master
9c457c6 HEAD@{1}: commit: commit on new-branch
dbc721a HEAD@{2}: checkout: moving from master to new-branch
dbc721a HEAD@{3}: commit (initial): Initial commit
As you see it also has 9c457c6
commit we did on the new-branch
.
Only when reflog
is expired and garbage collector is run 9c457c6
becomes unreachable:
$ git reflog expire --expire=all --all
$ git gc --prune=now
Counting objects: 3, done.
Writing objects: 100% (3/3), done.
Total 3 (delta 0), reused 0 (delta 0)
$ git show 9c457c6
fatal: ambiguous argument '9c457c6': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
By default reflog
entries expire after 90 days and git gc
is run
automatically after some commands so if you have removed the branch
relatively recently you should be able to restore it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With