git branch --contains is slow with a lot of branches
- From
Mike Hommey <mh@glandium.org>
- Date
- Mar 31, 2015, 01:45 UTC
- Message-ID
- <20150331014511.GA28418@glandium.org>
Hi,
Sometimes I want to know what (possibly remote) branch contains a given commit. The repository where I do that has thousands of branches:
$ git for-each-ref | wc -l 7657
And a lot of commits:
$ git rev-list --all | wc -l 538174
Using git branch --contains can be a very expensive thing:
$ time git branch --contains 0812b94 --all > /dev/null
real 3m0.871s user 3m0.828s sys 0m0.084s
I'd argue this shouldn't take much more time than enumerating all revs:
$ time git rev-list --all | wc -l 538174
real 0m4.842s user 0m4.488s sys 0m1.332s
This can be reproduced to a certain degree with the git git repo:
$ git clone https://github.com/git/git $ cd git $ for i in $(seq 1 1000); do git branch branch$i master; done $ git gc # will pack the refs $ time git rev-list --all | wc -l 40886
real 0m0.505s user 0m0.464s sys 0m0.108s
$ time git branch --contains v2.0.0 > /dev/null
real 0m6.207s user 0m6.204s sys 0m0.004s
(especially in this case where all branches point to the same commit)
It's also essentially linear on the number of branches:
$ for i in $(seq 1001 7000); do git branch branch$i master; done $ git gc $ time git rev-list --all | wc -l 40886
real 0m0.493s user 0m0.484s sys 0m0.076s
$ time git branch --contains v2.0.0 > /dev/null
real 0m43.446s user 0m43.436s sys 0m0.040s
Mike