{"thread":{"id":"12178","subject":"BUG: rebase -p after cherry-pick does not work","startedAt":"2008-02-18T14:06:52Z","lastAt":"2008-02-18T15:06:17Z","messageCount":2,"participants":["sf","Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"69151","messageId":"47B990FC.9090600@b-i-t.de","threadId":"12178","inReplyTo":null,"subject":"BUG: rebase -p after cherry-pick does not work","fromName":"sf","fromEmail":"sf@b-i-t.de","sentAt":"2008-02-18T14:06:52Z","receivedAt":"2008-02-18T14:06:52Z","isPatch":false,"sender":{"key":"sf@b-i-t.de","avatar":null},"body":"Hello,\n\ngit-rebase -p does not work when one of the changes is cherry-picked\nbefore rebase. Test case:\n\nset -e -u\nmkdir git\ncd git\ngit init\nfor x in abc def ghi\ndo\n  echo $x >$x\n  git add $x\n  git commit -m$x\ndone\ngit branch first\ngit reset --hard first~2\ngit cherry-pick first^\ngit branch second\nEDITOR=: git rebase --verbose --interactive --preserve-merges \\\nsecond first\ngit status\n\nThe result for me is:\n\nInitialized empty Git repository in .git/\nCreated initial commit fc8b37c: abc\n 1 files changed, 1 insertions(+), 0 deletions(-)\n create mode 100644 abc\nCreated commit 3d6ca20: def\n 1 files changed, 1 insertions(+), 0 deletions(-)\n create mode 100644 def\nCreated commit 4c5e07a: ghi\n 1 files changed, 1 insertions(+), 0 deletions(-)\n create mode 100644 ghi\nHEAD is now at fc8b37c... abc\nFinished one cherry-pick.\nCreated commit 3d6ca20: def\n 1 files changed, 1 insertions(+), 0 deletions(-)\n create mode 100644 def\nSwitched to branch \"first\"\nNote: moving to \"3d6ca204f4823bde7273a4bb83676055ae415224\" which isn't a\nlocal branch\nIf you want to create a new branch from this checkout, you may do so\n(now or later) by using -b with the checkout command again. Example:\n  git checkout -b <new_branch_name>\nHEAD is now at 3d6ca20... def\nRebasing (1/1)\n4c5e07a7107c87dec18244200ad1b52b76e71ea0\nFast forward to 4c5e07a7107c87dec18244200ad1b52b76e71ea0\nSuccessfully rebased and updated refs/heads/first.\n# On branch first\n# Changes to be committed:\n#   (use \"git reset HEAD <file>...\" to unstage)\n#\n#       deleted:    ghi\n#\n\nThe problem area is function pick_one_preserving_merges in\ngit-rebase--interactive.sh:\n\n    # rewrite parents; if none were rewritten, we can fast-forward.\n    fast_forward=t\n    preserve=t\n    new_parents=\n    for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)\n    do\n        if test -f \"$REWRITTEN\"/$p\n        then\n            preserve=f\n            new_p=$(cat \"$REWRITTEN\"/$p)\n            test $p != $new_p && fast_forward=f\n            case \"$new_parents\" in\n            *$new_p*)\n                ;; # do nothing; that parent is already there\n            *)\n                new_parents=\"$new_parents $new_p\"\n                ;;\n            esac\n        fi\n    done\n\nIf a commit's parent is not applied during rebase (e.g. because it was\ncherry-picked already) then it is not rewritten either.\n\nRegards\n\nStephan\n"},{"id":"69158","messageId":"alpine.LSU.1.00.0802181458300.30505@racer.site","threadId":"12178","inReplyTo":"47B990FC.9090600@b-i-t.de","subject":"Re: BUG: rebase -p after cherry-pick does not work","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-02-18T15:06:17Z","receivedAt":"2008-02-18T15:06:17Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 18 Feb 2008, sf wrote:\n\n> git-rebase -p does not work when one of the changes is cherry-picked\n> before rebase.\n>\n> [...]\n> \n> The problem area is function pick_one_preserving_merges in\n> git-rebase--interactive.sh:\n> \n> [...]\n>\n> If a commit's parent is not applied during rebase (e.g. because it was \n> cherry-picked already) then it is not rewritten either.\n\nThat is right.  How about giving it a try yourself?\n\nHints: you need to write a sha-1 to \"$REWRITTEN\"/<commit> for every commit \nthat was _not_ cherry-picked.  To do this, you could run the same rev-list \nas for $TODO, but without the --cherry-pick, and then filter with\n\n\t(cat \"$TODO\" \"$TODO\" \"$ALLCOMMITS\") | sort | uniq -u\n\nFor these commits, you need to find the ones with the same patch-id, but \nwhich are upstream.  You can achieve that by calling \"git patch-id\" for \neach upstream commit that was not in the to-be-rebased branch, and storing \nthose mappings in a file.  Then, for each leftout commit, you grep in that \nfile, and write to \"$REWRITTEN\"/<orig-commit>.\n\nOh, and you have to warn or error if there are two or more commits with \nthe desired patch-id.\n\nAlternatively, you can wait until Daniel has rewritten \ngit-rebase--interactive in C, which shouldn't be too long, and work on \nthat.  Should be easier and more efficient, too.\n\nCiao,\nDscho\n"}]}