2

In my companies workflow, we often have to apply a similar commit across several maintenance branches. Because we are in a period of heave refactoring, we do this with independant commits (cherry picking when possible, but it's often not possible), not with merges. There is discussion about changing to a more git-flow workflow and always merging upwards, but variour reasons this is not currently the case.

I often find myself wanting to know -- have I applied a particular commit to all the branches that need it? I can get part way there with:

 git log --all --grep "Issue_number"

Which gives me a list of all commits with the relevant message number, independant of branch. If I could only have it also list all branches to which those commits apply, I would be content (for now).

I have tried using some of the suggestions in How to know which branch a "git log" commit belongs to?", but these do not seem to help.

Can someone tell me how to accomplish this?

Community
  • 1
  • 1
Spacemoose
  • 3,856
  • 1
  • 27
  • 48

4 Answers4

2

Based on orahman's answer and the man-pages, I did a little trial and error, and found that

git log --decorate=full --source --all --grep "commit#"

did the trick.

Unless I screwed up on the testing, it seems like both "=full" and "--source" are needed to get any branch information to show, but I am unable to explain why this is the case atm.

Suzanne Soy
  • 3,027
  • 6
  • 38
  • 56
Spacemoose
  • 3,856
  • 1
  • 27
  • 48
1

Perhaps --decorate might be what you're looking for?

git log --decorate --all --grep "Issue_number"

This will add the branch name right after the commit hash of each entry in the log.

orahman
  • 76
  • 3
  • That sounds great, but running the command as written, on git v 1.8.2 and 2.4.3 does not display any branch information in the commit output. – Spacemoose Jul 28 '15 at 13:00
  • Right, sorry. `--decorate` only adds the ref name, which in my small test case included the branch names in the tips. – orahman Jul 28 '15 at 13:06
  • well, it helped me find a working solution, although I'm still unclear why the working solution worked, and your solution didn't. – Spacemoose Jul 28 '15 at 13:07
0

The challenge is that your commits have different hashes because they've been cherry-picked. If you were searching for the branches containing one commit you could use git branch --contains:

git branch --contains abcd123
# * master
#   develop

There are a few ways to proceed. You could pipe the commits found by git log straight into git branch --contains:

git log --all --grep "Issue_number" | git branch --contains
# * master

This only shows the branches that are found. If you want to see the commit hashes as well you could use a loop, e.g. something like

for COMMIT in $(git log --all --grep "Issue_number" --pretty=format:%H); do
    echo "$COMMIT" 
    git branch --contains "$COMMIT"
done
# abcd123
# * master
#   develop
# deadbeef
#   feature1

Of course, either of these solutions could be aliased to something shorter.

ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257
0

Commits can always find their own ancestors but not their parents, so once you've found a commit you can't go UP the commit tree to find branch tips that are reachable.

Rather than first finding commits and then finding branches from those, you could ask each branch for its commits that match your issue number, then print those in a friendly manner.

Here's a commit tree that, I think, shows the workflow you're using:

$ git log --graph --decorate --pretty=oneline --abbrev-commit --all
* c332e51 (HEAD -> 1.x-dev) [Issue_4] Fix a problem with bar.
* a5a1c89 Add some copy to foo.
* b2e21e4 [Issue_3] Get baz some copy.
* 62df79a [Issue_2] Tweak bar a bit.
* 0c10193 [Issue_1] Adjust foo.
| * ab3f45f (2.x-dev) [Issue_3] Get baz some copy.
| * db14d19 [Issue_2] Tweak bar a bit.
| * 8722417 [Issue_1] Adjust foo.
| * 091fd82 Tweak baz.
|/
* eb9dace (master) This is bar
* 26d9260 Adjust foo.
* 15cd4ef Added some files.
* d73dbe7 Initial commit

I have two dev branches (1.x-dev and 2.x-dev). I've indicated issue-fixing commits with the string [Issue_NN] at the beginning of the commit message (mainly to make it easy to see from the tree). I've cherry-picked the issue commits from branch to branch. You can see that Issues 1-3 are applied to both branches, but Issue 4 is only on 1.x-dev.

So now, assuming that matches your practice, you can find the names of all the branches that contain [Issue_1] by listing all the branches and running your git log command just on that branch, then munging the output to conditionally display. For example:

# grab branch names from refs/heads
for branch in $(git for-each-ref --format='%(refname:short)' refs/heads/); \
  # set a var to the log line of the matching commit, if any
  do commit=$(git log --pretty=oneline --abbrev-commit --grep "Issue_3" $branch); \
  # list the branch and commit info if it matches
  [[ $commit != "" ]] && echo "$branch: $commit"; \
  done

This code looks for Issue_3 and if you run it you get output like:

1.x-dev: b2e21e4 [Issue_3] Get baz some copy.
2.x-dev: ab3f45f [Issue_3] Get baz some copy.

If you run it for Issue_4, however:

1.x-dev: c332e51 [Issue_4] Fix a problem with bar.

you can see that the Issue_4 commit has been applied only to 1.x-dev.

There may be prettier ways to accomplish this but I think the general principle is that you'll need to ask the branches for their commits, rather than finding commits then working backwards to branches.

joel boonstra
  • 425
  • 3
  • 12