Git 如何将更改推送到其他人';是否从我自己的存储库的子模块中删除了?

Git 如何将更改推送到其他人';是否从我自己的存储库的子模块中删除了?,git,github,Git,Github,所以我有自己的存储库,我们称之为“我的”,它包含一个子模块存储库“他们的”。我可以访问他们的远程存储库,因此我可以直接将更改推送到存储库 我试图将我对“他们的”所做的更改推回到他们的远程GitHub存储库,但我似乎无法让它工作。我可以将更改推送到GitHub上的远程存储库“我的”,在那里可以看到对“他们的”的新提交。但是当我访问他们的GitHub时,它没有添加最新的提交 子模块不应该只是一个常规的存储库,在另一个存储库中包含一些额外的元数据吗?如果是这样的话,为什么从“Theres”目录中的“g

所以我有自己的存储库,我们称之为“我的”,它包含一个子模块存储库“他们的”。我可以访问他们的远程存储库,因此我可以直接将更改推送到存储库

我试图将我对“他们的”所做的更改推回到他们的远程GitHub存储库,但我似乎无法让它工作。我可以将更改推送到GitHub上的远程存储库“我的”,在那里可以看到对“他们的”的新提交。但是当我访问他们的GitHub时,它没有添加最新的提交

子模块不应该只是一个常规的存储库,在另一个存储库中包含一些额外的元数据吗?如果是这样的话,为什么从“Theres”目录中的“git push”不起作用?我尝试过从“他们的”和“cd…”中提交和推送,然后从“我的”中提交/推送,但也不起作用

我尝试了这里列出的步骤:没有用。我只能假设,因为我试图推送到一个我不拥有的存储库,所以需要做一些其他的事情

~/Mine$ git remote -v                                                                                                                                                                                                        
origin  https://github.com/myUser/Mine.git (fetch)                                                                                                                                                                                
origin  https://github.com/myUser/Mine.git (push) 

~/Mine/Their$ git remote -v                                                                                                                                                                                                    
origin  https://github.com/theirUser/Theirs.git (fetch)                                                                                                                                                                                        
origin  https://github.com/theirUser/Theirs.git (push) 

一旦提交完成,就推出分叉回购(即“我的”)。从你的叉子上打开一个正确分支中的拉动请求。一旦拉动请求得到批准和合并,您可以将变更从上游拉动到本地回购


然后更改将被添加到“他们的”存储库中。

您是正确的:子模块本身就是一个存储库。这意味着您可以将
cd
chdir
放入子模块,并以与使用任何其他Git存储库相同的方式开始使用它,包括运行
Git fetch
Git checkout
Git commit
,等等

子模块之所以成为子模块,是因为位于子模块上方某处的另一个Git正在控制子模块,通常是通过在其中运行
Git checkout hash id
。这将使子模块进入Git所称的分离头模式。(控制Git的是超级项目。)

这种“头部分离”模式有点棘手。您可以在此模式下进行新的提交,但当您这样做时,大多数普通方法都无法找到它们。目前可以通过特殊名称
HEAD
轻松找到它们,但是超级项目将强制调整此特殊名称
HEAD
,它将
chdir
放入子模块,并再次运行
git checkout hash id
,从而丢失您所做的提交

要将您在子模块Git存储库中所做的提交发送到其他Git存储库,必须在其他Git存储库中为这些提交指定一个名称。通常,这意味着给他们一个分支名称。在您的存储库中使用分支名称没有什么硬性要求,因为您可以运行:

git推压头:
通过名称
HEAD
将子模块存储库中标识的提交发送到另一个Git,并礼貌地要求它创建或更新其名称
name
,以指向该提交。但是大多数人不喜欢在超脱的头部模式下工作

一般来说,这意味着要在作为某个超级项目的子模块的Git存储库中工作,您应该使用以下顺序:2

  • 输入子模块。从这里到第3步,您只需将其作为常规Git存储库使用

  • 通过选择要签出的分支名称,或创建指向当前提交的分支名称,退出分离头模式。请注意,如果选择某个现有分支名称,则可能是与当前提交不同的提交。或者它可能与当前提交相同

    记住,superproject存储库之前告诉这个Git:使用这个原始提交,通过它的散列ID进入分离头模式。我们现在正在脱离分离头部模式,这需要拾取或创建分支名称。如果选择某个现有的分支名称,则必须执行该分支名称选择的任何提交操作。但是,如果您在子模块存储库中开发新的提交,您可能需要一个分支名称来记住它们

  • 现在,以通常的方式进行新的提交。按常规方式使用git push。提交将或不将以提交做或不做的通常方式转到接收存储库。如果他们确实到达了接收存储库,那么将以通常的方式创建或更新该存储库的分支名称

  • 完成所有操作后,退出子模块存储库,返回超级项目存储库。现在是在超级项目中做出新承诺的时候了

  • 我已经多次提到,超级项目Git一直控制着子模块Git。它对子模块Git执行
    chdir
    ,并运行
    Git checkout hash id
    。这里的关键分为两部分:

    • 超级项目Git何时对子模块执行此操作
    • 超级项目Git从哪里获得原始哈希ID
    第一个问题的答案很复杂:
    git子模块更新
    做到了,但并不总是这样;3
    git checkout——递归执行(始终);根据选项和设置,各种其他操作有时也可以执行此操作。也就是说,除非你要求它发生,否则它不会发生,但你要求它发生并不总是显而易见的我们要做的是确保在第二点再次发生之前解决它。

    第二个问题的答案是超级项目Git从哪里获得原始哈希ID,它是从超级项目中的提交中获得的。但是您已经在子模块中进行了一次新的提交,并将其上传到其他一些Git存储库,因此现在是在超级项目中进行新提交的时候了,以记录正确的哈希ID,即您在子模块中进行的新提交的哈希ID

    一如既往,任何承诺都无法改变;
    git push <remote-or-URL> HEAD:<name>