Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git pull --rebase resolve conflicts by keeping local changes

Tags:

git

rebase

pull

I rebased to master on my local branch. Meanwhile someone did changes on this branch on remote. I am doing git pull --rebase. I don't understand how git interprets this command when it comes to the naming of current and incoming, as well as ours and theirs.

Which should I choose to always keep my local changes? Also, after my first rebase with master, there are dozens of conflicts. Is there a command to make git pull --rebase just keep all my local changes, instead of having to do it manually? I know about ours and theirs, but I don't know how to incorporate those keywords in git pull --rebase command.

This stuff is confusing as hell, since all those keywords get reversed between merge and rebase, and then there is pull with rebase to add extra confusion.

like image 768
Peter S. Avatar asked Aug 27 '20 07:08

Peter S.


People also ask

Will git pull remove my local changes?

The reason for error messages like these is rather simple: you have local changes that would be overwritten by the incoming new changes that a "git pull" would bring in. For obvious safety reasons, Git will never simply overwrite your changes.

What does git pull -- rebase does?

Git pull rebase is a method of combining your local unpublished changes with the latest published changes on your remote. Let's say you have a local copy of your project's main branch with unpublished changes, and that branch is one commit behind the origin/main branch.


Video Answer


1 Answers

The command to favor the changes in your local branch is:

git pull --rebase -X theirs

The reason why you have to say "theirs" when, intuitively, you'd like to say "ours" is because the meaning of "ours" and "theirs" is swapped during a rebase compared to a merge. Let me explain.

Ours and Theirs in a Merge vs. Rebase

When you do a merge, you're always merging into the current branch; in case of a conflict, "ours" means the branch you're on, while "theirs" means the branch you're merging. Exactly as you would expect.

A rebase is different. Let's say that you're rebasing a branch called local onto master.

        master
        ⌄
o---o---o
    \
     A---B---C ‹ local

During a rebase, Git creates a sort of "temporary branch" to do the work1. It starts by moving HEAD to the tip of the branch you're rebasing onto, in this case master:

        master
        ⌄   
o---o---o ‹ HEAD
    \
     A---B---C ‹ local

Then, it cherry-picks the commits from local one at a time:

        master
        ⌄   
o---o---o---A'---B' ‹ HEAD
    \
     A---B---C ‹ local

Now, let's image that commit C has a conflict:

        master
        ⌄             X
o---o---o---A'---B'---C' ‹ HEAD
    \
     A---B---C ‹ local

In this case, "ours" indicates the temporary branch Git is working on, while "theirs" is the branch from which the commit was cherry-picked, which is local.

If you wanted to keep the changes in your local branch, you'd have to choose the "theirs" side. If, instead, you wanted to keep the changes in master, you'd choose the "ours" side.

Once the conflict has been resolved, Git completes the rebase operation by moving local to point to where HEAD is:

        master
        ⌄             
o---o---o---A'---B'---C' ‹ HEAD, local
    \
     A---B---C

Given that no branch is left referencing commit C, those commits become unreachable and will eventually be deleted:

        master
        ⌄             
o---o---o---A'---B'---C' ‹ HEAD, local

1 It's really just a detached head, but for the purpose of this explanation, you can think of it as a temporary branch, even though no branch reference is being created.

like image 156
Enrico Campidoglio Avatar answered Oct 21 '22 03:10

Enrico Campidoglio