Git rebase/workflow confusion - what's the proper workflow for a branch that needs to pull in upstream commits?

StackOverflow https://stackoverflow.com/questions/22473982

  •  16-06-2023
  •  | 
  •  

Pergunta

Here's my setup: I've branched "master", and there is no intention of ever merging "my_branch" back into master. However, I want to continue to get all the updates to master.

If I branch master at MC1 (master commit #1), and add new commits to my_branch (BC1 and BC2), and somebody adds a new commit to master (MC2) in the meantime, I would like history to be:

MC1<-MC2<-BC1<-BC2

In the past, I used:

git fetch origin
git rebase origin/master

So far so good. It replays BC1 and BC2, I fix up the merge conflicts, and rebase --continue until completion. However, the final commit involves a merge of "merge branch "my-branch" of github.... into my-branch (maybe that's where this starts going wrong?)

But then I add more commits to my branch (BC4,BC5). In the meantime, MC3 is added to master. So I again try to rebase...

It replays BC1. I'm having to redo merge conflicts I've already handled (e.g., the code I changed in BC1 from MC1 hasn't changed from MC1 thru MC3). I find myself having to pick through merge conflicts that later patches will then change themselves. And the my_branch history now includes multiply copies of BC1 scattered throughout for each additional rebase.

Is there a better way to handle branching and merging of upstream changes?

Foi útil?

Solução

I strongly recommend to reconsider whether you absolutely need to rebase. Merging upstream into your branch might be the better option:

git fetch origin
git merge origin/master

This will:

  1. Not issue the same merge conflicts twice
  2. Not duplicate commits

Rebasing inherently re-creates all commits you are rebasing, so it is normal/expected, that your history contains multiple versions of the same commit.

With the merging workflow, your history will look like this:

MC1     <-     MC2        <-        MC3 
 ^              ^                    ^
  \              \                    \
  BC1 <- BC2 <- BC3 <- BC4 <- BC5 <- BC6

Where BC3 and BC6 are merge commits resolving potential conflicts.

IMHO, rebasing is a only a good idea for:

  1. Short-lived branches (e.g. remote tracking branches)
  2. Branches with a small, number of commits (e.g. setting values in a config file)

Another option would be to squash all your commits into a single one, practically protecting you from having to resolve merge conflicts each time. But since this makes you loose history, it's probably not an option.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top