我使用以下命令建立了一个新的Git存储库:
mkdir plans-for-world-domination
cd plans-for-world-domination
git init
echo "MWA HA HA HA HA!" > plans.txt
git add .
git commit -m "Beginning my plans..."
然后,我对该存储库进行了克隆,进行了一些更改,将其提交,然后尝试推送:
cd ..
git clone plans-for-world-domination clone
cd clone
echo "Step 1: set up super secret spy base in Cleveland, Ohio" >> plans.txt
git commit -am "Update plans"
git push origin master
但是,当我cd
回到plans-for-world-domination
存储库时,在暂存区/索引中进行了一些更改,这些更改与我刚刚推送的更改相反:
$ cd ../plans-for-world-domination
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: plans.txt
$ git diff --staged
diff --git a/plans.txt b/plans.txt
index febb495..ce01362 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,2 +1 @@
MWA HA HA HA HA!
-Step 1: set up super secret spy base in Cleveland, Ohio
为什么我的第一个存储库有这些未分级的更改,这些更改与我刚刚推送的内容相反,我该如何解决?
第一个存储库中的暂存区域似乎包含与刚刚推送的更改相反的内容,因为它是一个非裸露的存储库,这意味着它包含一个工作副本,在工作目录中通常也称为工作树(目录) Git文档。另一方面,裸存储库没有工作副本目录。
由于存储库是非裸存储库,因此在推送到存储库时,该推送仅更新分支引用和符号HEAD
引用,因为git push
它不会对非裸存储库中存在的工作副本和登台区域进行操作。
因此,非裸仓库的工作副本和暂存区域仍保留在更新推送之前存在的存储库状态中HEAD
。换句话说,工作副本和登台区域的实际状态与所指向的提交状态不匹配 HEAD
。这就是为什么两种状态之间的差异在git status
和git diff
运行时会显示出来的原因:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: plans.txt
$ git diff --staged
diff --git a/plans.txt b/plans.txt
index febb495..ce01362 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,2 +1 @@
MWA HA HA HA HA!
-Step 1: set up super secret spy base in Cleveland, Ohio
由于工作副本和临时区域与不同步HEAD
,因此使它们再次匹配的解决方案是简单地使用
git reset --hard HEAD
git reset --hard
将工作区和暂存区重置为指向的提交HEAD
。
但是,这不是理想的解决方案...
实际上,您不应该使用非裸存储库,因为它们的工作副本和登台区域与存储库引用不同步的确切问题是这样的。取而代之的是,除非您出于特殊原因要推送到非裸存储库,否则您应该真正地推送到裸存储库,因为裸存储库没有工作副本。
要创建裸仓库,只需使用--bare
标志:
# Initialize a bare repo
mkdir bare
cd bare
git init --bare
# Push changes to the bare repo
cd ..
mkdir project
cd project
# Make some changes and commit
git remote add origin ../bare
git push origin master
# Or create a bare clone from another bare or non-bare repo
git clone --bare <repo-path-or-uri>
请注意,从Git版本1.6.2开始,默认情况下拒绝推送到非裸存储库:
在下一个主要版本中,
git push
默认情况下将拒绝进入当前已签出的分支。您可以通过receive.denyCurrentBranch
在接收存储库中设置配置变量来选择在进行此推送时应该发生的情况。
实际上,当您尝试使用当前版本的Git推送到非裸仓库时,您的推送应被拒绝,并显示以下错误消息(为简洁起见,对其进行了略微修改):
$ git push origin master
Total 0 (delta 0), reused 0 (delta 0)
error: refusing to update checked out branch: refs/heads/master
error: By default, updating the current branch in a non-bare repository
error: is denied, because it will make the index and work tree inconsistent
error: with what you pushed, and will require 'git reset --hard' to match
error: the work tree to HEAD.
error:
error: You can set 'receive.denyCurrentBranch' configuration variable to
error: 'ignore' or 'warn' in the remote repository to allow pushing into
error: its current branch; however, this is not recommended unless you
error: arranged to update its work tree to match what you pushed in some
error: other way.
error:
error: To squelch this message and still keep the default behaviour, set
error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To non-bare
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'non-bare'
如上面的错误消息所述,您可以通过禁用远程非裸仓库中的receive.denyCurrentBranch
配置设置来禁用阻止进入非裸仓库的安全检查:
git config receive.denyCurrentBranch warn # Warn when pushing to non-bare repo
git config receive.denyCurrentBranch ignore # Don't even bother warning
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句