我最近在laravel中将一个新网站添加为电子商务。当我尝试将此站点推送到我的生产服务器时,收到关于未跟踪该站点的错误消息。
当我运行git status时,我得到了:
C:\Users\Kye\sites\laravel>git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
(commit or discard the untracked or modified content in submodules)
modified: e-commerce/demo (modified content, untracked content)
no changes added to commit (use "git add" and/or "git commit -a")
当我尝试添加文件夹和文件时:
git add e-commerce/demo -A
它仍然无法正常工作,并表示未跟踪。如何提交此更改并添加文件?
C:\Users\Kye\sites\laravel>git add .
C:\Users\Kye\sites\laravel>git add -A
C:\Users\Kye\sites\laravel>git commit -m "test"
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
modified: e-commerce/demo (modified content)
no changes added to commit
C:\Users\Kye\sites\laravel>git push
root@54.38.214.9's password:
Everything up-to-date
C:\Users\Kye\sites\laravel>
答案 0 :(得分:3)
此:
Changes not staged for commit: modified: e-commerce/demo (modified content)
表示您已经有一个子模块。具体来说,(modified content)
是赠品。
当超级项目使用子模块(在这种情况下)时,超级项目本身是Git存储库,而子模块是另一个主要独立的Git存储库。超级项目有一些关键的控制文件:
.gitmodules
包含Git超级项目所需的信息,以便运行git clone
来使子模块存储库存在。这些东西只需要一次!
.git/config
包含超级项目Git在运行git clone
后松散了的信息,以便子模块现在存在。
第二个文件当然还包含超级项目存储库对克隆超级项目的Git存储库执行的所有操作git fetch
和git push
。
请注意,由于子模块是是一个Git存储库,因此它具有自己的.git
,其中包含自己的.git/config
。这告诉子模块如何git fetch
和git push
到从中克隆子模块Git的Git存储库(由超级项目Git)。此时,有四个有趣的存储库:
git status
。origin
。(cd path; git status)
进行操作的Git,发现其中有一些修改。origin
,从中克隆了您的子模块。通常,这是您处理在子模块中所做的更改的方式:
在子模块Git中的某个地方(最好是分支)提交它们。一旦您非常熟悉Git,这部分就很容易了。
将它们发送给控制此子模块上游的任何人。例如,这可能涉及在GitHub上创建某个项目的分支。这部分比较难,但是与在任何具有上游资源的存储库中所做的一样,因此一旦您对Git非常熟悉,就不难了。
说服子模块上游的所有者接受您的更改。如果您自己拥有上游产品,那将非常容易:只需说服自己进行自己的更改即可。如果其他人拥有它,则可能需要做很多令人信服的事情,并且可能需要付出很多后端工作才能最终做出不同的承诺。这部分通常非常困难!取决于上游。
(或者,当然,您将来可以只使用fork,即 change 存储在超级项目的.gitmodules
和.git/config
中的URL。完成此操作后,您便拥有了上游资源,您只需要说服自己,就像我们刚才看到的那样,这可能会容易得多。)
现在这些更改已在上游存储库中提交,您可以在以后的克隆中依赖它们,所以一切都很好。在子模块中使用git checkout
可以检出正确的提交。如果需要,请在此处使用git fetch
,以从上游获取正确的提交。请确保此时git rev-parse HEAD
打印出 right 提交哈希ID,因为这就是我们要使用的。请记住,Git就是关于 commits 和它们的哈希ID 。分支名称仅在让我们查找哈希ID方面很重要。
最后,现在,您可以在超级项目中运行git add e-commerce/demo
。当您在超级项目中进行 next 提交时,您的Git将记录该提交的哈希ID,以从子模块中检出。
我们在步骤1-4中完成所有这些操作的原因不是为了使您的当前存储库正常工作。 (我们可以做得更简单。)这是使超级项目的未来克隆工作。
将来,有人会跑:
git clone <url for superproject>
这将为他们提供一个具有.gitmodules
文件的克隆。在该.gitmodules
文件中,它们将具有另一个 URL,用于指定如何克隆子模块。
接下来,他们将在必要时运行git checkout
(如果他们想要特定的提交或分支或其他任何操作),然后git submodule update --init
使其其 Git克隆子模块,按照.gitmodules
文件的指示。这将使用存储在.gitmodules
中的URL,并将信息复制到其.git/config
中用于其超级项目克隆。 此git submodule update
的最后一步是,他们的Git将查看当前提交,以查看子模块中git checkout
的哈希ID是什么。此时,他们的超级项目Git将执行(cd submodule; git checkout hash)
的等效操作,将其子模块放入您在步骤3中成功保存的提交中。您在中记录了该哈希ID。在第5步>您的超级项目Git;您获得在步骤4中已准备好该哈希ID;但您在第3步中将该哈希ID放入了上游存储库中。
您已经具有可以使用的提交,但是当未来人员将来克隆超级项目时,它们还没有您的子模块。他们获得了.gitmodules
的副本,这为他们提供了另一个git clone
的URL。他们运行另一个git clone
并获得子模块存储库。根据{{1}}文件的指示,它们获取的子模块来自上游的 。克隆超级项目时, 需要拥有该提交,该提交的哈希ID在步骤5中记录。
这就是让这变得困难的原因。这就是为什么有人将它们称为 sob -modules的原因。 :-)它确实可以完成所有工作,只是很复杂。如果您控制子模块的上游,那还不错。