裸git回购post接收钩子不再能够签出
我在web服务器上有一个常见的裸git回购设置,使用post接收挂钩自动签出对web站点的更改。这一直很有效 但是,一位同事最近克隆了裸repo(裸git回购post接收钩子不再能够签出,git,git-post-receive,git-bare,Git,Git Post Receive,Git Bare,我在web服务器上有一个常见的裸git回购设置,使用post接收挂钩自动签出对web站点的更改。这一直很有效 但是,一位同事最近克隆了裸repo(git clone),对其本地repo进行了一些更改,提交了这些更改,然后将更改推回(git push origin master)。我不确定这个过程是否是导致问题的原因,但是由于推送,post-receive钩子不再工作。输出失败: fatal: You are on a branch yet to be born 这是钩子: #!/bin/bas
git clone
),对其本地repo进行了一些更改,提交了这些更改,然后将更改推回(git push origin master
)。我不确定这个过程是否是导致问题的原因,但是由于推送,post-receive钩子不再工作。输出失败:
fatal: You are on a branch yet to be born
这是钩子:
#!/bin/bash
GIT_WORK_TREE=/home/marweldc/app git checkout -f
我能够将同事所做的更改从远程实例拉到本地实例。在服务器上的裸repo目录中运行git branch
,会显示*master
,git log
显示所有更改,包括我同事的更改,因此远程repo显然可以很好地跟踪事情
但是,如果我这样做,比如说,一个GIT\u WORK\u TREE=/home/marweldc/app GIT status
我会得到以下输出:
# Not currently on any branch.
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# ../CONTRIBUTING.md
# ../README.inno.txt
# <all the other files and folders that should be in the repo>
nothing added to commit but untracked files present (use "git add" to track)
我们被难住了。是什么改变了我们的钩子,使它在正常工作时以这种方式失效
编辑:
我尝试过的一些事情如下所示:
从裸回购协议内部产生cat HEAD
ref:refs/heads/master
来自裸回购收益GIT_TRACE=1 GIT rev parse master
但是使用trace: built-in: git 'rev-parse' 'master' f6462b06f75d126ab932e3cfccef7385da2805ba
选项集的相同命令会产生--worktree
trace: built-in: git 'rev-parse' 'master' master fatal: ambiguous argument 'master': unknown revision or path not in the working tree. Use '--' to separate paths from revisions
- 运行
(一个新的签出目录)可以正常工作GIT\u WORK\u TREE=/home/marweldc/app new GIT checkout-f
--work tree=/home/marweldc/app
会导致Git无法在Git目录和工作树之间来回移动。(其他工作树路径不会导致问题。)
Git没有注意到自己返回裸存储库的失败,然后无法对分支名称执行任何操作(因为它无法返回存储库,所以在这一点上很可能会失败)
更现代的Git可能一开始就没有这个bug,或者会注意到在工作树和裸存储库之间来回切换的失败
同时,指定--git dir=
似乎可以解决这个问题
原始(一般)答案如下
这:
fatal:您在一个尚未出生的分支上
意思就是它所说的,尽管它所说的可能令人困惑。:-)你真的“在”某个还不存在的分支上
(现在还不清楚你在哪个分支上,你可能有一个Git称之为“分离的头”,但如果你曾经有过分支的话,它确实看起来好像你不再有一个master
分支。)
短版
使用git branch
查看您现在所在的分支以及可用的分支。使用git symbolic ref HEAD refs/heads/master
强制将裸存储库的HEAD
设置回master
分支。对于其他名为B的分支,请使用refs/heads/B
下面是长形式的答案,即发生了什么
无论存储库是否是空的,它仍然有一个当前分支 在任何普通的非裸存储库中,您都可以通过运行
git status
来查看您所在的分支。但是,git status
查看工作树,因此在裸存储库中,git status
拒绝运行:没有工作树
查看您所在分支的另一种方法是运行git branch
:
$ git branch
diff-merge-base
* master
stash-exp
这适用于裸存储库和非裸存储库。*
以当前分支的名称命名
在常规存储库中,如何更改您所在的分支?
答案是:git checkout
。例如,git checkout master
将您(或我)置于master
上,git checkout stash exp
将您(或我)置于stash exp
上
1还有另一种方法,使用管道命令,但您通常不想使用它,因为它可能会弄乱当前提交、索引和工作树之间的差异。但由于裸存储库没有工作树,这就变成了。。。“安全”太强了,但我们可以说“危险小得多”
在裸存储库中,您如何更改您所在的分支? 答案仍然是
git checkout
当您签出裸存储库中的分支时,将使用和更改当前分支,方式与签出非裸存储库中的分支时完全相同。
当然,您不能git签出裸存储库中的分支,因为这会更新工作树。除此之外,当您使用git--work tree=。。。签出…
。您提供要签出的分支的名称,这会像往常一样将新的分支名称写入HEAD
。如果您签出一个commit by hash ID,它会像往常一样分离HEAD
未出生(孤)枝
但还有一种特殊情况:如果您将HEAD
设置为一个尚未存在的分支的名称(例如git checkout--orphant
),则将该名称放入HEAD
,而不创建分支。这在常规(非裸)存储库中是很正常的,只是您只在两种情况下看到它:
- 第一次创建新的空存储库时。您在
master
上,但master
尚不存在。您可以通过将提交放入存储库来解决这种情况,该存储库进入master
,创建master
。(新提交是根提交,即没有父提交。)
- 当您使用<代码
$ git branch
diff-merge-base
* master
stash-exp
fatal: You are on a branch yet to be born
On branch master