远程分支存在,本地分支消失
Remote branch exists, local branch disappeared
好的,上下文是我在自己的分支上工作,为某个项目创建功能。
我的分支叫做 Exif(大写 E),今天我不小心做了
git push origin exif (lowercase e)
所以它为我创建了一个名为 exif
的新分支
意识到这一点后,我做到了
$ git push origin --delete exif
$ git branch -d exif
再次有效删除分支。
我必须补充一点,我在 Exif(大写 E)中检出时执行了这两行,但这应该无关紧要吧?
现在,当我执行
git status
我得到一个巨大的列表,说整个项目中的每个文件都是一个新文件
当我尝试时
git log
它说,你当前的分支还没有任何提交
当我
git branch -a
所有分支都有,除了Exif,它也不在远程分支列表中
但在我们的 gitlab 服务器上,它显示分支正常,就像什么也没发生一样。
有人知道这里发生了什么吗?
编辑:
在 eclipse 中,它在每个文件旁边显示一个星号,这意味着每个文件都已暂存。
在 Eclipse 中,它还会在根项目文件夹旁边显示该项目具有 [NO-HEAD]
删除分支时,git不区分大小写,这意味着如果您执行
,您的分支"Exif"将被删除
git branch -d exif
您一开始甚至没有创建分支 "Exif",因为通过推送到不同的分支,您不会自动在本地存储库中创建该分支。
要返回原来的分支,我会通过再次检查远程分支来创建一个新的本地分支,如下所示:
git checkout origin/exif
这里的另一个答案不太正确,虽然这个:
but on our gitlab server it shows the branch just fine like nothing happened.
很有前途,因此您可能有一种简单的方法来解决问题。
我将展示一个示例,其中我销毁了自己的 master
分支(当然是在克隆中)。由于这个特定的系统是区分大小写的,我只是手动删除了 master
分支(在 Git 的背后,就像它一样)。
Git 错误:分支名称区分大小写,除非它们不区分大小写
这是 Git 中的错误:它设法删除了您所在的分支。
出现问题是因为 Git 是 区分大小写的:就 Git 而言,分支 exif
完全与分支 Exif
分开。当您要求 Git 删除 exif
时,实际上检查了:
- 我在分支
exif
吗?
- 如果是这样,请拒绝尝试,因为它会搞砸一切。
- 否则,继续删除
exif
。
所以 Git 检查了一下,发现你当前的分支是 Exif
,而不是 exif
。嗯,对Git来说,那些明明是不同,删了一定安全!只是……他们不是,也不是。 ,但是在 Windows 和 MacOS 系统上,Git 要么需要一些实现上的改变——这样分支名称真的 可以 区分大小写,所有时间 — 或者 Git 需要 停止相信 它们区分大小写,因为它们有时(通常在这些系统上)不区分大小写。
正在修复
与此同时,棘手的部分是恢复您的分支。这需要深入研究 Git 内部结构。
两部分
在 Git 中,当前分支有两个关键组件。一个是文件.git/HEAD
。该文件包含一个简单的字符串:
$ cat .git/HEAD
ref: refs/heads/master
$
也就是说,这个文件包含(作为纯文本:不是 "rich text",不是 Unicode,不是 Windows UCS-2 格式,只是简单的 ASCII 文本)文字字符串 ref: refs/heads/
,在 refs/heads/
之前有一个 space,后跟分支名称,然后是换行符。此文件没有受到伤害!
另一半比较复杂。好消息是大部分并发症都消失了,因为如果没有,分支名称将区分大小写 "the rest of the way",您可能(或可能不会)仍然没问题。但是这个:
$ git log
fatal: your current branch 'Exif' does not have any commits yet
证明分支值仅存储在文件 .git/refs/heads/<em>branchname</em>
.
也就是说,您曾经有一个文件名为:
.git/refs/heads/Exif
其中有一些哈希值,类似于这个(但具有不同的哈希值):
$ cat .git/refs/heads/master
3ab228137f980ff72dbdf5064a877d07bec76df9
我们需要做的是用相同的值将该文件放回原处。
修复它:如果您有值(或部分值)
如果您可以看到值——甚至只是其中的一部分——某处,例如,在现有的window中,这足以获得整个值背部。例如,如果我在某处显示 3ab228
,我可以这样做:
$ git rev-parse 3ab228
3ab228137f980ff72dbdf5064a877d07bec76df9
这让我可以这样做来解决问题:
$ git rev-parse 3ab228 > .git/refs/heads/master
我们完成了。 (请参阅下面关于 reflog 的最后一项。)
修复它:如果您将它作为远程跟踪分支
如果你之前已经成功推送了分支,你可能拥有远程跟踪分支的价值:
$ git rev-parse origin/master
3ab228137f980ff72dbdf5064a877d07bec76df9
在这种情况下,您可以将其放回原处:
$ git rev-parse origin/master > .git/refs/heads/master
大功告成。 (请参阅下面关于 reflog 的最后一项。)
修复它:如果你的上游有它
在你的例子中,听起来像远程 origin
在名称 exif
下有正确的散列 ID(全部小写),即由于某种原因它忽略了 git push --delete
命令。在这种情况下,您可以向遥控器询问该值。请注意,其他人 可能 从那时起更新了它:
$ git ls-remote origin master
454cb6bd52a4de614a3633e4f547af03d5c3b640 refs/heads/master
(显然我的遥控器已经移动了,所以我无法使用它,但如果你幸运的话,你的没有)。确保值是好的:
$ git rev-parse 454cb6bd
454cb6bd
fatal: ambiguous argument '454cb6bd': unknown revision or path
not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
(所以这对我不起作用,因为他们确实继续前进)。
万不得已,您可以 运行:
$ git fsck --unreachable
这可能会吐出一大堆 unreachable
消息:
unreachable commit fcfbe9a1165e38467b4d24d41b3166a20c1dfb80
unreachable commit c8056a11ef8eee1bfaaaa2e32a9cc92a02eae2e0
unreachable blob 010a1a22a90b2bd78e6b87a3922c3324c44a8a9b
unreachable commit c1163ad1eeff0c86f030483907ea8cedcdd431e3
unreachable commit f35fc21adeb21e1a4800ccebd5719317efb968dc
忽略除 "commit" 之外的所有内容:其中之一是正确的。要找出哪一个,每个 运行 git show
,也许有一些可以帮助缩短它们的东西,例如:
$ git show --pretty=oneline --no-patch fcfbe9a1165e38467b4d24d41b3166a20c1dfb80
fcfbe9a1165e38467b4d24d41b3166a20c1dfb80 WIP on precious: e59f6c2 The last
minute bits of fixes
(这表明该特定项目实际上是 git stash
提交)。
当你找到合适的,你可以把它放入 .git/refs/heads/Exif
来恢复价值,你的存储库将大部分恢复原状。 git rev-parse
方法在这里也适用,虽然因为你有完整的原始哈希,你真的不必 rev-parse
它。
reflog不见了;以及您还可以去哪里
恢复分支文件修复分支并使一切重新准备就绪,例如:
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
但是,分支的 reflog 现已消失:
$ git reflog master
$
HEAD
的 reflog 仍然有效,一旦你在你的分支上做更多的事情,分支的 reflog 将被重新创建。
如果您的文件系统得到备份——例如,通过 MacOS Time Machine,或通过在 Windows 网络驱动器上做快照,或类似的方式——您可以查看您的系统备份。如果幸运的话,您可能会在这些备份中同时找到分支文件和 reflog。
在这种情况下,您可以简单地将它们还原到位。这与找到正确的哈希具有相同的效果,但通过恢复 reflog,您可以恢复 reflog。
好的,上下文是我在自己的分支上工作,为某个项目创建功能。
我的分支叫做 Exif(大写 E),今天我不小心做了
git push origin exif (lowercase e)
所以它为我创建了一个名为 exif
的新分支意识到这一点后,我做到了
$ git push origin --delete exif
$ git branch -d exif
再次有效删除分支。
我必须补充一点,我在 Exif(大写 E)中检出时执行了这两行,但这应该无关紧要吧?
现在,当我执行
git status
我得到一个巨大的列表,说整个项目中的每个文件都是一个新文件
当我尝试时
git log
它说,你当前的分支还没有任何提交
当我
git branch -a
所有分支都有,除了Exif,它也不在远程分支列表中
但在我们的 gitlab 服务器上,它显示分支正常,就像什么也没发生一样。
有人知道这里发生了什么吗?
编辑:
在 eclipse 中,它在每个文件旁边显示一个星号,这意味着每个文件都已暂存。
在 Eclipse 中,它还会在根项目文件夹旁边显示该项目具有 [NO-HEAD]
删除分支时,git不区分大小写,这意味着如果您执行
,您的分支"Exif"将被删除git branch -d exif
您一开始甚至没有创建分支 "Exif",因为通过推送到不同的分支,您不会自动在本地存储库中创建该分支。
要返回原来的分支,我会通过再次检查远程分支来创建一个新的本地分支,如下所示:
git checkout origin/exif
这里的另一个答案不太正确,虽然这个:
but on our gitlab server it shows the branch just fine like nothing happened.
很有前途,因此您可能有一种简单的方法来解决问题。
我将展示一个示例,其中我销毁了自己的 master
分支(当然是在克隆中)。由于这个特定的系统是区分大小写的,我只是手动删除了 master
分支(在 Git 的背后,就像它一样)。
Git 错误:分支名称区分大小写,除非它们不区分大小写
这是 Git 中的错误:它设法删除了您所在的分支。
出现问题是因为 Git 是 区分大小写的:就 Git 而言,分支 exif
完全与分支 Exif
分开。当您要求 Git 删除 exif
时,实际上检查了:
- 我在分支
exif
吗? - 如果是这样,请拒绝尝试,因为它会搞砸一切。
- 否则,继续删除
exif
。
所以 Git 检查了一下,发现你当前的分支是 Exif
,而不是 exif
。嗯,对Git来说,那些明明是不同,删了一定安全!只是……他们不是,也不是。
正在修复
与此同时,棘手的部分是恢复您的分支。这需要深入研究 Git 内部结构。
两部分
在 Git 中,当前分支有两个关键组件。一个是文件.git/HEAD
。该文件包含一个简单的字符串:
$ cat .git/HEAD
ref: refs/heads/master
$
也就是说,这个文件包含(作为纯文本:不是 "rich text",不是 Unicode,不是 Windows UCS-2 格式,只是简单的 ASCII 文本)文字字符串 ref: refs/heads/
,在 refs/heads/
之前有一个 space,后跟分支名称,然后是换行符。此文件没有受到伤害!
另一半比较复杂。好消息是大部分并发症都消失了,因为如果没有,分支名称将区分大小写 "the rest of the way",您可能(或可能不会)仍然没问题。但是这个:
$ git log
fatal: your current branch 'Exif' does not have any commits yet
证明分支值仅存储在文件 .git/refs/heads/<em>branchname</em>
.
也就是说,您曾经有一个文件名为:
.git/refs/heads/Exif
其中有一些哈希值,类似于这个(但具有不同的哈希值):
$ cat .git/refs/heads/master
3ab228137f980ff72dbdf5064a877d07bec76df9
我们需要做的是用相同的值将该文件放回原处。
修复它:如果您有值(或部分值)
如果您可以看到值——甚至只是其中的一部分——某处,例如,在现有的window中,这足以获得整个值背部。例如,如果我在某处显示 3ab228
,我可以这样做:
$ git rev-parse 3ab228
3ab228137f980ff72dbdf5064a877d07bec76df9
这让我可以这样做来解决问题:
$ git rev-parse 3ab228 > .git/refs/heads/master
我们完成了。 (请参阅下面关于 reflog 的最后一项。)
修复它:如果您将它作为远程跟踪分支
如果你之前已经成功推送了分支,你可能拥有远程跟踪分支的价值:
$ git rev-parse origin/master
3ab228137f980ff72dbdf5064a877d07bec76df9
在这种情况下,您可以将其放回原处:
$ git rev-parse origin/master > .git/refs/heads/master
大功告成。 (请参阅下面关于 reflog 的最后一项。)
修复它:如果你的上游有它
在你的例子中,听起来像远程 origin
在名称 exif
下有正确的散列 ID(全部小写),即由于某种原因它忽略了 git push --delete
命令。在这种情况下,您可以向遥控器询问该值。请注意,其他人 可能 从那时起更新了它:
$ git ls-remote origin master
454cb6bd52a4de614a3633e4f547af03d5c3b640 refs/heads/master
(显然我的遥控器已经移动了,所以我无法使用它,但如果你幸运的话,你的没有)。确保值是好的:
$ git rev-parse 454cb6bd
454cb6bd
fatal: ambiguous argument '454cb6bd': unknown revision or path
not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
(所以这对我不起作用,因为他们确实继续前进)。
万不得已,您可以 运行:
$ git fsck --unreachable
这可能会吐出一大堆 unreachable
消息:
unreachable commit fcfbe9a1165e38467b4d24d41b3166a20c1dfb80
unreachable commit c8056a11ef8eee1bfaaaa2e32a9cc92a02eae2e0
unreachable blob 010a1a22a90b2bd78e6b87a3922c3324c44a8a9b
unreachable commit c1163ad1eeff0c86f030483907ea8cedcdd431e3
unreachable commit f35fc21adeb21e1a4800ccebd5719317efb968dc
忽略除 "commit" 之外的所有内容:其中之一是正确的。要找出哪一个,每个 运行 git show
,也许有一些可以帮助缩短它们的东西,例如:
$ git show --pretty=oneline --no-patch fcfbe9a1165e38467b4d24d41b3166a20c1dfb80
fcfbe9a1165e38467b4d24d41b3166a20c1dfb80 WIP on precious: e59f6c2 The last
minute bits of fixes
(这表明该特定项目实际上是 git stash
提交)。
当你找到合适的,你可以把它放入 .git/refs/heads/Exif
来恢复价值,你的存储库将大部分恢复原状。 git rev-parse
方法在这里也适用,虽然因为你有完整的原始哈希,你真的不必 rev-parse
它。
reflog不见了;以及您还可以去哪里
恢复分支文件修复分支并使一切重新准备就绪,例如:
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
但是,分支的 reflog 现已消失:
$ git reflog master
$
HEAD
的 reflog 仍然有效,一旦你在你的分支上做更多的事情,分支的 reflog 将被重新创建。
如果您的文件系统得到备份——例如,通过 MacOS Time Machine,或通过在 Windows 网络驱动器上做快照,或类似的方式——您可以查看您的系统备份。如果幸运的话,您可能会在这些备份中同时找到分支文件和 reflog。
在这种情况下,您可以简单地将它们还原到位。这与找到正确的哈希具有相同的效果,但通过恢复 reflog,您可以恢复 reflog。