gpt4 book ai didi

git - 为什么我不能推送到非裸仓库的已 checkout 分支?

转载 作者:太空狗 更新时间:2023-10-29 13:32:10 25 4
gpt4 key购买 nike

我对自己创造的一个场景感到困惑。我在github上创建了一个存储库(我们称之为a)并将代码推送到它上面。之后,我将该存储库克隆到本地(我们称之为b),这样本地的源代码就是远程repo a。
现在,我从本地B克隆来创建另一个本地实例C。

A → B → C

这类似于分叉,但这里我在客户端而不是服务器端创建了克隆。
现在,如果我试图使用从c到它的原点b的push:
git push origin 

然后我收到一个错误,指出我不能推送到非裸存储库。我知道,推送到非裸存储库可能会导致远程提交丢失,而本地提交不存在。
然而,这种情况是否与我将代码从b推送到a的情况不相似?
我很困惑,如果B到A是可能的,那么为什么不C到B呢。
对于合并到a,我们可以按如下方式推到上游:
git push upstream

最佳答案

一些基本的东西
无论何时git clone,从开发人员的角度来看,您都需要处理刚刚克隆的代码。所以git给了你一个“工作树”来工作。它之所以被称为树,是因为当你考虑到你所做的所有提交和分支并把它们放在一个图上时,它就像一棵树。
克隆的存储库称为非裸存储库。要创建一个非裸存储库,只需执行一个简单的git init-这就是原始程序员开始用git跟踪克隆代码所做的。您也可以将其克隆到一个裸存储库中,但是它的细节和有用性应该是它自己在一个恰当的问题中的答案。
裸存储库不包含工作树。它只是用来存储您的代码——如果您愿意的话,它是由git管理的代码的服务器。要创建一个裸存储库,可以执行一个简单的git init --bare name_of_repository.git。它将创建一个名为name_of_repository.git的目录,其中包含git所需的所有文件。git扩展只是一个使用的约定;它不是必需的,可以是任何东西,也可以是完全没有的。
git中有一个类似指针的东西,叫做head。它指向您工作的分支中活动的最新提交,无论它是裸存储库还是非裸存储库。
分支就像是刚刚从远程存储库中提取的代码的“不同副本”(可能有不同的修改或没有修改)。它有开发人员认为合适的任何名称。它们很有用,因为您可以处理不同的函数或修复不同的问题,而不必担心您或其他人正在开发的当前代码。稍后,您可以将所有内容合并到主分支(通常是主分支),然后删除不再需要的合并分支。
git尽量避免不同位置或分支的文件版本之间的问题。所以他不允许你在某些情况下,至少可以说是混乱的。git永远不会出错,因为它要求您检查、更改或强制您正在做的事情。所以任何错误都不是吉特的错,而是你的错。
了解情况
让我们考虑一下:
A存储库是一个裸存储库。B和C存储库都是非裸存储库。这意味着a没有工作目录,仅用于存储。B和C用于你需要做的工作。
一般来说,你(通常)有分支。通常,初学者不会创建分支,因为他正在学习,甚至可能还不知道分支-尽管它们有很多原因是有用的。所以他几乎总是在一个'主'分支-默认分支。
这就是说,假设你修改了b中的一些文件,你想修改多少次就修改多少次,最后甚至修改了agit push。或者你什么都不做。但你是主枝。
稍后,您将修改C中的文件,并提交并尝试推送到A。记住:您是C的主分支,git commit可以工作!
然后,你也试着把C推到B。它不起作用。
结果:git将(不是)字面上的尖叫,警告您试图玷污(更新)非裸存储库b的主分支,其头部指向另一个提交!如果他让你做推送,你会把git在存储库b上跟踪的历史搞砸,它再也不知道b发生了什么事!您甚至可以用B上的相同名称覆盖对该分支的修改!所以不,如果两者都是非裸存储库,就不能从c推到b!
现在怎么办?!我的世界会这样结束吗?!我能做什么?!吉特怎么可能无视主人的意愿?!这纯粹是异端!
解决方案
1-在B上有两个分支-主分支和一个临时分支。把头指向临时分支。例子:

cd B                  # change to B's working directory
git branch temp # create 'temp' branch
git checkout temp # change from master branch to branch temp

2-现在,移动到C工作目录(简称WD)并使用B的内容进行拉取。注意,我认为B是C的远程(如您在案例中所述):
cd ../C               # change to C's working directory
git pull B master # pulls B's modifications to C

3-修改C中的文件。请注意,您是C的主分支。然后,在提交对c的修改之后,将其推送到b的master:
git push B master     # pushes C's mods to B's master branch

4-现在回到B WD,使头部指向主分支:
cd ../B               # change to B's working directory
git checkout master # change from temp branch to branch master

5-如果不再使用临时分支,则可以将其删除:
git branch -d temp    # delete branch temp

6-如果您在C中进行新的修改,则不需要同时执行步骤4和5。如果您这样做了,任何时候您希望在c中进行修改,您都需要预先执行步骤1和2。
这就解决了你的问题!可能。。。
澄清和加固
git push创建新分支;
git push使头部指向这个新分支;
git branch name_of_the_branch创建一个分支,并在一个命令中使头部指向该分支。我用更长的方法是因为你也应该知道更长的方法;
如前所述,如果以后要使用分支,请不要删除它。但我建议这样做是为了避免在拉/推或甚至合并时出现两个存储库中临时分支的问题。根据需要创建临时分支-非常容易使用终端历史记录-然后删除它;

关于git - 为什么我不能推送到非裸仓库的已 checkout 分支?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39616617/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com