176

I am using an intermediate Git repository to mirror a remote SVN repository, from which people can clone and work on. The intermediate repository has its master branch rebased nightly from the upstream SVN, and we are working on feature branches. For example:

remote:
  master

local:
  master
  feature

I can successfully push my feature branch back to the remote, and end up with what I expect:

remote:
  master
  feature

local:
  master
  feature

I then re-setup the branch to track the remote:

remote:
  master
  feature

local:
  master
  feature -> origin/feature

And all is well. What I would like to do from here is to rebase the feature branch to the master branch on the remote, but I would like to do this from my local machine. I'd like to be able to do:

git checkout master
git pull
git checkout feature
git rebase master
git push origin feature

To keep the remote feature branch up-to-date with the remote master. However, this method causes Git to complain:

To <remote>
 ! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to '<remote>'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

git pull does the trick but causes a merge commit that I'd like to avoid. I'm concerned that the message states feature -> feature rather than feature -> origin/feature but this may just be a presentation thing.

Am I missing something, or going about this in completely the wrong way? It's not critical to avoid doing the rebase on the remote server, but it makes fixing any merge conflicts from the rebase much harder.

1
  • 1
    I had the same problem. I wanted to start a branch rebase model (like this). Then I noticed that I made a mistake: If you want to rebase (You should't push your changes to the remote feature before you do the rebase onto master) So you commit some code to your feature. And now you want to push it to your remote feature. Bevor you do this: -You should do fetch and pull your master if you need to. -You should rebase onto master if there have been some changes on the master you do not have in your feature. Now you can push the feature and there won't be a problem.
    – Markus
    Commented Mar 10, 2016 at 13:54

6 Answers 6

241

It comes down to whether the feature is used by one person or if others are working off of it.

You can force the push after the rebase if it's just you:

git push origin feature -f

However, if others are working on it, you should merge and not rebase off of master.

git merge master
git push origin feature

This will ensure that you have a common history with the people you are collaborating with.

On a different level, you should not be doing back-merges. What you are doing is polluting your feature branch's history with other commits that don't belong to the feature, making subsequent work with that branch more difficult - rebasing or not.

This is my article on the subject called branch per feature.

5
  • 35
    +1 for if others are working on it, you should merge and not rebase off of master, rebase better be used only on private branch.
    – O.O
    Commented Aug 29, 2012 at 14:43
  • 7
    alternativ to git push origin feature -f you could also delete your remote feature and push feature again
    – Markus
    Commented Mar 10, 2016 at 13:55
  • 2
    Merging master into your branch will create a merge commit and will cause conflicts with any other open feature branch from master after your changes are pushed.
    – Steven
    Commented May 18, 2016 at 18:47
  • 1
    +1 for git push origin feature -f. In certain contexts it may be necessary to perform a rebase even with remote branches. The crux is knowing what you are doing. And we should take over that you may be deleting commits in remote repo.
    – enagra
    Commented Oct 26, 2019 at 12:04
  • That does make sense~ For shared branches, we should rarely or never use git rebase. Maybe there can be an automatically check script before you do git rebase on shared branches (which has remote tracks)?
    – Yarco
    Commented Nov 15, 2021 at 9:01
45

This is an important thing/concept in git that a lof of git users would benefit from knowing. git rebase is a very powerful tool and enables you to squash commits together, remove commits etc. But as with any powerful tool, you basically need to know what you're doing or something might go really wrong.

When you are working locally and messing around with your local branches, you can do whatever you like as long as you haven't pushed the changes to the central repository. This means you can rewrite your own history, but not others history. By only messing around with your local stuff, nothing will have any impact on other repositories.

This is why it's important to remember that once you have pushed commits, you should not rebase them later on. The reason why this is important, is that other people might pull in your commits and base their work on your contributions to the code base, and if you later on decide to move that content from one place to another (rebase it) and push those changes, then other people will get problems and have to rebase their code. Now imagine you have 1000 developers :) It just causes a lot of unnecessary rework.

2
  • So what are you really saying? That the rebase functionality is kind of meant for local commits only? Commented Nov 27, 2023 at 19:35
  • @SterpuMihai I wouldn't say he said, hypothetically speaking, with his words, unless it is discovered he intentionally intended, by chance, or perhaps, or even inferred, at a minimum, or maximum to solely utilize only while in local development…IN FACT—dare I say—the intent guides those who do not know or should not know to not use and thus insinuating, and "for serious now," to simply avoid the use when a large blast radius is less than ideal.
    – darcher
    Commented Dec 13, 2023 at 21:04
7

Because you rebased feature on top of the new master, your local feature is not a fast-forward of origin/feature anymore. So, I think, it's perfectly fine in this case to override the fast-forward check by doing git push origin +feature. You can also specify this in your config

git config remote.origin.push +refs/heads/feature:refs/heads/feature

If other people work on top of origin/feature, they will be disturbed by this forced update. You can avoid that by merging in the new master into feature instead of rebasing. The result will indeed be a fast-forward.

1
  • What does the + sign mean here? I tried searching but I couldn't find relevant answers Commented Nov 29 at 17:09
0

I am unfamiliar using GitBash and I am adding an answer using TortoiseGit (GUI for newbees) here for those devs using Windows:

Force re-basing remote branch with local branch using TortoiseGit

Like many mentioned above, do this if only with your "private" repo branch and that means no one will ever throw a chair at you for re-basing the remote "develop" or "feature" branch with your local copy. The other devs who've committed and pushed their week's worth (or more) of work will be ERASED from the branch's history (log).

There will be no way to recover them - of course your co-developers will still have their changes on theirs as their PULL will most likely throw an error as they will be way way ahead of the branch current history or latest commits vs. theirs. Good thing Git is a distributed versioning system.

So, be careful with this power to reverting a remote branch. You are hereby warned. ;)

0

If you are working on a feature branch with other people, then it will probably happen that they have committed something. From there on, you cannot simply push your changes, as they conflict with the commit history. What you could do, would be to call git pull which is a git fetch + git merge command. This would create another commit for the merging.

I would try to avoid unnecessary merge commits in your history and keep your git commit history clean by simply calling git pull --rebase. This will put your commits after the existing ones.

Of course, you should only add the git history of your local branch, never change the git history of the remote branch.

-1

You can disable the check (if you're really sure you know what you're doing) by using the --force option to git push.

2
  • 20
    The problem is, I'm not sure I do really know what I'm doing :)
    – kfb
    Commented Jun 1, 2011 at 11:20
  • @r_: Please read my answer. It might help you in your understanding of what you're doing :) Commented Jun 1, 2011 at 19:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.