can't push to branch after rebase

前端 未结 6 599
走了就别回头了
走了就别回头了 2021-01-29 17:28

We use git and have a master branch and developer branches. I need to add a new feature and then rebase the commits to master, then push master to CI server.

The problem

相关标签:
6条回答
  • 2021-01-29 18:10

    First, you and those you're working with need to agree whether a topic/devel branch is for shared development or just your own. Other developers know not to merge on my development branches because they'll be rebased at any time. Usually the workflow is as follows:

    o-----o-----o-----o-----o-----o       master
     \
       o-----o-----o                      devel0
                    \
                      o-----o-----o       devel1
    

    Then to stay up-to-date with remote I'll do the following:

     git fetch origin
     git checkout master
     git merge --ff origin/master
    

    I do this for two reasons. First because it allows me to see if there are remote changes without needing to switch from my devel branch. Second it's a safety mechanism to make sure I don't overwrite any un-stashed/committed changes. Also, if I can't fast-forward merge to the master branch that means either someone has rebased the remote master (for which they need to be flogged severely) or I accidentally committed to master and need to clean up my end.

    Then when remote has changes and I've fast forwarded to the latest I'll rebase:

    git checkout devel0
    git rebase master
    git push -f origin devel0
    

    Other developers then know they'll need to rebase their devel branches off my latest:

    git fetch <remote>
    git checkout devel1
    git rebase <remote>/devel0
    

    Which results in much cleaner history:

    o-----o                                 master
           \
             o-----o-----o                  devel0
                          \
                            o-----o-----o   devel1
    

    Don't merge commits back and forth at your whim. Not only does it create duplicate commits and make history impossible to follow, finding regressions from a specific change becomes near impossible (which is why you're using version control in the first place, right?). The problem you're having is the result of doing just this.

    Also it sounds like other developers may be making commits to your devel branches. Can you confirm this?

    The only time to merge is when your topic branch is ready to be accepted into master.

    On a side note. If multiple developers are committing to the same repository you should all consider having named branches to distinguish between developers devel branches. For example:

    git branch 'my-name/devel-branch'
    

    So all developers topic branches reside within their own nested set.

    0 讨论(0)
  • 2021-01-29 18:16

    The general answer that has already been given -- to use git push -f origin myNewFeature when pushing rebased changes -- is a good starting place. I'm writing this answer to address the edit about whether it will break your workflow.

    If we assume that you're going to be using git pull --rebase ... (or some variation on that) followed by a force-push to the remote branch, then the thing that breaks the workflow in your example is developer2 is merging myNewFeature into hisNewFeature. It makes sense to be able to rebase your own feature branch as long as nobody else is working on that branch, so you need rules to demarcate branch territory.

    You can get around this by a) establishing a rule that you only ever merge from master, or b) creating a collective develop branch, upon which you base your own myNewFeature branch, and establish a rule that you only ever merge from develop. master will then be reserved only for milestones or releases (or however else you want to set that up), and develop will be where you push each feature when it's ready to be integrated into other feature branches.

    I believe this could be considered a simplified version of the Gitflow workflow.

    0 讨论(0)
  • 2021-01-29 18:20

    You need to perform a forced push, i.e. git push -f origin myNewFeature

    Oh, and you better make damn sure that people don't base anything on your dev branch - usually you aren't supposed to publish branches where you are rewriting history at all (or rather do not rewrite history once published). One way would be using a branch name like wip/myNewFeature and then mentioning that wip branches will be rebased to master from time to time.

    0 讨论(0)
  • 2021-01-29 18:21

    I agree with MrCholo, and maybe Trevor Norris could consider updating its good answer to replace

    git push -f origin devel0
    

    with

    git push --force-with-lease origin devel0
    
    0 讨论(0)
  • 2021-01-29 18:23

    You need to force the push as you have moved the commits further down the line git is expecting you to add commits to the tip of the branch. git push -f origin myNewFeature will fix your problem.

    Tip: Above is a legitimate usage of force pushing. Never ever rewrite the history on a publicly accessible repository or a lot of people will hate you.

    0 讨论(0)
  • 2021-01-29 18:28

    The main thing to keep in mind here is what pull and rebase are doing behind the scenes.

    A pull will basically do two things: fetch and merge. When you include --rebase it will do a rebase instead of the merge.

    A rebase is pretty much like stashing all of your local changes since you branched, fast forwarding your branch to the latest commit on the target, and unstashing your changes in order on top.

    (This explains why you may get multiple conflict resolution prompts when doing a rebase vs the one conflict resolution you may get with a merge. You have the opportunity to resolve a conflict on EACH commit that is being rebased in order to otherwise preserve your commits.)

    You never want to push rebased changes to remote branches as this is rewritting history. Ofcoarse, never is a bit strong as there are almost always exceptions. The case that you need to maintain a remote version of your local repository to work on a specific environment for example.

    This will require you to push rebased changes at times either using force:

    git push -f origin newfeature
    

    Or in some cases your administrator may have removed the ability to force so you must delete and recreate:

    git push origin :newfeature
    git push origin newfeature
    

    In either case you must be absolutely sure you know what you are doing if someone else is collaborating with you on your remote branch. This may mean that you work together initially with merges and rebase those into a more manageable commit format just before going to master and removing your working branch.

    Remember you can almost always fallback on git's GC by taking advantage of:

    git reflog
    

    This is a HUGE life saver as you can reset back to a more stable state if you get lost in all of your rebase/conflict management.

    0 讨论(0)
提交回复
热议问题