1

I am trying to push an amended commit from one repo to another (on a different machine) and am having trouble understanding why it is not working a second time.

My session (edited, but still relevant):

[/c/git/repo] (mybranch)
[user] $ git commit -a --amend
[mybranch ad1804290] Add filtering
 Date: Thu Jun 21 09:50:43 2018 -0400
 26 files changed, 2302 insertions(+), 2006 deletions(-)

[user] $ git push centos7vm mybranch
Counting objects: 157, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (135/135), done.
Writing objects: 100% (157/157), 59.76 KiB | 3.51 MiB/s, done.
Total 157 (delta 121), reused 34 (delta 15)
To ssh://mymachine/home/user/git/repo
 * [new branch]          mybranch -> mybranch

Works, right? Let's make some changes and try again:

[/c/git/repo] (mybranch)
[user] $ git commit -a --amend
[mybranch 26c680cbf] Add filtering
 Date: Thu Jun 21 09:55:43 2018 -0400
 26 files changed, 2302 insertions(+), 2006 deletions(-)

[/c/git/repo] (mybranch)
[user] $ git push centos7vm mybranch
To ssh://mymachine/home/user/git/repo
 ! [rejected]            mybranch -> mybranch (non-fast-forward)
error: failed to push some refs to 'ssh://user@mymachine/home/user/git/repo'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Fails... But, why? I have not even checked out the branch on the remote to make any changes. How can my current branch be behind the remote? This makes no sense to me.

My remote setup:

[user] $ git remote show centos7vm
* remote centos7vm
  Fetch URL: ssh://user@mymachine/home/user/git/repo
  Push  URL: ssh://user@mymachine/home/user/git/repo
  HEAD branch: development
  Remote branches:
  Local refs configured for 'git push':
    development        pushes to development        (fast-forwardable)
    mybranch           pushes to mybranch           (local out of date)
Jon
  • 1,675
  • 26
  • 57
  • possible duplicate of https://stackoverflow.com/questions/253055/how-do-i-push-amended-commit-to-the-remote-git-repository – gogaz Aug 22 '18 at 17:04
  • Possible duplicate of [How do I push amended commit to the remote Git repository?](https://stackoverflow.com/questions/253055/how-do-i-push-amended-commit-to-the-remote-git-repository) – phd Aug 22 '18 at 17:38

2 Answers2

0

When you commit for the first time your local HEAD changed from A to B. By pushing to the remote you fast forward remote branch, making its HEAD pointing to B, too.

When you amend, you're not creating revision C after B, you're modifying B, essentially making it B'. Eventually when you try to push for the second time, git verifies that B and B' have same parent A but different hashes which is a conflict.

    / B  (remote)
A---
    \ B' (local)

One way to resolve this issue is to just overwrite remote commit by pushing with -f flag, which is highly discouraged for obvious reasons.

It also sounds like you have flaws in your workflow. Ideally you should use a code review system like Gerrit or similar which allows you to push subsequent amendments for the same commit. Only the last revision which passed reviews, verification etc. ends up in a branch.

  • This is me, pushing from one PC, to another, for building and testing. Gerrit will come into play later, when the code is building and operating properly. – Jon Aug 22 '18 at 18:19
0

If you look closely at your commands you can see that --amend actually creates a new commit.

First try:

  [user] $ git commit -a --amend
  [mybranch ad1804290] Add filtering

2nd try:

  [user] $ git commit -a --amend
  [mybranch 26c680cbf] Add filtering

(ad1804290 vs 26c680cbf)

Changing commits after pushing them is rarely a good idea. I would just leave it as it is. If you need changes, just create a new commit.

Since you're working on your own push --force may be OK here, but using -f is a very bad habit to develop.

It's just better if you don't amend pushed commits.

tymtam
  • 31,798
  • 8
  • 86
  • 126
  • So, how would that work... does the push (to my linux remote) just take whatever is new, push that over and adjust the remote HEAD to point to the latest commit? How does that affect commits for gerrit? Would I end up needing to squash several commits, prior to pushing to gerrit? How would I then handle changes arising from code reviews? – Jon Aug 30 '18 at 23:11