简体   繁体   中英

git log — show which branches a commit applies to

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?

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.

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.

The challenge is that your commits have different hashes because they've been cherry-pick ed. 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, eg 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM