.git:获取并应用已删除分支的提交
.git: fetch and apply commits of removed branch
我做了一些旧的更改,提交并推送到远程 (bitbucket) 存储库。这些更改未合并到任何其他分支。分支本身已在本地和远程仓库中删除。
但是,正如我在 bitbucket web 中看到的那样,包含到已删除分支的提交仍然存在(在 repo 中)。我在谷歌上搜索了很多,但没有找到方法,如何检索
从远程提交已删除的分支。我唯一能做的就是在 bitbucket web 中查看它们并在那里获取 sha of commit。
我看到了一些例子,比如
git checkout <sha>
或
git checkout -b <branch-name> <sha>
但是总是报如下错误
fatal: reference is not a tree: <sha>
那么,是否有可能以及如何从远程检索(获取)这些提交,从它们创建分支,合并到发布分支?
更新:
更具体地说,我创建了一个 repo,新分支,在这个 ne 分支中提交并删除分支:
回购 https://github.com/yurybond/stackowerflow-rocks
Link 从删除的分支 https://github.com/yurybond/stackowerflow-rocks/commit/a1c1540abd453773b3ce6445d01e51ad336bbe84
到(独立)提交
问题还是一样:如何取回属于已删除分支的提交(a1c1540abd453773b3ce6445d01e51ad336bbe84)?
我在 Stack Overflow 上没有看到任何关于检查已删除的提交的信息。但是,应该可以通过以下方式硬重置已删除的提交:
git checkout -b some_new_branch
git reset --hard <SHA-1 of deleted commit>
这会将分支 some_new_branch
重置为已删除的提交,也许这足以让您继续。
我假设您在 Bitbucket 中看到的已删除提交来自 reflog。如果是这样,那么您还应该能够通过以下方式查看已删除的提交:
git reflog
如果您没有看到您删除的提交,那么它也可能解释了您遇到的错误。在这种情况下,如果删除的提交真的只存在于 Bitbucket 上,那么您将需要一些其他方式来访问它们。
如果您仍然可以在 Bitbucket 中看到该提交(而不是在 Recent activity 中),那么该提交仍然可以从某个分支或某个标签访问。您可以 运行 git fetch
获取这些引用的最新版本,如果本地存储库中不存在该特定提交,也会下载该提交。但是,错误 fatal: reference is not a tree: <sha>
意味着 sha
不是提交。它很可能是一个斑点。如果您找到正确的提交,git checkout <commit>
或 git checkout -b <branch-name> <commit>
应该可以工作。
分支里面有标签吗?关于为什么分支会出现在 bitbucket 上但没有使用 fetch 命令获取下来的原因尚不清楚。
无论如何,尝试 git fetch +refs/*:refs/*
然后查看 .git/FETCH_HEAD
文件,希望您会在那里找到您想要的提交之一。如果没有,将需要更多信息。我还会复制您当前的存储库,以避免像那样强制获取远程引用空间可能带来的任何麻烦。
如果此提交确实存在于 Bitbucket 存储库中,那么您可以使用 Bitbucket 网络界面将其合并到另一个分支中。
- 转到分支 --> 在 Bitbucket 中创建一个新分支。随意命名
- 创建分支后,单击比较(右上角的三点菜单)
- 在比较屏幕中,select 更改源并粘贴您的提交参考。如果得出结果,那么您很幸运。 Select它。
- Select 更改目的地,并将其更改为您的新分支。
- 您应该能够浏览差异,看到您想要引入的所有更改。
- Select满意就合并。
现在是关键。如果在第 3 步粘贴该提交引用失败,那么你就不走运了。这意味着提交在远程或本地都不存在。
如果您讨厌导航并希望直接 link 进行比较(不过会与 master 进行比较):https://bitbucket.org/<user>/<repository>/branches/compare/<commit-reference>..master
因为您已经在本地删除了分支,所以您不能像其他人建议的那样使用 sha-1 恢复它。
reflog 在远程端也不起作用(而且它也从远程端删除了。
这给您留下了两个选择之一。要么写信给 Bitbucket 支持,以便他们恢复您需要的内容。
或在这里尝试迈克尔的建议:Recovering a deleted branch from a remote on Bitbucket (git)
建议的解决方案听起来可能会解决您的问题。请告诉我它是如何工作的
您可以手动下载缺失
以 mbox
格式提交并使用 git am
手动应用它们。为了
示例:
github
(您链接到的存储库):
$ 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
注意 git am
不仅会应用文本补丁,还会
在当前分支上重新创建整个提交。
如果您从远程存储库中删除了一个分支,则无法
从远程存储库取回它。然而,通常你还是
由于 git reflog
,也许能够在本地恢复已删除的分支。见下文
例如。
首先,创建一个新的 non-bare 存储库:
$ git init
Initialized empty Git repository in /tmp/reflog-test/.git/
添加 file
并在 master
分支上创建新提交:
$ 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
切换到一个创造性地命名为 new-branch
:
的新分支
$ git checkout -b new-branch
Switched to a new branch 'new-branch'
修改 file
并提交更改:
$ echo new-branch >> file
$ git commit -am 'commit on new-branch'
[new-branch 9c457c6] commit on new-branch
1 file changed, 1 insertion(+)
切换回 master
:
$ git checkout -
Switched to branch 'master'
$ git branch
* master
new-branch
删除new-branch
$ git branch -D new-branch
Deleted branch new-branch (was 9c457c6).
没了:
$ 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>...]'
但是,您应该仍然可以引用提交:
$ git show --stat 9c457c6
commit 9c457c69de8a54376a2614ca8cfc0f515c64676c
Author: Arkadiusz Drabczyk <adrabczyk@bigcorp.com>
Date: Tue Apr 3 10:43:49 2018 +0200
commit on new-branch
file | 1 +
1 file changed, 1 insertion(+)
即使在任何分支上都找不到。以下命令
returns 没有:
$ git branch --contains 9c457c6
Reflog
显示在存储库中执行的所有操作:
$ 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
如您所见,它还有我们在 new-branch
上所做的 9c457c6
提交。
仅当 reflog
过期且垃圾收集器为 运行 9c457c6
变得无法访问:
$ 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>...]'
默认情况下 reflog
条目在 90 天后过期并且 git gc
是 运行
在一些命令之后自动,所以如果你已经删除了分支
最近你应该能够恢复它。
git fetch origin <sha>
将从服务器获取提交,但这可能取决于您使用的是 GitHub、BitBucket 还是其他托管服务提供商
我做了一些旧的更改,提交并推送到远程 (bitbucket) 存储库。这些更改未合并到任何其他分支。分支本身已在本地和远程仓库中删除。
但是,正如我在 bitbucket web 中看到的那样,包含到已删除分支的提交仍然存在(在 repo 中)。我在谷歌上搜索了很多,但没有找到方法,如何检索 从远程提交已删除的分支。我唯一能做的就是在 bitbucket web 中查看它们并在那里获取 sha of commit。
我看到了一些例子,比如
git checkout <sha>
或
git checkout -b <branch-name> <sha>
但是总是报如下错误
fatal: reference is not a tree: <sha>
那么,是否有可能以及如何从远程检索(获取)这些提交,从它们创建分支,合并到发布分支?
更新:
更具体地说,我创建了一个 repo,新分支,在这个 ne 分支中提交并删除分支:
回购 https://github.com/yurybond/stackowerflow-rocks
Link 从删除的分支 https://github.com/yurybond/stackowerflow-rocks/commit/a1c1540abd453773b3ce6445d01e51ad336bbe84
到(独立)提交问题还是一样:如何取回属于已删除分支的提交(a1c1540abd453773b3ce6445d01e51ad336bbe84)?
我在 Stack Overflow 上没有看到任何关于检查已删除的提交的信息。但是,应该可以通过以下方式硬重置已删除的提交:
git checkout -b some_new_branch
git reset --hard <SHA-1 of deleted commit>
这会将分支 some_new_branch
重置为已删除的提交,也许这足以让您继续。
我假设您在 Bitbucket 中看到的已删除提交来自 reflog。如果是这样,那么您还应该能够通过以下方式查看已删除的提交:
git reflog
如果您没有看到您删除的提交,那么它也可能解释了您遇到的错误。在这种情况下,如果删除的提交真的只存在于 Bitbucket 上,那么您将需要一些其他方式来访问它们。
如果您仍然可以在 Bitbucket 中看到该提交(而不是在 Recent activity 中),那么该提交仍然可以从某个分支或某个标签访问。您可以 运行 git fetch
获取这些引用的最新版本,如果本地存储库中不存在该特定提交,也会下载该提交。但是,错误 fatal: reference is not a tree: <sha>
意味着 sha
不是提交。它很可能是一个斑点。如果您找到正确的提交,git checkout <commit>
或 git checkout -b <branch-name> <commit>
应该可以工作。
分支里面有标签吗?关于为什么分支会出现在 bitbucket 上但没有使用 fetch 命令获取下来的原因尚不清楚。
无论如何,尝试 git fetch +refs/*:refs/*
然后查看 .git/FETCH_HEAD
文件,希望您会在那里找到您想要的提交之一。如果没有,将需要更多信息。我还会复制您当前的存储库,以避免像那样强制获取远程引用空间可能带来的任何麻烦。
如果此提交确实存在于 Bitbucket 存储库中,那么您可以使用 Bitbucket 网络界面将其合并到另一个分支中。
- 转到分支 --> 在 Bitbucket 中创建一个新分支。随意命名
- 创建分支后,单击比较(右上角的三点菜单)
- 在比较屏幕中,select 更改源并粘贴您的提交参考。如果得出结果,那么您很幸运。 Select它。
- Select 更改目的地,并将其更改为您的新分支。
- 您应该能够浏览差异,看到您想要引入的所有更改。
- Select满意就合并。
现在是关键。如果在第 3 步粘贴该提交引用失败,那么你就不走运了。这意味着提交在远程或本地都不存在。
如果您讨厌导航并希望直接 link 进行比较(不过会与 master 进行比较):https://bitbucket.org/<user>/<repository>/branches/compare/<commit-reference>..master
因为您已经在本地删除了分支,所以您不能像其他人建议的那样使用 sha-1 恢复它。
reflog 在远程端也不起作用(而且它也从远程端删除了。
这给您留下了两个选择之一。要么写信给 Bitbucket 支持,以便他们恢复您需要的内容。
或在这里尝试迈克尔的建议:Recovering a deleted branch from a remote on Bitbucket (git)
建议的解决方案听起来可能会解决您的问题。请告诉我它是如何工作的
您可以手动下载缺失
以 mbox
格式提交并使用 git am
手动应用它们。为了
示例:
github
(您链接到的存储库):$ 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
注意 git am
不仅会应用文本补丁,还会
在当前分支上重新创建整个提交。
如果您从远程存储库中删除了一个分支,则无法
从远程存储库取回它。然而,通常你还是
由于 git reflog
,也许能够在本地恢复已删除的分支。见下文
例如。
首先,创建一个新的 non-bare 存储库:
$ git init
Initialized empty Git repository in /tmp/reflog-test/.git/
添加 file
并在 master
分支上创建新提交:
$ 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
切换到一个创造性地命名为 new-branch
:
$ git checkout -b new-branch
Switched to a new branch 'new-branch'
修改 file
并提交更改:
$ echo new-branch >> file
$ git commit -am 'commit on new-branch'
[new-branch 9c457c6] commit on new-branch
1 file changed, 1 insertion(+)
切换回 master
:
$ git checkout -
Switched to branch 'master'
$ git branch
* master
new-branch
删除new-branch
$ git branch -D new-branch
Deleted branch new-branch (was 9c457c6).
没了:
$ 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>...]'
但是,您应该仍然可以引用提交:
$ git show --stat 9c457c6
commit 9c457c69de8a54376a2614ca8cfc0f515c64676c
Author: Arkadiusz Drabczyk <adrabczyk@bigcorp.com>
Date: Tue Apr 3 10:43:49 2018 +0200
commit on new-branch
file | 1 +
1 file changed, 1 insertion(+)
即使在任何分支上都找不到。以下命令 returns 没有:
$ git branch --contains 9c457c6
Reflog
显示在存储库中执行的所有操作:
$ 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
如您所见,它还有我们在 new-branch
上所做的 9c457c6
提交。
仅当 reflog
过期且垃圾收集器为 运行 9c457c6
变得无法访问:
$ 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>...]'
默认情况下 reflog
条目在 90 天后过期并且 git gc
是 运行
在一些命令之后自动,所以如果你已经删除了分支
最近你应该能够恢复它。
git fetch origin <sha>
将从服务器获取提交,但这可能取决于您使用的是 GitHub、BitBucket 还是其他托管服务提供商