11

I am currently working on a project and using machines in two different locations to do it. I have created a branch for the feature I am working on and when I finish some work on it I amend my commit to that branch and push it to the server so I can pick up where I left off on my other machine.

When I try to send my amended commit it rejects my push. I assume this is because I am pushing up a commit that is intended to clobber the current HEAD of the feature branch. I typically just use --force.

Is there a better way to do this?

mike@sleepycat:~/projects/myproject$ git pull origin topx
From heroku.com:myproject
 * branch            topx       -> FETCH_HEAD
Already up-to-date.
mike@sleepycat:~/projects/myproject$ git add app/models/reward.rb
mike@sleepycat:~/projects/myproject$ git commit --amend
[topx 82a9880] Added topX reward
 9 files changed, 106 insertions(+), 21 deletions(-)
 rewrite app/views/ceo/_reward_criteria.html.erb (96%)
 create mode 100644 public/javascripts/jquery.multiselect.min.js
 create mode 100644 public/site/javascripts/jquery.multiselect.min.js
 create mode 100644 public/stylesheets/jquery.multiselect.css
mike@sleepycat:~/projects/myproject$ git push origin topx
To git@heroku.com:myproject.git
 ! [rejected]        topx -> topx (non-fast-forward)
error: failed to push some refs to 'git@heroku.com:myproject.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.
mikewilliamson
  • 24,303
  • 17
  • 59
  • 90

2 Answers2

19

There is no way to overwrite remote branch without --force in this case. You have 2 options:

  • continue to use git push --force
  • don't use --amend. If some work you've done deserves a separate commit (is stable enough, compiling, passing more tests, etc...), create new commit. If not, create temporary branch (something like my-feature-unstable if your branch is my-feature) and commit there. When it becomes stable again, you can do git reset --soft my-feature, checkout my-feature and commit to create single commit in your branch from several unfinished commits. After that, temporary branch can be deleted.
max
  • 33,369
  • 7
  • 73
  • 84
  • 7
    I'd qualify the "don't use amend" option: don't use it on published work. On unpublished work (local/personal branches) you should absolutely use it. (And if you have more than one personal repo, that does mean you'll use `push --force` to transfer your work around sometimes. That's fine.) – Cascabel Oct 19 '10 at 13:20
  • Thanks a lot for that! Now I can keep my code safe and the commit logs clean. – Rafael Merlin Oct 13 '15 at 13:11
3

There is a better way, the option --force-with-lease

 git push --force-with-lease

It will only force the update if nobody has pushed after you, or if you haven't pushed on another machine;. If you got a rejection you will then fetch/rebase before pushing again, so working in a more secure way.

From the documentation

--force-with-lease alone, without specifying the details, will protect all remote refs that are going to be updated by requiring their current value to be the same as the remote-tracking branch we have for them.

pdem
  • 3,880
  • 1
  • 24
  • 38