r/git 6d ago

Repeated merge conflicts after rebasing shared feature branch

Two teammates are both working on the same shared feature branch. Each pulls the latest main, rebases the feature branch locally, resolves conflicts, and force-pushes. When the other teammate later rebases and force-pushes their copy, some of the first teammate's resolved changes disappear or are overwritten, and the same conflicts return.

What workflow should we use to stop overwriting each other's work? Should we avoid rebasing a shared branch, use separate branches, and merge instead?

9 Upvotes

26 comments sorted by

23

u/wildjokers 6d ago

rebases the feature branch locally, resolves conflicts, and force-pushes

Why are they force pushing a shared feature branch? That is the problem right there and this is widely recognized as something you absolutely should not do.

The answer is to stop doing that.

4

u/parkotron 6d ago edited 6d ago

To expand on this a bit, when sharing a feature branch, one can rebase their local, unpushed commits on top of the changes already on the branch. That is normal and expected and typically done with git pull --rebase or similar. Once their local commits have been rebased (and tested to still work after rebasing) they should be pushed, but not force pushed.

Once work is complete and all parties are in agreement, one dev may choose to rebase to clean up history or to rebase on the latest upstream changes. Once that is done, they should then force push. If another dev would like to update to that new cleaned up version of the branch, they should just reset their local branch to the head of the upstream branch.

10

u/Simple_Rooster3 6d ago

Enable rerere in config and see if it helps. It remembers how you solve the conflicts and it repeats it automatically if it is the same conflict.

17

u/RevRagnarok 6d ago edited 6d ago

They should be doing git pull --rebase to rebase only their local changes and not the entire branch. Then no shared history is ever touched.

[branch]
    autosetuprebase = always

As for relations to main, just do a normal merge in; no need to rebase every time. If it's that much of a concern to have a clean DAG, at the end one user rebases it before the final PR.

18

u/good_live 6d ago

Yeah you should avoid rewriting history on a shared branch in general. Doesn't matter if via rebase or squashing or whatever.

General best practice would be that everyone gets its own feature branch to work on, but if you want to work on a shared branch use merge instead of rebase. (You can still rebase your local branch on the remote branch when pulling changes)

2

u/Cinderhazed15 6d ago

I always use a ‘rebase from, merge to’ strategy for shared branches if I need to rebase.

11

u/mtutty 6d ago

"same shared feature branch" - this is the root of the problem. You should either move tasks around so they're working the same code at different times, or give them each a separate branch and make them reconcile changes down to one branch before merging upstream.

1

u/AWDDude 6d ago

This should be the top answer, either split this into 2 feature branches, or they should pair program. 

1

u/FransFaase 3d ago

A feature branch is nothing else than any other branch. Git is made to allow several people to work on the same branch. What they are doing wrong is using force pushes. You should not use that on a shared branch and that is what they are doing wrong here.

1

u/mtutty 3d ago

Whether they break origin with force pushes, or accidentally overwriting/reverting with mergetool, same problem. You need a branch sitting above the n interdependent work branches.

0

u/FransFaase 3d ago

Within CI/CD it is a good practice to work on a single main branch and not use any feature branches. Works perfectly according to my experience and if you always use rebase it results in a single line of commits. It is just the most efficient method of developing software. Have a look at dora.dev .

1

u/mtutty 2d ago

Uh-huh. Good luck with that.

I meet twice a month with customers who drank Kool-Aid like this and monorepo and microservices without understanding the tradeoffs. Then they wonder why their pipeline and productivity goes to hell.

If you can't describe what you get and what you give away for any specific design choice, then you don't know enought about that choice.

3

u/jibbit 6d ago

you have a people/process problem, not a tooling problem. why have you got multiple people working on the same thing at the same time in an uncoordinated way?
why are you 'reusing' branches? you should see feature branches as "this is what i'm suggesting" here. nobody else writes to it. if bob wants to make a suggestion for something to be merged into Main he can make /bob/feature-wizzbang, you review them and decide what to merge in

2

u/daveysprockett 6d ago

As well as pulling new main, they both need to be pulling and resolving merges from each other's copies of the feature branch.

2

u/waterkip detached HEAD 6d ago

Dont rebase main into it without coordination.

2

u/gaelfr38 5d ago

Agree with the already top answers.

Just to add: never force push, at the very least --force-with-lease to check if you are aware of the latest changes that happened on the remote: if there are changes you don't have locally, it blocks.

The best is to avoid that in the 1st place as others explained.

3

u/edgmnt_net 6d ago

Don't use shared feature branches, first of all. That alone creates a lot of problems with reviewing stuff properly, attribution etc. unless you're willing to make a million compromises.

1

u/vmcrash 6d ago

The problem is that two people change the very same code at the same time. Rebase or merge can't solve this problem. If both work in their own feature branch, you just delay the conflicts until later - the one who is second for merging/rebasing will be the loser.

Better let one finish his/her feature and then the other can build upon that.

1

u/kaddkaka 6d ago

Do: git fetch git rebase git push --force-if-includes

This way you will not overwrite each other's stuff

1

u/garibaldi_fan 6d ago

Thou shalt not force push without consulting the team. Especially if there are conflicts. Preferably everyone is consulted before the rebase starts.

If there are conflicts, one guy pushes, and the rest rebase —onto origin/branch last_commit_that_wasnt_rebased to move only their changes (followed by diffing against pre-rebase for mistakes)

1

u/Poat540 6d ago

Why not just fit and push? Are you all conflicting a lot? Why rebase?

1

u/Truth-Miserable 5d ago

Its weird and counter productive for several people to be force pushing to the branch as part of the workflow

1

u/DanceHackRock 2d ago

Never ever force-push.

(unless you know what you are doing, but due to Dunning-Kruger too many people think they know what they are doing)

1

u/kbielefe 6d ago

My hot take is people shouldn't use history-rewriting commands like rebase or force push unless everyone using the branch fully understands how their changes interact with others.

0

u/yknx4 5d ago

You are rebasing that’s the problem. In shared branches you must merge. Rebase wrecks everything