如何将git回购添加为自身的子模块?(或者:如何以编程方式生成GitHub页面?)
我想开始使用我的项目的网站。这只需要在回购协议中有一个名为如何将git回购添加为自身的子模块?(或者:如何以编程方式生成GitHub页面?),git,github,git-submodules,Git,Github,Git Submodules,我想开始使用我的项目的网站。这只需要在回购协议中有一个名为gh pages的分支(子树),并提供其内容。问题是网站的一部分(手册、变更日志、下载页面…)是由构建系统自动生成的,因此我想找到最好的方法,在主回购保持在主回购上时,将这些变更提交到gh页面分支 要提交到gh页面分支,我可以编写一个脚本,将repo克隆到一个临时目录中,进行修改,提交它们,然后将它们推回到主repo。但这听起来像是一个容易出错的过程,所以我希望有一个更简单的方法 一位朋友建议我可以将gh页面分支作为子模块添加到主存储库中
gh pages
的分支(子树),并提供其内容。问题是网站的一部分(手册、变更日志、下载页面…)是由构建系统自动生成的,因此我想找到最好的方法,在主回购保持在主回购上时,将这些变更提交到gh页面
分支
要提交到gh页面
分支,我可以编写一个脚本,将repo克隆到一个临时目录中,进行修改,提交它们,然后将它们推回到主repo。但这听起来像是一个容易出错的过程,所以我希望有一个更简单的方法
一位朋友建议我可以将gh页面
分支作为子模块添加到主存储库中。我做了一个小实验,但不太管用:
$ git init main
Initialized empty Git repository in /tmp/main/.git/
$ cd main
$ touch main.txt
$ git add .
$ git commit -m'Initial commit in main branch.'
[master (root-commit) 1c52a4e] Initial commit in main branch.
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 main.txt
$ git symbolic-ref HEAD refs/heads/gh-pages
$ rm .git/index
$ git clean -fdx
Removing main.txt
$ touch index.html
$ git add .
$ git commit -m'Initial commit in website branch.'
[gh-pages (root-commit) 94b10f2] Initial commit in website branch.
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 index.html
$ git checkout master
Switched to branch 'master'
$ git submodule add -b gh-pages . gh-pages
repo URL: '.' must be absolute or begin with ./|../
$ git submodule add -b gh-pages ./ gh-pages
remote (origin) does not have a url defined in .git/config
我不熟悉子模块;当然,我读过一些书,但我不理解这种行为。为什么它需要一个原点
遥控器?理想情况下,我希望子模块总是引用它所在的repo,因此它不应该引用origin
或任何其他远程设备。如果有人克隆repo并运行git子模块init;git子模块更新
,理想情况下应该从新克隆的repo中提取
是否可以将回购协议添加为其自身的子模块?这是可取的吗?有什么陷阱需要我注意吗?有没有更好的方法来实现我想要的?在这种情况下,git的行为似乎是试图将原始存储库的源设置为子模块的源。这一点可以通过
git子模块
手册页得到证实,手册页上写着[我的重点]:
是新子模块的源存储库的URL。这可能是一个绝对URL,或者(如果它以./或./)开头)相对于超级项目的原始存储库的位置
对我来说,一个不错的解决方法是执行以下操作:
# Define origin to be the absolute path to this repository - we'll remove
# this later:
$ cd /tmp/main/
$ git remote add origin /tmp/main/
# Now add the submodule:
$ git submodule add -b gh-pages ./ gh-pages
Initialized empty Git repository in /tmp/main/gh-pages/.git/
Branch gh-pages set up to track remote branch gh-pages from origin.
# Now .gitmodules looks sensible:
$ cat .gitmodules
[submodule "gh-pages"]
path = gh-pages
url = ./
# However, the origin for the submodule isn't what we want:
$ cd gh-pages
$ git remote -v
origin /tmp/main/ (fetch)
origin /tmp/main/ (push)
# So remove it and add the right origin (just ".."):
$ git remote rm origin
$ git remote add origin ..
# Change back to the main repository and commit:
$ cd ..
$ git commit -m "Added the gh-pages branch as a submodule of this repository"
[master 6849d53] Added the gh-pages branch as a submodule of this repository
2 files changed, 4 insertions(+), 0 deletions(-)
create mode 100644 .gitmodules
create mode 160000 gh-pages
这似乎工作正常-如果我切换到另一个目录并执行以下操作:
$ cd /var/tmp
$ git clone --recursive /tmp/main/
。。。子模块已正确更新和初始化。(更新:尽管正如您在下面的评论中指出的,子模块中的origin
将设置为您从中克隆的URL,而不是。
)
至于这是否是一个好主意:我曾经参与过一个项目,该项目在过去使用过类似的设置,但后来放弃了它。然而,这样做的原因是(a)主存储库中的替代分支非常庞大,甚至对于不需要子模块的人来说,存储库也过于臃肿;(b)它给不确定发生了什么的人带来了困惑
然而,对于您的用例,我认为这是一个相当简洁的解决方案:)使用生成的替代方法是使用。和的。甚至有一个新版本可能会也可能不会与您的Git版本一起安装。在我看来,你真正需要知道的只有这两点
- 子树合并策略在合并时匹配两个存储库/分支的树(git的目录树概念),以便不合并无关的文件和文件夹,只合并相关的树。这正是您想要的Github页面,因为它位于孤立分支中,所以它与主分支具有完全不同的树
- 通常,子树合并具有简化的工作流程,并且与子模块相比,丢失修订的可能性更小
gh pages
的分支,则使用--orphan
标志创建一个分支,使其为空。如果您使用了,则可以跳过此步骤,但在本文的其他任何地方,都可以将本地分支gh页面
替换为远程分支origin/gh页面
,否则。注意:您可以跳过创建.nojekyll
文件,但必须从孤立分支中删除所有文件并提交,否则将无法创建该文件
如果您已经在主分支的一个子树中拥有文档,您可以立即将其拉入并使用提交,但您必须了解树。假设您可以首先使用,它将输出当前索引中由--prefix
标志命名的树的SHA-1。然后使用-u
标志更新带有来自主分支的更改的gh页面
分支,并提交更改
. $ (master) git write-tree --prefix=docs/_build/html master
abcdefghijklmnopqrstuvwxyz1234567890abcd
. $ (master) git checkout gh-pages
. $ (gh-pages) git read-tree abcdefghijklmnopqrstuvwxyz1234567890abcd
. $ (gh-pages) git commit -m "update gh-pages html from master docs"
master
并使用git read tree
将gh页面的工作副本复制到master
中的某个路径,例如:/docs/\u build/html
。如果合并成功,-u
标志将更新工作副本中的文件。如果gh pages
分支中没有要与master合并的文件,则此步骤可能是不必要的,但如果有,它可能有助于子树合并策略确定文件位于哪个树中。和往常一样,Git不允许您合并已经存在的文件,或者如果您的repo中有未提交的更改。如果要将使用自动页面生成创建的页面合并回另一个树中,例如:docs
在master
分支中,请使用此步骤。不要忘记将新文件提交到主分支
. $ (gh-pages) git checkout master
. $ (master) git read-tree --prefix=docs/_build/html -u gh-pages
. $ (master) git commit -m "read gh-pages tree into master at ./docs/_build/html"
-s子树
)更新您的gh页面
分支,挤压所有提交,这样您的Github页面历史记录就不会被污染(--squash
),并等到合并后再提交,这样您就可以查看(--no commit
)。注意:当您签出gh页面时
. $ (gh-pages) git checkout master
. $ (master) git read-tree --prefix=docs/_build/html -u gh-pages
. $ (master) git commit -m "read gh-pages tree into master at ./docs/_build/html"
./docs $ (master) sphinx-quickstart
...
./docs $ (master) make html
./docs/_build/html $ (master) echo >> .nojekyll
. $ (master) git checkout origin/gh-pages
. $ (gh-pages) git merge --no-commit --squash -s subtree master
. $ (gh-pages) git merge --no-commit --squash -s recursive -Xsubtree=docs/_build/html/ master
. $ (gh-pages) git commit
. $ (gh-pages) git push origin gh-pages
. $ (gh-pages) git checkout master
. $ git diff-tree master gh-pages