Search code examples
gitintellij-ideaatlassian-sourcetree

Search pull requests / merges by commit message and cherry-pick all corresponding commits


Consider the following history:

      #1    #2    #3   PR no.

-O-----A-----B-----C   commits on master (merges)
  \   / \   / \   /
   1-2   3-4   5-6     commits on branches

As can be seen, there were 3 PRs, merged via the commits A, B, C. The commit messages of these merges contain issue keys:

  • A: "Merge FIB-13 ..."
  • B: "Merge FIB-21 ..."
  • C: "Merge FIB-34 ..."

Now I would like to search for certain issues and get a list of the commits that they introduced:

Input: List of issue keys
Output: List of commits from PRs

Example
-------

Input: FIB-13, FIB-34
Output: 1, 2, 5, 6

Afterwards, I would like to cherry-pick these commits into another branch, commit by commit:

-1-2-5-6   another branch

Is there a good way to script this and/or can this be achieved via IntelliJ's Git client or Sourcetree?


Solution

  • From what I read in the comments, the first obstacle you encountered is finding all the commits you want to git cherry-pick. As proposed by @torek, it can be easily done with git log or git rev-list. Basically something like this:

    #!/bin/bash
    first_log="git rev-list --reverse --merges"
    for feature in $@ 
    do
        first_log+=" --grep=\"^Merge ${feature}\"" 
    done
    
    for cmt in $(eval "$first_log master")
    do
        git log --format="%h: %s" --reverse ${cmt}^2 ^${cmt}^1
    done
    

    A brief explanation of what it does: It loops over the input parameters $@, and adds as many --grep as the feature ids you passed. Then it evaluates the git rev-list command and for each merge commit found, it retrieves all the commits that belong to the second parent of the merge commit, which is the feature branch tip, but unreachable from the first parent of the merge commit, which is the previous commit in the master branch: ${cmt}^2 ^${cmt}^1. The advantage of doing this is that it finds even the commits of the sub-branches originated from the feature branch.

    To get the reverse chronological order, you just need to add --reverse option to both git log and git rev-list.

    Input sample:

    ./script.sh FIB-13 FIB-34
    

    Output sample:

    429ab60: 1
    c458a31: 2
    1c0d098: 5
    3bd087c: 6
    

    Once you arrive here, cherrypicking should be quite straightforward.