How to add a git repo as a submodule of itself? (Or: How to generate GitHub Pages programmatically?)

后端 未结 2 668
故里飘歌
故里飘歌 2020-12-14 02:13

I want to start using GitHub Pages for my project\'s website. This simply requires a branch (subtree) named gh-pages in the repo, and serves up its content. The

2条回答
  •  有刺的猬
    2020-12-14 02:51

    An alternative to using Git Submodules to generate GitHub Pages is to use Git Subtree Merge Strategy. There are many sites that show how to do this and that argue the pros and cons of Submodules vs Subtree-Merge. There is even a newish git-subtree command that may or may not be installed with your version of Git. IMO the only things you really need to know are these two points.

    • The subtree merge strategy matches the trees (git's notion of a directory tree) of two repositories/branches when merging so that extraneous files & folders are not merged, only the relevant trees. This is exactly what you want for Github Pages, since it is in an orphan branch, it has a completely different tree your master branch.

    • In general, the subtree merge has a simplified workflow and less chance for losing revisions than submodules do.

    Here's how to use subtree merge strategy with Github Pages:

    1. If you don't have a branch called gh-pages in either local or remote repos, then create one using the --orphan flag so that it will be empty. Github has instructions for creating Github pages manually.. If you used the Automatic Page Generation then you can can skip this step, but replace the local branch gh-pages with the remote branch origin/gh-pages everywhere else in this post, otherwise fetch the remote branch locally. NOTE: You can skip creating the .nojekyll file, but you must remove all files from the orphan branch and commit it or it will not be created.

      . $ (master) git checkout --orphan gh-pages
      . $ (gh-pages) git rm -rf. 
      . $ (gh-pages) echo >> .nojekyll
      . $ (gh-pages) git add .nojekyll
      . $ (gh-pages) git commit -m "create github pages, ignore jekyll"
      

      If you have documentation in a sub tree in your main branch already you could pull it in and commit it using git-read-tree right now, but you would have to know tree-ish. Presumably you could first use git-write-tree which will output the SHA-1 of the tree named by the --prefix flag in the current index. Then use the -u flag to update the gh-pages branch with changes form the main branch and commit the changes.

      . $ (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"
      
    2. Checkout master and use git-read-tree to copy the working copy of the gh-pages branch to some path in master, EG: ./docs/_build/html. The -u flag updates files in the working copy if merge is successful. This step may be unnecessary if there are no files in gh-pages branch that you want to merge back with master, but if there are, it may help the subtree merge strategy to figure out in what tree your files are. As usual, Git won't let you merge over files that already exist or if there are uncommitted changes in your repo. Use this step if you want to merge the pages you created using Automatic Page Generation back into a different tree, EG: docs in your master branch. Don't forget to commit the new files to your master branch.

      . $ (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"
      
    3. Make changes to your documentation and generate some html by whatever means you prefer. EG: Jekyll, Pelican or Sphinx. NOTE: If you are not using Jekyll, and will need underscore folders/files, EG: for *.css or *.js files, then be sure to add a file called .nojekyll to your html directory.

      ./docs $ (master) sphinx-quickstart
      ...
      ./docs $ (master) make html
      ./docs/_build/html $ (master) echo >> .nojekyll
      
    4. Update your gh-pages branch using the subtree merge strategy (-s subtree), squash all of the commits so your Github pages history isn't polluted (--squash) and wait till after the merge to commit so you can review (--no-commit). NOTE: When you checkout your gh-pages branch, files & folders from master will probably remain as Untracked, just ignore them and concentrate on what is actually in the index. NOTE: Git will not checkout gh-pages if there are any uncommited or unstashed modifications in master.

      . $ (master) git checkout origin/gh-pages
      . $ (gh-pages) git merge --no-commit --squash -s subtree master
      

      Git makes its best guess as to what trees you want to merge using the subtree merge strategy, however, if there isn't much to go on, you might be better explicitly telling Git which tree to merge.

      . $ (gh-pages) git merge --no-commit --squash -s recursive -Xsubtree=docs/_build/html/ master
      
    5. Review your changes and commit. Merge generates a message for you containing the short log of all of the commits being merged.

      . $ (gh-pages) git commit
      
    6. Pushing your gh-pages branch deploys your GitHub Pages website.

      . $ (gh-pages) git push origin gh-pages
      
    7. Return to master.

      . $ (gh-pages) git checkout master
      
    8. If you need to pull changes from your gh-pages for whatever reason, use the subtree merge strategy in the opposite direction. EG git merge --squash --no-commit -s subtree gh-pages

    9. To do a diff of the two branches matching the trees, use diff-tree

      . $ git diff-tree master gh-pages
      
    10. Put this into a script or a post-commit hook that runs whenever you edit your documents or add it to the Makefile you use to generate html and voila! programmatically generated GitHub pages.

提交回复
热议问题