1

On my local feature branch,

  1. I did some work in a commit, and then manually edited some files to undo some of the work, and committed the undo work into two new commits. Right after making each commit, I also pushed it to GitHub.

  2. Then I wanted to clean up my feature branch, by going back to the commit on master where the feature branch was created, by running

    git reset HEAD~3
    

    The unstaged changes shown by git status at this point was the accumulated changes done in the latest 3 commits, and was exactly what I hoped for after cleaning up. So I ran git add and git commit to commit them.

  3. When I tried to push the commit to Github,

    $ git push origin feature
    To https://xxx
     ! [rejected]        feature -> feature (non-fast-forward)
    error: failed to push some refs to 'https://xxx'
    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.
    

    Then I followed the hint by running git pull, which automatically merged the remote feature branch into my local feature branch, with no merge conflict because their tip commits are identical.

    However, the commits removed by git reset HEAD~3 earlier show up again in the output of git log, and

    $ git status
    On branch feature
    Your branch is ahead of 'origin/feature' by 2 commits.
      (use "git push" to publish your local commits)
    nothing to commit, working tree clean
    

    That doesn't clean up my feature branch, but add two new commits to the original feature branch. If I push to github, the remote feature branch will be the same.
    So do I miss anything? Or generally in similar cases, there is no need to clean up commits?

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
Tim
  • 1
  • 141
  • 372
  • 590
  • 1
    If you **have control**, you should've "force pushed" instead of pulling. This would reflect your history rewrite on github as well, instead of bringing back your original commits, which was what that pull did. – Lasse V. Karlsen May 09 '17 at 18:44
  • 1
    By "have control" I mean that nobody else is basing their work on the commits you intend to get rid of, like in this case, nobody else is working on that branch. If they are, you risk one of them pushing your removed commits back at a later time anyway, unless you get everybody to do fresh clones or rebase their work on your new commits. – Lasse V. Karlsen May 09 '17 at 18:45
  • Thanks. No one work on the same feature branch as i do. I ran `git push origin feature`, and how can i "force pushed" instead? – Tim May 09 '17 at 18:47
  • Is it `git push origin feature --force`? http://stackoverflow.com/a/12610763/156458 – Tim May 09 '17 at 18:59

2 Answers2

1

Your workflow could use some improvement:

  1. Do not push to remote after every commit. Only push after you have reached some kind of milestone where you are comfortable with what you've got and will unlikely make changes to these existing commits.

  2. git reset is not the best way to clean up your work. Use git rebase -i instead. For instance, git rebase -i HEAD~3 would allow you to edit one of the last 3 commits, or squash some of them.

Try those and you'll find yourself less likely stuck in a situation where you have to force push. :-)

jingx
  • 3,698
  • 3
  • 24
  • 40
0

I ran git push origin feature, and how can I "force pushed" instead?

git push --force 

Your branch should already have an upstream branch associated to it, so you don't need to add origin feature.

Now, since you already pulled, you should instead reset again (see "Undo git pull, how to bring repos to old state"), add, commit and force push.

git reset HEAD@{1}
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250