Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Deploy to `gh-pages` from a `dist` folder on the master branch. Useful for use with [yeoman](http://yeoman.io).

Deploying a subfolder to GitHub Pages

Sometimes you want to have a subdirectory on the master branch be the root directory of a repository’s gh-pages branch. This is useful for things like sites developed with Yeoman, or if you have a Jekyll site contained in the master branch alongside the rest of your code.

For the sake of this example, let’s pretend the subfolder containing your site is named dist.

Step 1

Remove the dist directory from the project’s .gitignore file (it’s ignored by default by Yeoman).

Step 2

Make sure git knows about your subtree (the subfolder with your site).

git add dist && git commit -m "Initial dist subtree commit"

Step 3

Use subtree push to send it to the gh-pages branch on GitHub.

git subtree push --prefix dist origin gh-pages

Boom. If your folder isn’t called dist, then you’ll need to change that in each of the commands above.


If you do this on a regular basis, you could also create a script containing the following somewhere in your path:

#!/bin/sh
if [ -z "$1" ]
then
  echo "Which folder do you want to deploy to GitHub Pages?"
  exit 1
fi
git subtree push --prefix $1 origin gh-pages

Which lets you type commands like:

git gh-deploy path/to/your/site
@mattr-

This comment has been minimized.

Show comment Hide comment
@mattr-

mattr- Apr 4, 2013

For the lazy, you can create an alias in ~/.gitconfig in the [alias] section, like so:

[alias]
    stp = subtree push

which would let you type git stp --prefix dist origin gh-pages

and if you want to be really lazy 😄

[alias]
    stpp = subtree push --prefix

which would let you type git stpp dist origin gh-pages

Boom. Shortcuts. 🤘

mattr- commented Apr 4, 2013

For the lazy, you can create an alias in ~/.gitconfig in the [alias] section, like so:

[alias]
    stp = subtree push

which would let you type git stp --prefix dist origin gh-pages

and if you want to be really lazy 😄

[alias]
    stpp = subtree push --prefix

which would let you type git stpp dist origin gh-pages

Boom. Shortcuts. 🤘

@cobyism

This comment has been minimized.

Show comment Hide comment
@cobyism

cobyism May 16, 2013

@mattr- Yep, I also have a script in my dotfiles for doing this:

#!/bin/sh
if [ -z "$1" ]
then
  echo "Which folder do you want to deploy to GitHub Pages?"
  exit 1
fi
git subtree push --prefix $1 origin gh-pages
Owner

cobyism commented May 16, 2013

@mattr- Yep, I also have a script in my dotfiles for doing this:

#!/bin/sh
if [ -z "$1" ]
then
  echo "Which folder do you want to deploy to GitHub Pages?"
  exit 1
fi
git subtree push --prefix $1 origin gh-pages
@parkr

This comment has been minimized.

Show comment Hide comment
@parkr

parkr Oct 2, 2013

If you keep a Jekyll site in your master branch in a subfolder, this is also incredibly helpful. Just push the Jekyll site up to gh-pages and GitHub Pages will do the rest:

git subtree push --prefix site/ origin gh-pages

@cobyism, why don't we do this for Jekyll itself?

parkr commented Oct 2, 2013

If you keep a Jekyll site in your master branch in a subfolder, this is also incredibly helpful. Just push the Jekyll site up to gh-pages and GitHub Pages will do the rest:

git subtree push --prefix site/ origin gh-pages

@cobyism, why don't we do this for Jekyll itself?

@parkr

This comment has been minimized.

Show comment Hide comment
@parkr

parkr Oct 9, 2013

No option to --force in this case.

parkr commented Oct 9, 2013

No option to --force in this case.

@robwierzbowski

This comment has been minimized.

Show comment Hide comment
@robwierzbowski

robwierzbowski Mar 4, 2014

If you're using Grunt I built a plugin for this exact use. https://github.com/robwierzbowski/grunt-build-control

If you're using Grunt I built a plugin for this exact use. https://github.com/robwierzbowski/grunt-build-control

@raine

This comment has been minimized.

Show comment Hide comment
@raine

raine Jun 10, 2014

This method isn't that nice since it forces you to keep generated files in project's source control.

Here's an alternative, https://github.com/X1011/git-directory-deploy

raine commented Jun 10, 2014

This method isn't that nice since it forces you to keep generated files in project's source control.

Here's an alternative, https://github.com/X1011/git-directory-deploy

@jegelstaff

This comment has been minimized.

Show comment Hide comment
@jegelstaff

jegelstaff Jul 11, 2014

I am trying to use this, but keep getting an error:

Updates were rejected because a pushed branch tip is behind its remote counterpart. Checkout this branch and integrate the remote changes.

However, this doesn't make any sense, because both master and gh-pages are up to date with the origin (github). gh-pages is "ahead" of master, it was created by github through their automatic creation tools, and so it diverged from master at that point, but it's an orphan of course, it will never match master. It's just a container for the contents of the github.io site.

We have a copy of the contents of gh-pages in a single folder in the master branch, and periodically, we want an easy way to push the contents of the that folder up to github to update the github.io site. This seems like it should be the answer, but the above error is a showstopper.

Thanks for any help anyone can provide!

--Julian

I am trying to use this, but keep getting an error:

Updates were rejected because a pushed branch tip is behind its remote counterpart. Checkout this branch and integrate the remote changes.

However, this doesn't make any sense, because both master and gh-pages are up to date with the origin (github). gh-pages is "ahead" of master, it was created by github through their automatic creation tools, and so it diverged from master at that point, but it's an orphan of course, it will never match master. It's just a container for the contents of the github.io site.

We have a copy of the contents of gh-pages in a single folder in the master branch, and periodically, we want an easy way to push the contents of the that folder up to github to update the github.io site. This seems like it should be the answer, but the above error is a showstopper.

Thanks for any help anyone can provide!

--Julian

@vences

This comment has been minimized.

Show comment Hide comment
@vences

vences Aug 7, 2014

hi,

They are a way to automatically deploy changement in the folder on the gh-pages.
Each times I change my directory dist I need to launch git subtree push --prefix dist origin gh-pages.
Any ideas ?

Thanks,

vences commented Aug 7, 2014

hi,

They are a way to automatically deploy changement in the folder on the gh-pages.
Each times I change my directory dist I need to launch git subtree push --prefix dist origin gh-pages.
Any ideas ?

Thanks,

@iakobos

This comment has been minimized.

Show comment Hide comment
@iakobos

iakobos Aug 13, 2014

@vences you could use a post-commit hook (See http://githooks.com/)

iakobos commented Aug 13, 2014

@vences you could use a post-commit hook (See http://githooks.com/)

@shankarmsy

This comment has been minimized.

Show comment Hide comment
@shankarmsy

shankarmsy Nov 24, 2014

This discussion thread was a life saver...thanks guys!!

On a side note, I deploy to my github user page (master not gh-pages). The one thing I realized was I needed to push to source first then subtree push the sub-directory to master. Otherwise it was throwing me a "Master is not an ancestor to commit" error.

Please correct if I am mis-stating.

This discussion thread was a life saver...thanks guys!!

On a side note, I deploy to my github user page (master not gh-pages). The one thing I realized was I needed to push to source first then subtree push the sub-directory to master. Otherwise it was throwing me a "Master is not an ancestor to commit" error.

Please correct if I am mis-stating.

@AllenSH12

This comment has been minimized.

Show comment Hide comment
@AllenSH12

AllenSH12 Jan 18, 2015

Thanks for the post, maybe someone else will also find the following command useful when trying to update gh-pages against a rebased master branch:

git push origin `git subtree split --prefix build_folder master`:gh-pages --force

(from http://stevenclontz.com/blog/2014/05/08/git-subtree-push-for-deployment/ and this question on SO)

Thanks for the post, maybe someone else will also find the following command useful when trying to update gh-pages against a rebased master branch:

git push origin `git subtree split --prefix build_folder master`:gh-pages --force

(from http://stevenclontz.com/blog/2014/05/08/git-subtree-push-for-deployment/ and this question on SO)

@cDima

This comment has been minimized.

Show comment Hide comment
@cDima

cDima Feb 16, 2015

This helped me out:

  1. git checkout master # you can avoid this line if you are in master...
  2. git subtree split --prefix dist -b gh-pages # create a local gh-pages branch containing the splitted output folder
  3. git push -f origin gh-pages:gh-pages # force the push of the gh-pages branch to the remote gh-pages branch at origin
  4. git branch -D gh-pages # delete the local gh-pages because you will need it: ref

from http://www.damian.oquanta.info/posts/one-line-deployment-of-your-site-to-gh-pages.html

cDima commented Feb 16, 2015

This helped me out:

  1. git checkout master # you can avoid this line if you are in master...
  2. git subtree split --prefix dist -b gh-pages # create a local gh-pages branch containing the splitted output folder
  3. git push -f origin gh-pages:gh-pages # force the push of the gh-pages branch to the remote gh-pages branch at origin
  4. git branch -D gh-pages # delete the local gh-pages because you will need it: ref

from http://www.damian.oquanta.info/posts/one-line-deployment-of-your-site-to-gh-pages.html

@dandv

This comment has been minimized.

Show comment Hide comment
@dandv

dandv Jun 4, 2015

Is there a way to have symlinks in the dist directory to files in directories outside of it? I've tried this with a .js included from dist/index.html via <script src="../script"> but that predictably didn't work.

My use case is a simple project with a .js in the root dir and without a build system that would copy the script from root to dist. Besides, I wouldn't want every commit to the script be mirrored in the dist copy of the script.

dandv commented Jun 4, 2015

Is there a way to have symlinks in the dist directory to files in directories outside of it? I've tried this with a .js included from dist/index.html via <script src="../script"> but that predictably didn't work.

My use case is a simple project with a .js in the root dir and without a build system that would copy the script from root to dist. Besides, I wouldn't want every commit to the script be mirrored in the dist copy of the script.

@edsu

This comment has been minimized.

Show comment Hide comment
@edsu

edsu Jul 28, 2015

Very helpful, thanks!

edsu commented Jul 28, 2015

Very helpful, thanks!

@fewspider

This comment has been minimized.

Show comment Hide comment
@fewspider

fewspider Aug 15, 2015

thanks

thanks

@JacopKane

This comment has been minimized.

Show comment Hide comment
@JacopKane

JacopKane Aug 19, 2015

Helped a lot thanks for sharing.

Now I'm trying to find a way without indexing dist folder, it's ugly to see minified/duplicate files in master branch.

Also found this gulp plugin for this purpose
https://github.com/shinnn/gulp-gh-pages

Helped a lot thanks for sharing.

Now I'm trying to find a way without indexing dist folder, it's ugly to see minified/duplicate files in master branch.

Also found this gulp plugin for this purpose
https://github.com/shinnn/gulp-gh-pages

@BlueRaja

This comment has been minimized.

Show comment Hide comment
@BlueRaja

BlueRaja Aug 20, 2015

Another option is to use a submodule. This has the advantage of not keeping the documentation in two separate places (which might become out of sync)

Another option is to use a submodule. This has the advantage of not keeping the documentation in two separate places (which might become out of sync)

@M3kH

This comment has been minimized.

Show comment Hide comment
@M3kH

M3kH Nov 29, 2015

I add this to my Makefile. 👍

M3kH commented Nov 29, 2015

I add this to my Makefile. 👍

@kaytwo

This comment has been minimized.

Show comment Hide comment
@kaytwo

kaytwo Jan 19, 2016

If you want to immediately push to gh-pages as soon as you've committed updates to the website, you can try this: (replace site with your own specific subdirectory)

#!/bin/bash

# if anything in the site/ subdirectory changed in the prior commit,
# push that directory to gh-pages for auto generation.
git diff-tree -r --name-only --no-commit-id master | grep '^site/' &> /dev/null
if [ $? == 0 ]; then
  git push origin `git subtree split --prefix site master 2> /dev/null`:gh-pages --force
fi

kaytwo commented Jan 19, 2016

If you want to immediately push to gh-pages as soon as you've committed updates to the website, you can try this: (replace site with your own specific subdirectory)

#!/bin/bash

# if anything in the site/ subdirectory changed in the prior commit,
# push that directory to gh-pages for auto generation.
git diff-tree -r --name-only --no-commit-id master | grep '^site/' &> /dev/null
if [ $? == 0 ]; then
  git push origin `git subtree split --prefix site master 2> /dev/null`:gh-pages --force
fi
@luckytianyiyan

This comment has been minimized.

Show comment Hide comment
@luckytianyiyan

luckytianyiyan Feb 20, 2016

Very helpful, thanks!👍
I use Jekyll to generate website.GitHub Page does not support local plugins, because this problem has been bugging me for days. 💢

Very helpful, thanks!👍
I use Jekyll to generate website.GitHub Page does not support local plugins, because this problem has been bugging me for days. 💢

@warpling

This comment has been minimized.

Show comment Hide comment
@warpling

warpling Feb 22, 2016

EXACTLY what I was looking for. Thank you!

EXACTLY what I was looking for. Thank you!

@thinkingmedia

This comment has been minimized.

Show comment Hide comment
@thinkingmedia

thinkingmedia Feb 27, 2016

This is what I did for my grunt task.

    grunt.task.registerTask('push-pages', function(){
       var shell = require('shelljs');
        shell.exec('git subtree split --prefix docs -b gh-pages');
        shell.exec('git push -f origin gh-pages:gh-pages');
        shell.exec('git branch -D gh-pages')
    });

I generate ngDocs in the subfolder docs and keep that in the master. Lets me view changes locally and when I release an update I just grunt push-pages to update the GitHub website.

This is what I did for my grunt task.

    grunt.task.registerTask('push-pages', function(){
       var shell = require('shelljs');
        shell.exec('git subtree split --prefix docs -b gh-pages');
        shell.exec('git push -f origin gh-pages:gh-pages');
        shell.exec('git branch -D gh-pages')
    });

I generate ngDocs in the subfolder docs and keep that in the master. Lets me view changes locally and when I release an update I just grunt push-pages to update the GitHub website.

@philmerrell

This comment has been minimized.

Show comment Hide comment
@philmerrell

philmerrell Mar 5, 2016

I added this as a script to run in package.json. For example:

{
    "name": "Example App",
    "dependencies": { ... },
    "scripts": {
        "deploy": "git subtree push --prefix subfolder-name-here origin gh-pages"
    }
}

Then you just run npm run deploy

Bam! 💥 deployed.

I added this as a script to run in package.json. For example:

{
    "name": "Example App",
    "dependencies": { ... },
    "scripts": {
        "deploy": "git subtree push --prefix subfolder-name-here origin gh-pages"
    }
}

Then you just run npm run deploy

Bam! 💥 deployed.

@brod-ie

This comment has been minimized.

Show comment Hide comment
@brod-ie

brod-ie Mar 10, 2016

@philmerrell Nice!

@brod-ie

This comment has been minimized.

Show comment Hide comment
@brod-ie

brod-ie Mar 12, 2016

I'm using this technique but don't want to keep the dist folder in my main repo. How can I ignore it on one branch but not in the other?

Aka if I add dist to .gitignore on master when I attempt a subtree push to gh-pages it fails with Everything up to date.

brod-ie commented Mar 12, 2016

I'm using this technique but don't want to keep the dist folder in my main repo. How can I ignore it on one branch but not in the other?

Aka if I add dist to .gitignore on master when I attempt a subtree push to gh-pages it fails with Everything up to date.

@chuyik

This comment has been minimized.

Show comment Hide comment
@chuyik

chuyik Mar 15, 2016

@brod-ie Seems like the subtree approach could not work as you want, meaning you need to keep track of the dist folder in master branch.
But you can try https://github.com/X1011/git-directory-deploy, simply wget the script and run it via npm, it's also cool.

chuyik commented Mar 15, 2016

@brod-ie Seems like the subtree approach could not work as you want, meaning you need to keep track of the dist folder in master branch.
But you can try https://github.com/X1011/git-directory-deploy, simply wget the script and run it via npm, it's also cool.

@drizzt

This comment has been minimized.

Show comment Hide comment
@drizzt

drizzt May 4, 2016

Quote!

drizzt commented May 4, 2016

Quote!

@jimafisk

This comment has been minimized.

Show comment Hide comment
@jimafisk

jimafisk May 5, 2016

Thanks for the guide @cobyism! I used this to create a pre-push git hook to make deploying to gh-pages using Jekyll easy: https://github.com/jimafisk/gh-pages_deploy. Thanks @AllenSH12 for providing a format that allows passing --no-verify to avoid the having the hook call itself recursively.

jimafisk commented May 5, 2016

Thanks for the guide @cobyism! I used this to create a pre-push git hook to make deploying to gh-pages using Jekyll easy: https://github.com/jimafisk/gh-pages_deploy. Thanks @AllenSH12 for providing a format that allows passing --no-verify to avoid the having the hook call itself recursively.

@JimTheMan

This comment has been minimized.

Show comment Hide comment
@JimTheMan

JimTheMan May 9, 2016

Original post doesn't work for me because my gh-pages branch contains the dist/ folder with all the files in it when I really need all the files in the root level of the gh-pages branch...

Original post doesn't work for me because my gh-pages branch contains the dist/ folder with all the files in it when I really need all the files in the root level of the gh-pages branch...

@yellownoggin

This comment has been minimized.

Show comment Hide comment
@yellownoggin

yellownoggin May 22, 2016

@JimTheMan did you use the option --prefix . Overall it worked for me. I thought the prefix option was the reason. Can't find any clear documentation on that reason why I'm unsure seems to be used in unix in general.

yellownoggin commented May 22, 2016

@JimTheMan did you use the option --prefix . Overall it worked for me. I thought the prefix option was the reason. Can't find any clear documentation on that reason why I'm unsure seems to be used in unix in general.

@guidobouman

This comment has been minimized.

Show comment Hide comment
@guidobouman

guidobouman Jun 14, 2016

People, why such a hard approach?

You can just check-out your gh-pages branch in the dist/ subfolder and keep that folder in the gitignore to keep your history clean.

If you have an existing gh-pages branch:

git clone git@github.com:q42/blink-ct.git --branch gh-pages dist

Then add the following to the scripts section of you package.json:

{
  ...
  "scripts": {
    ...
    "clean": "rm -rf dist/*",
    "release": "npm run clean && npm run build",
    "deploy": "cd dist && git add --all && git commit -m \"Release at $(date)\" && git push"
  },
  ...
}

where npm run build is your build script. This could be Gulp, Grunt or Webpack, whatever you prefer.

People, why such a hard approach?

You can just check-out your gh-pages branch in the dist/ subfolder and keep that folder in the gitignore to keep your history clean.

If you have an existing gh-pages branch:

git clone git@github.com:q42/blink-ct.git --branch gh-pages dist

Then add the following to the scripts section of you package.json:

{
  ...
  "scripts": {
    ...
    "clean": "rm -rf dist/*",
    "release": "npm run clean && npm run build",
    "deploy": "cd dist && git add --all && git commit -m \"Release at $(date)\" && git push"
  },
  ...
}

where npm run build is your build script. This could be Gulp, Grunt or Webpack, whatever you prefer.

@rtsao

This comment has been minimized.

Show comment Hide comment
@codazoda

This comment has been minimized.

Show comment Hide comment
@codazoda

codazoda Jun 27, 2016

Another option I like is to create the master and gh-pages branches as usual and then checkout the gh-pages branch into the ./gh-pages directory. Then you add gh-pages to the .gitignore on the master branch so that you have your master branch in the root and your gh-pages branch in the ./gh-pages directory. Both are checked out at the same time so that you don't have to flip back and forth but they are still contained in a single github repo. I got the idea from the instructions below.

https://gist.github.com/chrisjacob/833223

Another option I like is to create the master and gh-pages branches as usual and then checkout the gh-pages branch into the ./gh-pages directory. Then you add gh-pages to the .gitignore on the master branch so that you have your master branch in the root and your gh-pages branch in the ./gh-pages directory. Both are checked out at the same time so that you don't have to flip back and forth but they are still contained in a single github repo. I got the idea from the instructions below.

https://gist.github.com/chrisjacob/833223

@daniloprates

This comment has been minimized.

Show comment Hide comment
@daniloprates

daniloprates Jul 5, 2016

I keep getting this message. I've done pull, push, fetch and all sort of things. any clues?

screen shot 2016-07-05 at 8 01 52 am

I keep getting this message. I've done pull, push, fetch and all sort of things. any clues?

screen shot 2016-07-05 at 8 01 52 am

@e-nichols

This comment has been minimized.

Show comment Hide comment
@e-nichols

e-nichols Jul 15, 2016

AllenSH12 that did the trick for me! Thank you.

AllenSH12 that did the trick for me! Thank you.

@stepquick

This comment has been minimized.

Show comment Hide comment
@stepquick

stepquick Aug 1, 2016

@daniloprates, it's saying your remote gh-pages branch is ahead of your local gh-pages branch. I had to destroy my remote gh-pages completely to get it submit properly.

@daniloprates, it's saying your remote gh-pages branch is ahead of your local gh-pages branch. I had to destroy my remote gh-pages completely to get it submit properly.

@mikeyhogarth

This comment has been minimized.

Show comment Hide comment
@mikeyhogarth

mikeyhogarth Aug 17, 2016

This has been working out for me;

"scripts": {
  ...
  "deploy-demo": "git push origin :gh-pages && git subtree push --prefix dist origin gh-pages"
}

deletes the branch and re-pushes. Avoids all that remote branch being ahead fluff that others are mentioning.

This has been working out for me;

"scripts": {
  ...
  "deploy-demo": "git push origin :gh-pages && git subtree push --prefix dist origin gh-pages"
}

deletes the branch and re-pushes. Avoids all that remote branch being ahead fluff that others are mentioning.

@marcamillion

This comment has been minimized.

Show comment Hide comment
@marcamillion

marcamillion Aug 27, 2016

What about in the case where you want to push to a subdirectory within your existing gh-pages repo? How do I do that?

For instance, I have a static site hosted on GH-pages, but I would like to add a blog powered by Middleman to my existing static site. I have the blog built, but when I deploy it keeps overwriting the entire gh-pages branch, when all I want it to do is to deploy to the blog/ subfolder within my gh-pages branch.

I was using middleman-deploy but it doesn't allow a subdirectory on the git deploy method.

Thoughts on how I can achieve that?

What about in the case where you want to push to a subdirectory within your existing gh-pages repo? How do I do that?

For instance, I have a static site hosted on GH-pages, but I would like to add a blog powered by Middleman to my existing static site. I have the blog built, but when I deploy it keeps overwriting the entire gh-pages branch, when all I want it to do is to deploy to the blog/ subfolder within my gh-pages branch.

I was using middleman-deploy but it doesn't allow a subdirectory on the git deploy method.

Thoughts on how I can achieve that?

@mattspaulding

This comment has been minimized.

Show comment Hide comment
@mattspaulding

mattspaulding Aug 31, 2016

Super easy using gulp:

Terminal:
npm install --save-dev gulp-gh-pages

Then in your gulpfile.js:

var gulp = require('gulp');
var ghPages = require('gulp-gh-pages');

gulp.task('deploy', function() {
  return gulp.src('./dist/**/*')
    .pipe(ghPages());
});

Any time you want to publish to gh-pages:

gulp deploy

Super easy using gulp:

Terminal:
npm install --save-dev gulp-gh-pages

Then in your gulpfile.js:

var gulp = require('gulp');
var ghPages = require('gulp-gh-pages');

gulp.task('deploy', function() {
  return gulp.src('./dist/**/*')
    .pipe(ghPages());
});

Any time you want to publish to gh-pages:

gulp deploy

@finom

This comment has been minimized.

Show comment Hide comment
@finom

finom Sep 13, 2016

Check out deploy-to-git.

finom commented Sep 13, 2016

Check out deploy-to-git.

@laszlourszuly

This comment has been minimized.

Show comment Hide comment
@laszlourszuly

laszlourszuly Nov 16, 2016

@AllenSH12 The risk with your suggestion is that the git subtree split ... command may fail and thereby return "nothing", ultimately causing your outer gitcommand to look like: git push origin :gh-pages --force, which also happens to be the command for forcefully deleting the remote gh-pages branch.

You know what I mean if you have ever done a too hasty rm -rf * :-)

@AllenSH12 The risk with your suggestion is that the git subtree split ... command may fail and thereby return "nothing", ultimately causing your outer gitcommand to look like: git push origin :gh-pages --force, which also happens to be the command for forcefully deleting the remote gh-pages branch.

You know what I mean if you have ever done a too hasty rm -rf * :-)

@goldylucks

This comment has been minimized.

Show comment Hide comment
@goldylucks

goldylucks Nov 22, 2016

I'm using a similar approach that does NOT check dist folder to source control:

#!/bin/bash
set -e # stop on error

echo bulid client ...
npm run build:client
echo check out branch gh-pages ...
git checkout -b gh-pages
echo add client-dist folder
git add -f client-dist
echo commit changes
git commit -m "deploy to gh-pages"
echo push to remote gh-pages
git push origin `git subtree split --prefix client-dist`:gh-pages --force
echo checkout branch master
git checkout master
echo delete branch gh-pages
git branch -D gh-pages
echo All done!

I can wrap it into an NPM package for ease of use if anyone is interested :)

so far it works on one of my proejcts

goldylucks commented Nov 22, 2016

I'm using a similar approach that does NOT check dist folder to source control:

#!/bin/bash
set -e # stop on error

echo bulid client ...
npm run build:client
echo check out branch gh-pages ...
git checkout -b gh-pages
echo add client-dist folder
git add -f client-dist
echo commit changes
git commit -m "deploy to gh-pages"
echo push to remote gh-pages
git push origin `git subtree split --prefix client-dist`:gh-pages --force
echo checkout branch master
git checkout master
echo delete branch gh-pages
git branch -D gh-pages
echo All done!

I can wrap it into an NPM package for ease of use if anyone is interested :)

so far it works on one of my proejcts

@thislooksfun

This comment has been minimized.

Show comment Hide comment
@thislooksfun

thislooksfun Dec 1, 2016

This is now built in, as of Aug. 17, 2016. https://github.com/blog/2228-simpler-github-pages-publishing

This is now built in, as of Aug. 17, 2016. https://github.com/blog/2228-simpler-github-pages-publishing

@wangpin34

This comment has been minimized.

Show comment Hide comment
@wangpin34

wangpin34 Dec 5, 2016

Thank you all. That's really helpful.

Thank you all. That's really helpful.

@gunnarmorling

This comment has been minimized.

Show comment Hide comment
@gunnarmorling

gunnarmorling Jan 3, 2017

I'm using this approach (based on @guidobouman's advice above, but's using a local clone instead of remote):

# remove previous publication
rm -rf dist
mkdir dist

# clone gh-pages branch from the local repo into a repo located within "dist"
git clone .git --branch gh-pages dist

# generate contents...    

# commit the changes in the clone and push them back to the local gh-pages branch    
cd dist && git add --all && git commit -m "Publishing to gh-pages" && git push origin gh-pages

# publish
git push upstream gh-pages

If you are on git 2.5 or later, the same may be achieved using the new worktree feature.

I'm using this approach (based on @guidobouman's advice above, but's using a local clone instead of remote):

# remove previous publication
rm -rf dist
mkdir dist

# clone gh-pages branch from the local repo into a repo located within "dist"
git clone .git --branch gh-pages dist

# generate contents...    

# commit the changes in the clone and push them back to the local gh-pages branch    
cd dist && git add --all && git commit -m "Publishing to gh-pages" && git push origin gh-pages

# publish
git push upstream gh-pages

If you are on git 2.5 or later, the same may be achieved using the new worktree feature.

@astericky

This comment has been minimized.

Show comment Hide comment
@astericky

astericky Jan 16, 2017

I need to thank you for this. I have been looking for this solution for quite sometime. Apparently, I starred this some years ago and didn't realize it actually works. Saturday was the first time I tried this out for some unknown reason. In any case, thanks again.

I need to thank you for this. I have been looking for this solution for quite sometime. Apparently, I starred this some years ago and didn't realize it actually works. Saturday was the first time I tried this out for some unknown reason. In any case, thanks again.

@lbineau

This comment has been minimized.

Show comment Hide comment
@lbineau

lbineau Feb 13, 2017

Really easy to use gh-pages npm package
https://www.npmjs.com/package/gh-pages
It creates a clone of your repo in order not to commit builded files in yours so your history remains clean 👍

lbineau commented Feb 13, 2017

Really easy to use gh-pages npm package
https://www.npmjs.com/package/gh-pages
It creates a clone of your repo in order not to commit builded files in yours so your history remains clean 👍

@lukehler

This comment has been minimized.

Show comment Hide comment
@lukehler

lukehler Feb 14, 2017

For user and organizational pages (in which the visible branch is master instead of gh-pages), I ran into the same issue as @daniloprates and managed to get around it by...

  1. In the repo's Settings / Branches, making my src branch the Default Branch
  2. With the src branch checked out, deleting the master branch with git push origin :master
  3. Creating a new master branch with git subtree push --prefix dest origin master
  4. Resetting the master branch as the Default Branch in the repo's Settings.

For user and organizational pages (in which the visible branch is master instead of gh-pages), I ran into the same issue as @daniloprates and managed to get around it by...

  1. In the repo's Settings / Branches, making my src branch the Default Branch
  2. With the src branch checked out, deleting the master branch with git push origin :master
  3. Creating a new master branch with git subtree push --prefix dest origin master
  4. Resetting the master branch as the Default Branch in the repo's Settings.
@vhbsouza

This comment has been minimized.

Show comment Hide comment
@vhbsouza

vhbsouza Mar 27, 2017

@lukehler, but after doing what you suggets.. how can I update my forked repository?
Because now my forked source code isn't on master branch anymore, it's now on src.

Any suggestion on how to manage that?

@lukehler, but after doing what you suggets.. how can I update my forked repository?
Because now my forked source code isn't on master branch anymore, it's now on src.

Any suggestion on how to manage that?

@kostia-lev

This comment has been minimized.

Show comment Hide comment
@kostia-lev

kostia-lev Apr 23, 2017

I did it, and my github.io still points to master branch :-(

I did it, and my github.io still points to master branch :-(

@bdjunayed

This comment has been minimized.

Show comment Hide comment
@bdjunayed

bdjunayed May 3, 2017

I did it! with a git supported dumb host, just pointing the domain to the dest folder.

I did it! with a git supported dumb host, just pointing the domain to the dest folder.

@lukehler

This comment has been minimized.

Show comment Hide comment
@lukehler

lukehler May 6, 2017

@vhbsouza and @kostia-lev: About a month or two late, but I just checked in and noticed the last couple of comments. Apologies.

In my case...

  • I've got all my build scripts in the src branch.
  • When I change the source files, I update, commit, and push the src branch.
  • I then, with the src branch still checked out, manually push the subtree into the master branch with git subtree push --prefix dest origin master (I added a line to my package.json to make an NPM build script to run that command, so I just use npm run deploy as an alias).

That lets you update, maintain, and track the source files in the src branch and the master branch is just a clone of the dest folder. I basically only ever use src as my "master" and populate the actual master branch exclusively with the subtree.

I hope that helps.

lukehler commented May 6, 2017

@vhbsouza and @kostia-lev: About a month or two late, but I just checked in and noticed the last couple of comments. Apologies.

In my case...

  • I've got all my build scripts in the src branch.
  • When I change the source files, I update, commit, and push the src branch.
  • I then, with the src branch still checked out, manually push the subtree into the master branch with git subtree push --prefix dest origin master (I added a line to my package.json to make an NPM build script to run that command, so I just use npm run deploy as an alias).

That lets you update, maintain, and track the source files in the src branch and the master branch is just a clone of the dest folder. I basically only ever use src as my "master" and populate the actual master branch exclusively with the subtree.

I hope that helps.

@kreedz

This comment has been minimized.

Show comment Hide comment
@kreedz

kreedz Jun 25, 2017

On which branch should be performed step 1 and step 2? It doesn't mentioned in any way.
I did it at master branch, because at gh-pages it caused errors.

But I have a problem with that.
Now at gh-pages in the root directory I have index.html file.
And I get 404 when trying to follow kreedz.github.io/Test.
But this kreedz.github.io/Test/index.html works.

Earlier it worked well without git subtree push when I did it with git merge master at gh-pages branch.

kreedz commented Jun 25, 2017

On which branch should be performed step 1 and step 2? It doesn't mentioned in any way.
I did it at master branch, because at gh-pages it caused errors.

But I have a problem with that.
Now at gh-pages in the root directory I have index.html file.
And I get 404 when trying to follow kreedz.github.io/Test.
But this kreedz.github.io/Test/index.html works.

Earlier it worked well without git subtree push when I did it with git merge master at gh-pages branch.

@mac-s-g

This comment has been minimized.

Show comment Hide comment
@mac-s-g

mac-s-g Nov 11, 2017

@kreedz same thing happened to me at first.

regarding your first question, you should be running those commands from master.

regarding the 404:
--this is only applicable if serving from a custom domain--
I was missing my CNAME record. make sure you're copying that into your /dist/ directory so that gh-pages has the dns config necessary to serve your site with only the files in that dir.

mac-s-g commented Nov 11, 2017

@kreedz same thing happened to me at first.

regarding your first question, you should be running those commands from master.

regarding the 404:
--this is only applicable if serving from a custom domain--
I was missing my CNAME record. make sure you're copying that into your /dist/ directory so that gh-pages has the dns config necessary to serve your site with only the files in that dir.

@musteresel

This comment has been minimized.

Show comment Hide comment
@musteresel

musteresel Jan 31, 2018

I think I found a better solution:

# 1. Set up a worktree in directory dist checked out on branch gh-pages
git worktree add dist gh-pages
# 2. Build whatever needs to be in dist however you like
# 3. Add everything in dist
(cd dist; git add .)
# 4. Commit, with some nice message to link to sources commit
(cd dist; git commit -m "Build output as of $(git log '--format=format:%H' master -1)"
# 5. Push
git push origin gh-pages
  • No duplicate repositories (no space waste, duplicate configurations, ...)
  • No build files in source tree (source branch)
  • Versioned builds (rollback made easy)

I think I found a better solution:

# 1. Set up a worktree in directory dist checked out on branch gh-pages
git worktree add dist gh-pages
# 2. Build whatever needs to be in dist however you like
# 3. Add everything in dist
(cd dist; git add .)
# 4. Commit, with some nice message to link to sources commit
(cd dist; git commit -m "Build output as of $(git log '--format=format:%H' master -1)"
# 5. Push
git push origin gh-pages
  • No duplicate repositories (no space waste, duplicate configurations, ...)
  • No build files in source tree (source branch)
  • Versioned builds (rollback made easy)
@maciejmyslinski

This comment has been minimized.

Show comment Hide comment
@maciejmyslinski

maciejmyslinski Feb 21, 2018

@musteresel this is great!

@musteresel this is great!

@js2me

This comment has been minimized.

Show comment Hide comment
@js2me

js2me Feb 22, 2018

@musteresel please add closed ) to this line:

(cd dist; git commit -m "Build output as of $(git log '--format=format:%H' master -1)"

js2me commented Feb 22, 2018

@musteresel please add closed ) to this line:

(cd dist; git commit -m "Build output as of $(git log '--format=format:%H' master -1)"
@sukima

This comment has been minimized.

Show comment Hide comment
@sukima

sukima Mar 9, 2018

@gunnarmorling solution was about 10000 times easier! To elaborate for git >2.5 (worktree)

Setup

$ rm -rf dist
$ echo "dist/" >> .gitignore
$ git worktree add dist gh-pages

Making changes

$ make # or what ever you run to populate dist
$ cd dist
$ git add --all
$ git commit -m "Deploy to gh-pages"
$ git push origin gh-pages
$ cd ..

Notes

git worktree feature has its own garbage collection so if dist is deleted it will not affect much and can be recreated as needed. If you want it to go away you can use git worktree prune See man pages on it.

Makefile

To make this stream line the following Makefile can be used to automate this process:

.PHONY: all deploy clean

all: dist dist/index.html

dist:
	git worktree add dist gh-pages

# Replace this rule with whatever builds your project
dist/index.html: src/index.html
	cp $< $@

deploy: all
	cd dist && \
	git add --all && \
	git commit -m "Deploy to gh-pages" && \
	git push origin gh-pages

# Removing the actual dist directory confuses git and will require a git worktree prune to fix
clean:
	rm -rf dist/*

sukima commented Mar 9, 2018

@gunnarmorling solution was about 10000 times easier! To elaborate for git >2.5 (worktree)

Setup

$ rm -rf dist
$ echo "dist/" >> .gitignore
$ git worktree add dist gh-pages

Making changes

$ make # or what ever you run to populate dist
$ cd dist
$ git add --all
$ git commit -m "Deploy to gh-pages"
$ git push origin gh-pages
$ cd ..

Notes

git worktree feature has its own garbage collection so if dist is deleted it will not affect much and can be recreated as needed. If you want it to go away you can use git worktree prune See man pages on it.

Makefile

To make this stream line the following Makefile can be used to automate this process:

.PHONY: all deploy clean

all: dist dist/index.html

dist:
	git worktree add dist gh-pages

# Replace this rule with whatever builds your project
dist/index.html: src/index.html
	cp $< $@

deploy: all
	cd dist && \
	git add --all && \
	git commit -m "Deploy to gh-pages" && \
	git push origin gh-pages

# Removing the actual dist directory confuses git and will require a git worktree prune to fix
clean:
	rm -rf dist/*
@manugarg

This comment has been minimized.

Show comment Hide comment
@manugarg

manugarg Mar 29, 2018

@sukima Much thanks for this. This worked very well for me.

@sukima Much thanks for this. This worked very well for me.

@rhyolight

This comment has been minimized.

Show comment Hide comment
@rhyolight

rhyolight Apr 5, 2018

This is so much easier than what I've been doing, thanks.

This is so much easier than what I've been doing, thanks.

@burrich

This comment has been minimized.

Show comment Hide comment
@burrich

burrich Apr 10, 2018

The git worktree solution is perfect, thanks guys.

burrich commented Apr 10, 2018

The git worktree solution is perfect, thanks guys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment