0

I would like to do the following command from Python script using dulwich:

$ git branch --contains <myCommitSha> | wc -l

What I intend is to check if a particular commit (sha) is placed in more than one branches.

Of course I thought that I can execute the above command from Python and parse the output (parse the number of branches), but that's the last resort solution.

Any other ideas/comments? Thanks in advance.

Blaise
  • 7,230
  • 6
  • 43
  • 53
  • executing the command is the way to go – that’s how you work with git. – Chronial Jan 25 '13 at 13:26
  • Thanks @ddotsenko, @Chronial, just wanted to make sure that there is no other way dulwich provides the `git branch --contains` output within Python code (I really wanted to avoid executing external process)? – Blaise Jan 25 '13 at 13:42

4 Answers4

8

Just in case someone was wondering how to do this now using gitpython:

repo.git.branch('--contains', YOURSHA)
harishkb
  • 406
  • 3
  • 7
2

Since branches are just pointers to random commits and they don't "describe" trees in any way, there is nothing linking some random commit TO a branch.

The only sensible way I would take to look up if a given commit is an ancestor of a commit to which some branch points is to traverse all ancestor chains from branch-top commit down.

In other words, in dulwich I would iterate over branches and traverse backwards to see if a sha is on the chain.

I am rather certain that's exactly what git branch --contains <myCommitSha> does as I am not aware of any other shortcut.

Since your choice is (a) make python do the iteration or (b) make C do same iteration, I'd just go with C. :)

ddotsenko
  • 4,926
  • 25
  • 24
1

There is no built-in function for this, but you can of course implement this yourself.

You can also just do something like this (untested):

branches = [ref for ref in repo.refs.keys("refs/heads/") if
            any((True for commit in repo.get_walker(include=[repo.refs[ref]])
                 if commit.id == YOURSHA))]

This will give you a list of all the branch heads that contain the given commit, but will have a runtime of O(n*m), n beeing the amount of commits in your repo, m beeing the amount of branches. The git implementation probably has a runtime of O(n).

Chronial
  • 66,706
  • 14
  • 93
  • 99
1

In case anyone uses GitPython and wants all branches

import git
gLocal = git.Git("<LocalRepoLocation>")
gLocal.branch('-a','--contains', '<CommitSHA>').split('\n')
joydeba
  • 778
  • 1
  • 9
  • 24