One-click GitHub Pages deployer
Replace the contents of a remote git branch (like gh-pages) with the contents of a local directory
in one command.
gh-pages is
complicated,
buggy, and
unmaintained; oneclickpush is
none of these, has zero dependencies and only uses built-in Node APIs + git.
Deploy your build directory (e.g. dist) to the gh-pages branch:
$ npx oneclickpush dist
Usage: oneclickpush <dir> [options]
Replace the contents of a remote git branch with that of a local directory.
Arguments:
dir Directory to deploy (required)
Options:
-e, --exclude <glob> Paths to leave out, relative to dir (default: "**/.DS_Store")
-b, --branch <name> Target branch (default: "gh-pages")
-m, --message <msg> Commit message (default: "Updates")
-r, --remote <name|url> Remote name or repo URL to deploy to (default: "origin")
-a, --author <author> Commit author, as "Name <email>"
-f, --force Force push new commit with no history
-n, --dry-run Show what would change, without committing or pushing
-l, --log-level <level> Output: silent, normal or verbose (default: "normal")
-V, --version Print version
-h, --help Show this help
Tip
--exclude takes glob patterns (*, **, ?) and can be repeated. Patterns are matched against
the full path, so use **/name to match at any depth.
| Level | Behavior |
|---|---|
silent |
Prints nothing, not even errors. Check the exit code instead. |
normal |
Prints the result and error messages (plus a spinner in a terminal). |
verbose |
Also logs every git command to stderr and prints full errors. |
Warning
If your remote URL contains a token (e.g. https://user:TOKEN@github.com/o/r.git), git error
messages shown at normal and verbose may include it. Use -l silent in CI, or keep tokens out
of the URL with a credential helper.
# Preview what would be deployed without pushing
npx oneclickpush build --dry-run
# Custom branch and commit message
npx oneclickpush public -b release -m "deploy: v1.0.0"
# Exclude source maps and test files
npx oneclickpush dist -e "**/*.map" -e "**/tests/**"
# Deploy to a different remote or repository URL
npx oneclickpush dist -r upstream
npx oneclickpush dist -r git@github.com:user/repo.git
# Set commit author (useful in CI environments)
npx oneclickpush dist -a "Deploy Bot <bot@example.com>"
# Force push fresh history
npx oneclickpush dist --force
# Silent output (useful in CI, check the exit code)
npx oneclickpush dist -l silent
# Log every git command
npx oneclickpush dist -l verboseYou can also use oneclickpush as an ES module:
# Install
npm i oneclickpushimport { deploy } from 'oneclickpush'
const changes = await deploy({
dir: 'dist',
exclude: ['**/.DS_Store', '**/*.map'],
branch: 'gh-pages',
message: 'Deploy updates',
remote: 'origin',
author: 'Deploy Bot <bot@example.com>',
force: false,
dryRun: false,
verbose: false
})
if (changes) {
console.log('Deployed changes:\n' + changes)
} else {
console.log('Nothing to deploy')
}| Name | Type | Default | Description |
|---|---|---|---|
dir |
string |
- (required) | Directory to deploy |
exclude |
string[] |
["**/.DS_Store"] |
Paths to exclude relative to dir |
branch |
string |
"gh-pages" |
Target git branch |
message |
string |
"Updates" |
Git commit message |
remote |
string |
"origin" |
Remote name or repository URL/path to deploy to |
author |
string |
- | Commit author and committer, as "Name <email>" |
force |
boolean |
false |
Force push fresh commit with no previous history |
dryRun |
boolean |
false |
Return staged changes without committing or pushing |
verbose |
boolean |
false |
Logs git commands to stderr |
- Resolves the target repository URL from git remote configuration or uses the provided remote URL/path directly.
- Creates an isolated temporary directory and fetches the target branch (or initializes it if it doesn't exist).
- Clears the target branch index and stages the contents of
dir(minusexcludepatterns) directly via Gitwork-tree. - Checks for differences (
git diff --cached --name-status). If there are changes, commits and pushes back to the remote repository. - Cleans up the temporary directory.
Warning
Requires Node 18.3+ and Git 2.28+.
- The target branch is fully replaced with the contents of
dir(WYSIWYG), and it's created if it doesn't exist yet. If you need files like.nojekyllorCNAME, put them indir, adding a post-build step if your build tool wipes the directory. - Dotfiles are included by default, except
.DS_Store. Use-eto exclude more, but note that it replaces the default list, so repeat-e "**/.DS_Store"if you still want that file excluded. - When
--remoteis a repository URL or path, you don't need to run from inside a git repository. - In dry-run output, identical content moved to a new path appears as a rename (
R100). - A directory starting with
-must come after--, e.g.oneclickpush -- -weird-dir.
ISC