Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep only head changes in a git rebase

Tags:

git

git-rebase

I'm currently in the middle of a lengthy rebase going through a dozen or so commits. I've structured things in my dev process such that only the changes from HEAD is what I want to keep - all other conflicts (e.g. commit hash b06a1dd) should be deleted.

Is there a way to simply remove all changes related to the >>>>>>> b06a1dd and keep the changes that Git will label <<<<<<< HEAD in one fell swoop, so I don't have to keep typing git rebase --continue, deal with more conflicts from more commit hashes, and only keep the HEAD changes?

like image 999
Smee Avatar asked Sep 08 '16 22:09

Smee


People also ask

Does rebase keep changes?

After starting a rebase, Git creates an anonymous branch and starts applying commits to it. Since ours means "keep changes from the current branch", that current branch will be HEAD , which contains upstream and any changes already applied by rebase .

What is head in a rebase?

But during the rebase, HEAD is either their branch-tip (commit L ), or one of the new commits copied and appended past their branch-tip; and --ours means the branch being grown at the end of L while --theirs means the commit being copied-from ( G or H above).

Why would you use git rebase head?

Rebasing is useful for making sure that the branch you are working on diverges from the latest version of the parent branch.


2 Answers

If you are willing to start the rebase over (git rebase --abort), then this should do what you need:

git rebase -X ours upstream

where upstream is the branch you are rebasing onto.

As noted in this answer and elsewhere, the ours vs. theirs labels are slightly more confusing for rebasing than for merging. After starting a rebase, Git creates an anonymous branch and starts applying commits to it. Since ours means "keep changes from the current branch", that current branch will be HEAD, which contains upstream and any changes already applied by rebase.

like image 187
Scott Weldon Avatar answered Oct 11 '22 01:10

Scott Weldon


For the sake of completeness, this is what I learn from the previous answer and comments in current Q&A (credit goes to their authors):

  • If you are willing to start over and choose same side for ALL the commits, the current chosen answer git rebase --abort and then git rebase -X ours upstream can do the trick.
  • But I guess in practice you won't want to blindly use either ours or theirs without looking into each commits. You would want to make a case-by-case decision for each commit, when "in the middle of a lengthy rebase". So, your actual options will be:

    1. To use the upstream:

      git checkout --ours path/to/a/specific/file
      git add path/to/a/specific/file
      

      or even better, in this case you simply use this:

      git reset HEAD path/to/a/specific/file
      
    2. Use your feature branch:

      git checkout --theirs path/to/a/specific/file
      
    3. or do it in the manual way to address each <<<< ... ==== ... >>>> in your editor.

PS: The ours and theirs have special meaning when doing rebase.:

Note that during git rebase and git pull --rebase, ours and theirs may appear swapped; --ours gives the version from the branch the changes are rebased onto, while --theirs gives the version from the branch that holds your work that is being rebased.

This is because rebase is used in a workflow that treats the history at the remote as the shared canonical one, and treats the work done on the branch you are rebasing as the third-party work to be integrated, and you are temporarily assuming the role of the keeper of the canonical history during the rebase. As the keeper of the canonical history, you need to view the history from the remote as ours (i.e. "our shared canonical history"), while what you did on your side branch as theirs (i.e. "one contributor’s work on top of it").

like image 38
RayLuo Avatar answered Oct 11 '22 01:10

RayLuo