git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Cleaning up history with git rebase

From
Michael Witten <mfwitten@gmail.com>
Date
Aug 4, 2011, 12:15 UTC
Message-ID
<d62225a3cc5740cda7cb163a94d55892-mfwitten@gmail.com>
In-Reply-To
<1b66c8efe0214915be2c52a5aacd22de-mfwitten@gmail.com>
On Mon, 01 Aug 2011 01:07:33 -0000, Michael Witten wrote:
Show 79 quoted lines
> Michael Witten wrote:
>
>> On Sun, 31 Jul 2011 18:44:43 -0300, Ricky, Egeland wrote:
>>
>>> On Jul 31, 2011, at 6:33 PM, Michael Witten wrote:
>>> 
>>>> On Sun, Jul 31, 2011 at 20:21, Michael Witten <mfwitten@gmail.com> wrote:
>>>>> Why are there conflicts anyway?
>>>>
>>>> Oh...
>>>>
>>>> I guess there were conflicts when the merge commit was made in
>>>> the original repository, and these conflicts were resolved by
>>>> the merge commit itself. Hence, when rebase tries to split up
>>>> a merge by dealing with just the non-merge parents, you end up
>>>> having to deal with the conflict again.
>>> 
>>> Yes, I thought it was something like this going on, too. In the
>>> pre-rebase history, when there is a commit with "Conflict:" and
>>> listing file which is in the sub-repository history, this is a
>>> point where rebase stops with a conflict.
>>> 
>>>> Shouldn't rebase take this into account?
>>> 
>>> Not sure.  Seems that it does not, it makes me resolve the conflict =
>>> again.
>>
>> I think git rebase should take this into account is what I'm saying.
>>
>> The following implements what I think `git rebase' should be doing;
>> run it instead of `git rebase' in your repo:
>>
>>   git branch saved
>>   git rev-list HEAD --reverse --first-parent --parents |
>>   {
>>     read root
>>     git reset --hard $root
>>     rebase_head=$root
>>
>>     while read commit first_parent other_parents; do
>>
>>       if [ -z "$other_parents" ]; then
>>
>>         git cherry-pick $commit
>>         rebase_head=$commit
>>
>>       else
>>
>>         for parent in $other_parents; do
>>
>>           if ! git cherry-pick $parent; then
>>
>>             git reset --hard $rebase_head
>>             git merge $other_parents
>>             git rm -rf .
>>             git checkout -- $commit
>>             git commit -aC $commit 
>>             break
>>
>>           fi
>>
>>         done
>>
>>         rebase_head=$(git rev-parse HEAD)
>>
>>       fi
>>
>>     done
>>   }
>
> Woops!
>
> This line:
>
>   git checkout -- $commit
>
> should be:
>
>   git checkout $commit -- .
I noticed that my script has another problem; the line:
  rebase_head=$commit
should be:
  rebase_head=$(git rev-parse HEAD)

I was trying to make an optimization, but it's the wrong logic :-/

Sorry for the confusion. Here is an updated version of the entire script:

  git branch saved
  git rev-list HEAD --reverse --first-parent --parents |
  {
    read root
    git reset --hard $root
    rebase_head=$root
    while read commit first_parent other_parents; do
      if [ -z "$other_parents" ]; then
        git cherry-pick $commit
      else
        for parent in $other_parents; do
          if ! git cherry-pick $parent; then
            git reset --hard $rebase_head
            git merge $other_parents
            git rm -rf .
            git checkout $commit -- .
            git commit -aC $commit
            break
          fi
        done
      fi
      rebase_head=$(git rev-parse HEAD)
    done
  }
Previous: pbegeland
Message 12 of 12 in “Cleaning up history with git rebase”
  1. Ricky EgelandJul 31, 2011
  2. Michael WittenJul 31, 2011
  3. Michael WittenJul 31, 2011
  4. Ricky EgelandJul 31, 2011
  5. Michael WittenAug 1, 2011
  6. Michael WittenAug 1, 2011
  7. pbegelandAug 3, 2011
  8. Michael WittenAug 4, 2011
  9. pbegelandAug 5, 2011
  10. Michael WittenAug 6, 2011
  11. pbegelandAug 9, 2011
  12. Michael WittenAug 4, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.