How do I force a subtree push to overwrite remote

2020-05-15 12:41发布

问题:

We use a subtree deployment a lá this Gist to deploy a subdirectory of our Yeoman project. In our case, the branch is called production, not gh-pages.

This worked perfectly until yesterday when the Git server rejected the command git subtree push --prefix dist origin production, saying

 ! [rejected]        9fe1683aa574eae33ee6754aad702488e0bd37df -> production (non-fast-forward)
error: failed to push some refs to 'git@gitlab.sdstate.edu:web-and-new-media/graduation2015.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart.

If I switch to the production branch locally (which is clean), git pull returns Your branch is up-to-date with 'origin/production'. even if I use the --rebase option.

I can see the contents of the production branch on the server through our web UI and there's nothing there that shouldn't be, just the compiled output of our dist directory like I'd expect.

To that end, it seems like I should safely be able to force an overwrite of these files, but how? git subtree push doesn't have a --force option.

回答1:

The trick was to chain the subtree split into a forced push:

git push origin `git subtree split --prefix dist master`:production --force

I got this from the Addendum of http://clontz.org/blog/2014/05/08/git-subtree-push-for-deployment/, who actually references this answer on Stack Overflow. I had skimmed this one earlier but Steve Clontz's post made it click for me.



回答2:

There is simpler solution

This always works for me.

  1. Set up a bash script which helps you do the following:
cd dist
git init
git add .
git commit -am "deploy"
git push --force <remote URL> master
rm -rf .git
cd ..

This creates a new git repository in the subdirectory you specify and force pushes everything from there.

  1. profit


回答3:

There is actually a solution that is much more simple.

Source: https://gist.github.com/cobyism/4730490#gistcomment-2337463

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 "$(git log '--format=format:%H' master -1)"
$ git push origin production --force
$ cd ..