git: obtain the benefits of `git rebase –interactive` for cherry picks

I’d like to be able to do this:

git cherry-pick --interactive hash-0..hash-n-1  # fantasy command

and obtain the same workflow as interactive rebase: an editor buffer comes up, containing:

  • Git: break a large+messy feature branch into smaller branches
  • Making a local repo to a public repo?
  • Git error: conq: repository does not exist
  • How to clone git repository from its zip
  • Git: why the file deletion does not sync?
  • Github and Git - what is needed to work with a git terminal in win7?
  • pick hash-0
    pick hash-1
    pick hash-2
    pick hash-n-1

    where I can delete any unwanted commits, squash them together, or edit to pause between the picks to do some manual fixup (like commit --amend) and all that.

    Note how the pick of interactive rebase is tanalizingly like cherry-pick.

    Now the above operation can be done by performing the cherry-pick first, and then the interactive rebase, which is inconvenient. That is:

    $ git tag old-head  # mark starting point for later rebase
    $ git cherry-pick hash-0..hash-n-1    # get everything first
    $ git rebase --interactive old-head   # okay now rebase "in-branch" to fix it up

    It’s not only inconvenient because of the two steps but because it may require resolving conflicts in commits you don’t even want that will be discarded in the rebase stage.

  • should minified files be committed into source control?
  • Is it possible to switch between GIT commits?
  • Redoing Commit History in GIT Without Rebase
  • Planning repository layout for git migration
  • How can I completely empty the master branch in Git?
  • Is there any personal information in the .git directory
  • 3 Solutions collect form web for “git: obtain the benefits of `git rebase –interactive` for cherry picks”

    Okay, figured out a nice hack.

    Start a trivial rebase --interactive HEAD^ over one commit in your current branch. You get something like:

    pick 1efd396b * Fixed a bug in frob function

    Now, just paste in additional hashes that you want to pick:

    pick 1efd396b * Fixed a bug in frob function
    pick f01934db * Awesome feature added
    pick 6fd109c1 * Refactored the widgets layer
    squash 3900fd77 * Refactored the widgets layer s'more

    Save and exit, and wee: the rebase mule obligingly takes the additional cruft you loaded on its back and incorporates it into the current branch according to the commands.

    You can actually do an empty rebase with:

    git rebase --interactive HEAD

    you get a buffer containing


    You don’t have to delete that; just add your picks after that.

    Addendum: To produce the pick lists for this method, use git log --oneline --reverse, then trim the output needed and prepend the rebase commands to each line: pick, squash, …

    Okay, following up on Carl Norum’s suggestion, I looked into the --onto argument of git rebase.

    The use case can be satisfied like this, which is an improvement, though still involves a somewhat excessive number of steps.

    The primary issue is that rebase needs a current branch to pick from so we have to shift our coordinates to a temporary branch, and then manipulate our original branch head afterward and delete the temporary branch.

    The flow looks like this:

    # We are originally on "mybranch"
    # We create a temp-branch pointing to the last commit to be picked: hash-n-1
    $ git checkout -b temp-branch hash-n-1   # create branch at last hash
    # Then we rebase from the point before the first hash, onto our original branch
    $ git rebase --interactive hash-0^ --onto mybranch
    # The above rebase should make "temp-branch" into the very object that
    # we want "mybranch" to be. If it looks that way, then all that is left is
    # make it so:
    $ git checkout mybranch          
    $ git reset --hard temp-branch
    $ git branch -D temp-branch

    The git rebase --interactive hash-0^ --onto mybranch uses the commit before hash-0 as the “upstream” for the rebase, taking all the commits from the current branch (based on hash-n-1) which are not in the upstream. Those commits are, of course, hash-0 through hash-n-1. They are rebased onto the mybranch head, but it is the current temp-branch which is reset --hard to track the result. So we just have to assign that pointer to mybranch and delete temp-branch.

    It’s fairly clumsy, but eliminates the duplicate cherry-picking, and is easy to recover from at any time just with git reset --hard mybranch.

    (Can this still be improved.)

    Perhaps a better answer is out there, but this might work for you

    git cherry | awk '$0=$2' > cherry.txt
    "$EDITOR" cherry.txt
    git cherry-pick --stdin < cherry.txt


    Git Baby is a git and github fan, let's start git clone.