Tree:
31e8595a11
main
maint
master
next
seen
todo
gitgui-0.10.0
gitgui-0.10.1
gitgui-0.10.2
gitgui-0.11.0
gitgui-0.12.0
gitgui-0.13.0
gitgui-0.14.0
gitgui-0.15.0
gitgui-0.16.0
gitgui-0.17.0
gitgui-0.18.0
gitgui-0.19.0
gitgui-0.20.0
gitgui-0.21.0
gitgui-0.6.0
gitgui-0.6.1
gitgui-0.6.2
gitgui-0.6.3
gitgui-0.6.4
gitgui-0.6.5
gitgui-0.7.0
gitgui-0.7.0-rc1
gitgui-0.7.1
gitgui-0.7.2
gitgui-0.7.3
gitgui-0.7.4
gitgui-0.7.5
gitgui-0.8.0
gitgui-0.8.1
gitgui-0.8.2
gitgui-0.8.3
gitgui-0.8.4
gitgui-0.9.0
gitgui-0.9.1
gitgui-0.9.2
gitgui-0.9.3
junio-gpg-pub
v0.99
v0.99.1
v0.99.2
v0.99.3
v0.99.4
v0.99.5
v0.99.6
v0.99.7
v0.99.7a
v0.99.7b
v0.99.7c
v0.99.7d
v0.99.8
v0.99.8a
v0.99.8b
v0.99.8c
v0.99.8d
v0.99.8e
v0.99.8f
v0.99.8g
v0.99.9
v0.99.9a
v0.99.9b
v0.99.9c
v0.99.9d
v0.99.9e
v0.99.9f
v0.99.9g
v0.99.9h
v0.99.9i
v0.99.9j
v0.99.9k
v0.99.9l
v0.99.9m
v0.99.9n
v1.0.0
v1.0.0a
v1.0.0b
v1.0.1
v1.0.10
v1.0.11
v1.0.12
v1.0.13
v1.0.2
v1.0.3
v1.0.4
v1.0.5
v1.0.6
v1.0.7
v1.0.8
v1.0.9
v1.0rc1
v1.0rc2
v1.0rc3
v1.0rc4
v1.0rc5
v1.0rc6
v1.1.0
v1.1.1
v1.1.2
v1.1.3
v1.1.4
v1.1.5
v1.1.6
v1.2.0
v1.2.1
v1.2.2
v1.2.3
v1.2.4
v1.2.5
v1.2.6
v1.3.0
v1.3.0-rc1
v1.3.0-rc2
v1.3.0-rc3
v1.3.0-rc4
v1.3.1
v1.3.2
v1.3.3
v1.4.0
v1.4.0-rc1
v1.4.0-rc2
v1.4.1
v1.4.1-rc1
v1.4.1-rc2
v1.4.1.1
v1.4.2
v1.4.2-rc1
v1.4.2-rc2
v1.4.2-rc3
v1.4.2-rc4
v1.4.2.1
v1.4.2.2
v1.4.2.3
v1.4.2.4
v1.4.3
v1.4.3-rc1
v1.4.3-rc2
v1.4.3-rc3
v1.4.3.1
v1.4.3.2
v1.4.3.3
v1.4.3.4
v1.4.3.5
v1.4.4
v1.4.4-rc1
v1.4.4-rc2
v1.4.4.1
v1.4.4.2
v1.4.4.3
v1.4.4.4
v1.4.4.5
v1.5.0
v1.5.0-rc0
v1.5.0-rc1
v1.5.0-rc2
v1.5.0-rc3
v1.5.0-rc4
v1.5.0.1
v1.5.0.2
v1.5.0.3
v1.5.0.4
v1.5.0.5
v1.5.0.6
v1.5.0.7
v1.5.1
v1.5.1-rc1
v1.5.1-rc2
v1.5.1-rc3
v1.5.1.1
v1.5.1.2
v1.5.1.3
v1.5.1.4
v1.5.1.5
v1.5.1.6
v1.5.2
v1.5.2-rc0
v1.5.2-rc1
v1.5.2-rc2
v1.5.2-rc3
v1.5.2.1
v1.5.2.2
v1.5.2.3
v1.5.2.4
v1.5.2.5
v1.5.3
v1.5.3-rc0
v1.5.3-rc1
v1.5.3-rc2
v1.5.3-rc3
v1.5.3-rc4
v1.5.3-rc5
v1.5.3-rc6
v1.5.3-rc7
v1.5.3.1
v1.5.3.2
v1.5.3.3
v1.5.3.4
v1.5.3.5
v1.5.3.6
v1.5.3.7
v1.5.3.8
v1.5.4
v1.5.4-rc0
v1.5.4-rc1
v1.5.4-rc2
v1.5.4-rc3
v1.5.4-rc4
v1.5.4-rc5
v1.5.4.1
v1.5.4.2
v1.5.4.3
v1.5.4.4
v1.5.4.5
v1.5.4.6
v1.5.4.7
v1.5.5
v1.5.5-rc0
v1.5.5-rc1
v1.5.5-rc2
v1.5.5-rc3
v1.5.5.1
v1.5.5.2
v1.5.5.3
v1.5.5.4
v1.5.5.5
v1.5.5.6
v1.5.6
v1.5.6-rc0
v1.5.6-rc1
v1.5.6-rc2
v1.5.6-rc3
v1.5.6.1
v1.5.6.2
v1.5.6.3
v1.5.6.4
v1.5.6.5
v1.5.6.6
v1.6.0
v1.6.0-rc0
v1.6.0-rc1
v1.6.0-rc2
v1.6.0-rc3
v1.6.0.1
v1.6.0.2
v1.6.0.3
v1.6.0.4
v1.6.0.5
v1.6.0.6
v1.6.1
v1.6.1-rc1
v1.6.1-rc2
v1.6.1-rc3
v1.6.1-rc4
v1.6.1.1
v1.6.1.2
v1.6.1.3
v1.6.1.4
v1.6.2
v1.6.2-rc0
v1.6.2-rc1
v1.6.2-rc2
v1.6.2.1
v1.6.2.2
v1.6.2.3
v1.6.2.4
v1.6.2.5
v1.6.3
v1.6.3-rc0
v1.6.3-rc1
v1.6.3-rc2
v1.6.3-rc3
v1.6.3-rc4
v1.6.3.1
v1.6.3.2
v1.6.3.3
v1.6.3.4
v1.6.4
v1.6.4-rc0
v1.6.4-rc1
v1.6.4-rc2
v1.6.4-rc3
v1.6.4.1
v1.6.4.2
v1.6.4.3
v1.6.4.4
v1.6.4.5
v1.6.5
v1.6.5-rc0
v1.6.5-rc1
v1.6.5-rc2
v1.6.5-rc3
v1.6.5.1
v1.6.5.2
v1.6.5.3
v1.6.5.4
v1.6.5.5
v1.6.5.6
v1.6.5.7
v1.6.5.8
v1.6.5.9
v1.6.6
v1.6.6-rc0
v1.6.6-rc1
v1.6.6-rc2
v1.6.6-rc3
v1.6.6-rc4
v1.6.6.1
v1.6.6.2
v1.6.6.3
v1.7.0
v1.7.0-rc0
v1.7.0-rc1
v1.7.0-rc2
v1.7.0.1
v1.7.0.2
v1.7.0.3
v1.7.0.4
v1.7.0.5
v1.7.0.6
v1.7.0.7
v1.7.0.8
v1.7.0.9
v1.7.1
v1.7.1-rc0
v1.7.1-rc1
v1.7.1-rc2
v1.7.1.1
v1.7.1.2
v1.7.1.3
v1.7.1.4
v1.7.10
v1.7.10-rc0
v1.7.10-rc1
v1.7.10-rc2
v1.7.10-rc3
v1.7.10-rc4
v1.7.10.1
v1.7.10.2
v1.7.10.3
v1.7.10.4
v1.7.10.5
v1.7.11
v1.7.11-rc0
v1.7.11-rc1
v1.7.11-rc2
v1.7.11-rc3
v1.7.11.1
v1.7.11.2
v1.7.11.3
v1.7.11.4
v1.7.11.5
v1.7.11.6
v1.7.11.7
v1.7.12
v1.7.12-rc0
v1.7.12-rc1
v1.7.12-rc2
v1.7.12-rc3
v1.7.12.1
v1.7.12.2
v1.7.12.3
v1.7.12.4
v1.7.2
v1.7.2-rc0
v1.7.2-rc1
v1.7.2-rc2
v1.7.2-rc3
v1.7.2.1
v1.7.2.2
v1.7.2.3
v1.7.2.4
v1.7.2.5
v1.7.3
v1.7.3-rc0
v1.7.3-rc1
v1.7.3-rc2
v1.7.3.1
v1.7.3.2
v1.7.3.3
v1.7.3.4
v1.7.3.5
v1.7.4
v1.7.4-rc0
v1.7.4-rc1
v1.7.4-rc2
v1.7.4-rc3
v1.7.4.1
v1.7.4.2
v1.7.4.3
v1.7.4.4
v1.7.4.5
v1.7.5
v1.7.5-rc0
v1.7.5-rc1
v1.7.5-rc2
v1.7.5-rc3
v1.7.5.1
v1.7.5.2
v1.7.5.3
v1.7.5.4
v1.7.6
v1.7.6-rc0
v1.7.6-rc1
v1.7.6-rc2
v1.7.6-rc3
v1.7.6.1
v1.7.6.2
v1.7.6.3
v1.7.6.4
v1.7.6.5
v1.7.6.6
v1.7.7
v1.7.7-rc0
v1.7.7-rc1
v1.7.7-rc2
v1.7.7-rc3
v1.7.7.1
v1.7.7.2
v1.7.7.3
v1.7.7.4
v1.7.7.5
v1.7.7.6
v1.7.7.7
v1.7.8
v1.7.8-rc0
v1.7.8-rc1
v1.7.8-rc2
v1.7.8-rc3
v1.7.8-rc4
v1.7.8.1
v1.7.8.2
v1.7.8.3
v1.7.8.4
v1.7.8.5
v1.7.8.6
v1.7.9
v1.7.9-rc0
v1.7.9-rc1
v1.7.9-rc2
v1.7.9.1
v1.7.9.2
v1.7.9.3
v1.7.9.4
v1.7.9.5
v1.7.9.6
v1.7.9.7
v1.8.0
v1.8.0-rc0
v1.8.0-rc1
v1.8.0-rc2
v1.8.0-rc3
v1.8.0.1
v1.8.0.2
v1.8.0.3
v1.8.1
v1.8.1-rc0
v1.8.1-rc1
v1.8.1-rc2
v1.8.1-rc3
v1.8.1.1
v1.8.1.2
v1.8.1.3
v1.8.1.4
v1.8.1.5
v1.8.1.6
v1.8.2
v1.8.2-rc0
v1.8.2-rc1
v1.8.2-rc2
v1.8.2-rc3
v1.8.2.1
v1.8.2.2
v1.8.2.3
v1.8.3
v1.8.3-rc0
v1.8.3-rc1
v1.8.3-rc2
v1.8.3-rc3
v1.8.3.1
v1.8.3.2
v1.8.3.3
v1.8.3.4
v1.8.4
v1.8.4-rc0
v1.8.4-rc1
v1.8.4-rc2
v1.8.4-rc3
v1.8.4-rc4
v1.8.4.1
v1.8.4.2
v1.8.4.3
v1.8.4.4
v1.8.4.5
v1.8.5
v1.8.5-rc0
v1.8.5-rc1
v1.8.5-rc2
v1.8.5-rc3
v1.8.5.1
v1.8.5.2
v1.8.5.3
v1.8.5.4
v1.8.5.5
v1.8.5.6
v1.9-rc0
v1.9-rc1
v1.9-rc2
v1.9.0
v1.9.0-rc3
v1.9.1
v1.9.2
v1.9.3
v1.9.4
v1.9.5
v2.0.0
v2.0.0-rc0
v2.0.0-rc1
v2.0.0-rc2
v2.0.0-rc3
v2.0.0-rc4
v2.0.1
v2.0.2
v2.0.3
v2.0.4
v2.0.5
v2.1.0
v2.1.0-rc0
v2.1.0-rc1
v2.1.0-rc2
v2.1.1
v2.1.2
v2.1.3
v2.1.4
v2.10.0
v2.10.0-rc0
v2.10.0-rc1
v2.10.0-rc2
v2.10.1
v2.10.2
v2.10.3
v2.10.4
v2.10.5
v2.11.0
v2.11.0-rc0
v2.11.0-rc1
v2.11.0-rc2
v2.11.0-rc3
v2.11.1
v2.11.2
v2.11.3
v2.11.4
v2.12.0
v2.12.0-rc0
v2.12.0-rc1
v2.12.0-rc2
v2.12.1
v2.12.2
v2.12.3
v2.12.4
v2.12.5
v2.13.0
v2.13.0-rc0
v2.13.0-rc1
v2.13.0-rc2
v2.13.1
v2.13.2
v2.13.3
v2.13.4
v2.13.5
v2.13.6
v2.13.7
v2.14.0
v2.14.0-rc0
v2.14.0-rc1
v2.14.1
v2.14.2
v2.14.3
v2.14.4
v2.14.5
v2.14.6
v2.15.0
v2.15.0-rc0
v2.15.0-rc1
v2.15.0-rc2
v2.15.1
v2.15.2
v2.15.3
v2.15.4
v2.16.0
v2.16.0-rc0
v2.16.0-rc1
v2.16.0-rc2
v2.16.1
v2.16.2
v2.16.3
v2.16.4
v2.16.5
v2.16.6
v2.17.0
v2.17.0-rc0
v2.17.0-rc1
v2.17.0-rc2
v2.17.1
v2.17.2
v2.17.3
v2.17.4
v2.17.5
v2.17.6
v2.18.0
v2.18.0-rc0
v2.18.0-rc1
v2.18.0-rc2
v2.18.1
v2.18.2
v2.18.3
v2.18.4
v2.18.5
v2.19.0
v2.19.0-rc0
v2.19.0-rc1
v2.19.0-rc2
v2.19.1
v2.19.2
v2.19.3
v2.19.4
v2.19.5
v2.19.6
v2.2.0
v2.2.0-rc0
v2.2.0-rc1
v2.2.0-rc2
v2.2.0-rc3
v2.2.1
v2.2.2
v2.2.3
v2.20.0
v2.20.0-rc0
v2.20.0-rc1
v2.20.0-rc2
v2.20.1
v2.20.2
v2.20.3
v2.20.4
v2.20.5
v2.21.0
v2.21.0-rc0
v2.21.0-rc1
v2.21.0-rc2
v2.21.1
v2.21.2
v2.21.3
v2.21.4
v2.22.0
v2.22.0-rc0
v2.22.0-rc1
v2.22.0-rc2
v2.22.0-rc3
v2.22.1
v2.22.2
v2.22.3
v2.22.4
v2.22.5
v2.23.0
v2.23.0-rc0
v2.23.0-rc1
v2.23.0-rc2
v2.23.1
v2.23.2
v2.23.3
v2.23.4
v2.24.0
v2.24.0-rc0
v2.24.0-rc1
v2.24.0-rc2
v2.24.1
v2.24.2
v2.24.3
v2.24.4
v2.25.0
v2.25.0-rc0
v2.25.0-rc1
v2.25.0-rc2
v2.25.1
v2.25.2
v2.25.3
v2.25.4
v2.25.5
v2.26.0
v2.26.0-rc0
v2.26.0-rc1
v2.26.0-rc2
v2.26.1
v2.26.2
v2.26.3
v2.27.0
v2.27.0-rc0
v2.27.0-rc1
v2.27.0-rc2
v2.27.1
v2.28.0
v2.28.0-rc0
v2.28.0-rc1
v2.28.0-rc2
v2.28.1
v2.29.0
v2.29.0-rc0
v2.29.0-rc1
v2.29.0-rc2
v2.29.1
v2.29.2
v2.29.3
v2.3.0
v2.3.0-rc0
v2.3.0-rc1
v2.3.0-rc2
v2.3.1
v2.3.10
v2.3.2
v2.3.3
v2.3.4
v2.3.5
v2.3.6
v2.3.7
v2.3.8
v2.3.9
v2.30.0
v2.30.0-rc0
v2.30.0-rc1
v2.30.0-rc2
v2.30.1
v2.30.2
v2.30.3
v2.30.4
v2.30.5
v2.30.6
v2.30.7
v2.30.8
v2.30.9
v2.31.0
v2.31.0-rc0
v2.31.0-rc1
v2.31.0-rc2
v2.31.1
v2.31.2
v2.31.3
v2.31.4
v2.31.5
v2.31.6
v2.31.7
v2.31.8
v2.32.0
v2.32.0-rc0
v2.32.0-rc1
v2.32.0-rc2
v2.32.0-rc3
v2.32.1
v2.32.2
v2.32.3
v2.32.4
v2.32.5
v2.32.6
v2.32.7
v2.33.0
v2.33.0-rc0
v2.33.0-rc1
v2.33.0-rc2
v2.33.1
v2.33.2
v2.33.3
v2.33.4
v2.33.5
v2.33.6
v2.33.7
v2.33.8
v2.34.0
v2.34.0-rc0
v2.34.0-rc1
v2.34.0-rc2
v2.34.1
v2.34.2
v2.34.3
v2.34.4
v2.34.5
v2.34.6
v2.34.7
v2.34.8
v2.35.0
v2.35.0-rc0
v2.35.0-rc1
v2.35.0-rc2
v2.35.1
v2.35.2
v2.35.3
v2.35.4
v2.35.5
v2.35.6
v2.35.7
v2.35.8
v2.36.0
v2.36.0-rc0
v2.36.0-rc1
v2.36.0-rc2
v2.36.1
v2.36.2
v2.36.3
v2.36.4
v2.36.5
v2.36.6
v2.37.0
v2.37.0-rc0
v2.37.0-rc1
v2.37.0-rc2
v2.37.1
v2.37.2
v2.37.3
v2.37.4
v2.37.5
v2.37.6
v2.37.7
v2.38.0
v2.38.0-rc0
v2.38.0-rc1
v2.38.0-rc2
v2.38.1
v2.38.2
v2.38.3
v2.38.4
v2.38.5
v2.39.0
v2.39.0-rc0
v2.39.0-rc1
v2.39.0-rc2
v2.39.1
v2.39.2
v2.39.3
v2.4.0
v2.4.0-rc0
v2.4.0-rc1
v2.4.0-rc2
v2.4.0-rc3
v2.4.1
v2.4.10
v2.4.11
v2.4.12
v2.4.2
v2.4.3
v2.4.4
v2.4.5
v2.4.6
v2.4.7
v2.4.8
v2.4.9
v2.40.0
v2.40.0-rc0
v2.40.0-rc1
v2.40.0-rc2
v2.40.1
v2.41.0
v2.41.0-rc0
v2.41.0-rc1
v2.41.0-rc2
v2.5.0
v2.5.0-rc0
v2.5.0-rc1
v2.5.0-rc2
v2.5.0-rc3
v2.5.1
v2.5.2
v2.5.3
v2.5.4
v2.5.5
v2.5.6
v2.6.0
v2.6.0-rc0
v2.6.0-rc1
v2.6.0-rc2
v2.6.0-rc3
v2.6.1
v2.6.2
v2.6.3
v2.6.4
v2.6.5
v2.6.6
v2.6.7
v2.7.0
v2.7.0-rc0
v2.7.0-rc1
v2.7.0-rc2
v2.7.0-rc3
v2.7.1
v2.7.2
v2.7.3
v2.7.4
v2.7.5
v2.7.6
v2.8.0
v2.8.0-rc0
v2.8.0-rc1
v2.8.0-rc2
v2.8.0-rc3
v2.8.0-rc4
v2.8.1
v2.8.2
v2.8.3
v2.8.4
v2.8.5
v2.8.6
v2.9.0
v2.9.0-rc0
v2.9.0-rc1
v2.9.0-rc2
v2.9.1
v2.9.2
v2.9.3
v2.9.4
v2.9.5
${ noResults }
8472 Commits (31e8595a1132187f99792a4b889c2128cd9253ef)
Author | SHA1 | Message | Date |
---|---|---|---|
![]() |
a91cc7fad0 |
strbuf: add and use strbuf_insertstr()
Add a function for inserting a C string into a strbuf. Use it throughout the source to get rid of magic string length constants and explicit strlen() calls. Like strbuf_addstr(), implement it as an inline function to avoid the implicit strlen() calls to cause runtime overhead. Helped-by: Taylor Blau <me@ttaylorr.com> Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
887a0fd573 |
add: change advice config variables used by the add API
advice.addNothing config variable is used to control the visibility of two advice messages in the add library. This config variable is replaced by two new variables, whose names are more clear and relevant to the two cases. Also add the two new variables to the documentation. Signed-off-by: Heba Waly <heba.waly@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
079f970971 |
name-rev: sort tip names before applying
name_ref() is called for each ref and checks if its a better name for the referenced commit. If that's the case it remembers it and checks if a name based on it is better for its ancestors as well. This in done in the the order for_each_ref() imposes on us. That might not be optimal. If bad names happen to be encountered first (as defined by is_better_name()), names derived from them may spread to a lot of commits, only to be replaced by better names later. Setting better names first can avoid that. is_better_name() prefers tags, short distances and old references. The distance is a measure that we need to calculate for each candidate commit, but the other two properties are not dependent on the relationships of commits. Sorting the refs by them should yield better performance than the essentially random order we currently use. And applying older references first should also help to reduce rework due to the fact that older commits have less ancestors than newer ones. So add all details of names to the tip table first, then sort them to prefer tags and older references and then apply them in this order. Here's the performance as measures by hyperfine for the Linux repo before: Benchmark #1: ./git -C ../linux/ name-rev --all Time (mean ± σ): 851.1 ms ± 4.5 ms [User: 806.7 ms, System: 44.4 ms] Range (min … max): 845.9 ms … 859.5 ms 10 runs ... and with this patch: Benchmark #1: ./git -C ../linux/ name-rev --all Time (mean ± σ): 736.2 ms ± 8.7 ms [User: 688.4 ms, System: 47.5 ms] Range (min … max): 726.0 ms … 755.2 ms 10 runs Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
2d53975488 |
name-rev: release unused name strings
name_rev() assigns a name to a commit and its parents and grandparents and so on. Commits share their name string with their first parent, which in turn does the same, recursively to the root. That saves a lot of allocations. When a better name is found, the old name is replaced, but its memory is not released. That leakage can become significant. Can we release these old strings exactly once even though they are referenced multiple times? Yes, indeed -- we can make use of the fact that name_rev() visits the ancestors of a commit after it set a new name for it and tries to update their names as well. Members of the first ancestral line have the same taggerdate and from_tag values, but a higher distance value than their child commit at generation 0. These are the only criteria used by is_better_name(). Lower distance values are considered better, so a name that is better for a child will also be better for its parent and grandparent etc. That means we can free(3) an inferior name at generation 0 and rely on name_rev() to replace all references in ancestors as well. If we do that then we need to stop using the string pointer alone to distinguish new empty rev_name slots from initialized ones, though, as it technically becomes invalid after the free(3) call -- even though its value is still different from NULL. We can check the generation value first, as empty slots will have it initialized to 0, and for the actual generation 0 we'll set a new valid name right after the create_or_update_name() call that releases the string. For the Chromium repo, releasing superceded names reduces the memory footprint of name-rev --all significantly. Here's the output of GNU time before: 0.98user 0.48system 0:01.46elapsed 99%CPU (0avgtext+0avgdata 2601812maxresident)k 0inputs+0outputs (0major+571470minor)pagefaults 0swaps ... and with this patch: 1.01user 0.26system 0:01.28elapsed 100%CPU (0avgtext+0avgdata 1559196maxresident)k 0inputs+0outputs (0major+314370minor)pagefaults 0swaps It also gets faster; hyperfine before: Benchmark #1: ./git -C ../chromium/src name-rev --all Time (mean ± σ): 1.534 s ± 0.006 s [User: 1.039 s, System: 0.494 s] Range (min … max): 1.522 s … 1.542 s 10 runs ... and with this patch: Benchmark #1: ./git -C ../chromium/src name-rev --all Time (mean ± σ): 1.338 s ± 0.006 s [User: 1.047 s, System: 0.291 s] Range (min … max): 1.327 s … 1.346 s 10 runs For the Linux repo it doesn't pay off; memory usage only gets down from: 0.76user 0.03system 0:00.80elapsed 99%CPU (0avgtext+0avgdata 292848maxresident)k 0inputs+0outputs (0major+44579minor)pagefaults 0swaps ... to: 0.78user 0.03system 0:00.81elapsed 100%CPU (0avgtext+0avgdata 284696maxresident)k 0inputs+0outputs (0major+44892minor)pagefaults 0swaps The runtime actually increases slightly from: Benchmark #1: ./git -C ../linux/ name-rev --all Time (mean ± σ): 828.8 ms ± 5.0 ms [User: 797.2 ms, System: 31.6 ms] Range (min … max): 824.1 ms … 838.9 ms 10 runs ... to: Benchmark #1: ./git -C ../linux/ name-rev --all Time (mean ± σ): 847.6 ms ± 3.4 ms [User: 807.9 ms, System: 39.6 ms] Range (min … max): 843.4 ms … 854.3 ms 10 runs Why is that? In the Chromium repo, ca. 44000 free(3) calls in create_or_update_name() release almost 1GB, while in the Linux repo 240000+ calls release a bit more than 5MB, so the average discarded name is ca. 1000x longer in the latter. Overall I think it's the right tradeoff to make, as it helps curb the memory usage in repositories with big discarded names, and the added overhead is small. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
977dc1912b |
name-rev: generate name strings only if they are better
Leave setting the tip_name member of struct rev_name to callers of create_or_update_name(). This avoids allocations for names that are rejected by that function. Here's how this affects the runtime when working with a fresh clone of Git's own repository; performance numbers by hyperfine before: Benchmark #1: ./git -C ../git-pristine/ name-rev --all Time (mean ± σ): 437.8 ms ± 4.0 ms [User: 422.5 ms, System: 15.2 ms] Range (min … max): 432.8 ms … 446.3 ms 10 runs ... and with this patch: Benchmark #1: ./git -C ../git-pristine/ name-rev --all Time (mean ± σ): 408.5 ms ± 1.4 ms [User: 387.2 ms, System: 21.2 ms] Range (min … max): 407.1 ms … 411.7 ms 10 runs Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
1c56fc2084 |
name-rev: pre-size buffer in get_parent_name()
We can calculate the size of new name easily and precisely. Open-code the xstrfmt() calls and grow the buffers as needed before filling them. This provides a surprisingly large benefit when working with the Chromium repository; here are the numbers measured using hyperfine before: Benchmark #1: ./git -C ../chromium/src name-rev --all Time (mean ± σ): 5.822 s ± 0.013 s [User: 5.304 s, System: 0.516 s] Range (min … max): 5.803 s … 5.837 s 10 runs ... and with this patch: Benchmark #1: ./git -C ../chromium/src name-rev --all Time (mean ± σ): 1.527 s ± 0.003 s [User: 1.015 s, System: 0.511 s] Range (min … max): 1.524 s … 1.535 s 10 runs Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
ddc42ec786 |
name-rev: factor out get_parent_name()
Reduce nesting by moving code to come up with a name for the parent into its own function. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
f13ca7cef5 |
name-rev: put struct rev_name into commit slab
The commit slab commit_rev_name contains a pointer to a struct rev_name, and the actual struct is allocated separatly. Avoid that allocation and pointer indirection by storing the full struct in the commit slab. Use the tip_name member pointer to determine if the returned struct is initialized. Performance in the Linux repository measured with hyperfine before: Benchmark #1: ./git -C ../linux/ name-rev --all Time (mean ± σ): 953.5 ms ± 6.3 ms [User: 901.2 ms, System: 52.1 ms] Range (min … max): 945.2 ms … 968.5 ms 10 runs ... and with this patch: Benchmark #1: ./git -C ../linux/ name-rev --all Time (mean ± σ): 851.0 ms ± 3.1 ms [User: 807.4 ms, System: 43.6 ms] Range (min … max): 846.7 ms … 857.0 ms 10 runs Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
d689d6d82f |
name-rev: don't _peek() in create_or_update_name()
Look up the commit slab slot for the commit once using commit_rev_name_at() and populate it in case it is empty, instead of checking for emptiness in a separate step using commit_rev_name_peek() via get_commit_rev_name(). Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
15a4205d96 |
name-rev: don't leak path copy in name_ref()
name_ref() duplicates the path string and passes it to name_rev(), which either puts it into a commit slab or ignores it if there is already a better name, leaking it. Move the duplication to name_rev() and release the copy in the latter case. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
36d2419c9a |
name-rev: respect const qualifier
Keep the const qualifier of the first parameter of get_rev_name() even when casting the object pointer to a commit pointer, and further for the parameter of get_commit_rev_name(), as all these uses are read-only. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
71620ca86c |
name-rev: remove unused typedef
The type alias became unused with
|
5 years ago |
![]() |
3e2feb0d64 |
name-rev: rewrite create_or_update_name()
This code was moved straight out of name_rev(). As such, we inherited the "goto" to jump from an if into an else-if. We also inherited the fact that "nothing to do -- return NULL" is handled last. Rewrite the function to first handle the "nothing to do" case. Then we can handle the conditional allocation early before going on to populate the struct. No need for goto-ing. Signed-off-by: Martin Ågren <martin.agren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
a21781011f |
index-pack: downgrade twice-resolved REF_DELTA to die()
When we're resolving a REF_DELTA, we compare-and-swap its type from REF_DELTA to whatever real type the base object has, as discussed in |
5 years ago |
![]() |
a7df60cac8 |
commit-graph.h: use odb in 'load_commit_graph_one_fd_st'
Apply a similar treatment as in the previous patch to pass a 'struct object_directory *' through the 'load_commit_graph_one_fd_st' initializer, too. This prevents a potential bug where a pointer comparison is made to a NULL 'g->odb', which would cause the commit-graph machinery to think that a pair of commit-graphs belonged to different alternates when in fact they do not (i.e., in the case of no '--object-dir'). Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
ad2dd5bb63 |
commit-graph.c: remove path normalization, comparison
As of the previous patch, all calls to 'commit-graph.c' functions which perform path normalization (for e.g., 'get_commit_graph_filename()') are of the form 'ctx->odb->path', which is always in normalized form. Now that there are no callers passing non-normalized paths to these functions, ensure that future callers are bound by the same restrictions by making these functions take a 'struct object_directory *' instead of a 'const char *'. To match, replace all calls with arguments of the form 'ctx->odb->path' with 'ctx->odb' To recover the path, functions that perform path manipulation simply use 'odb->path'. Further, avoid string comparisons with arguments of the form 'odb->path', and instead prefer raw pointer comparisons, which accomplish the same effect, but are far less brittle. This has a pleasant side-effect of making these functions much more robust to paths that cannot be normalized by 'normalize_path_copy()', i.e., because they are outside of the current working directory. For example, prior to this patch, Valgrind reports that the following uninitialized memory read [1]: $ ( cd t && GIT_DIR=../.git valgrind git rev-parse HEAD^ ) because 'normalize_path_copy()' can't normalize '../.git' (since it's relative to but above of the current working directory) [2]. By using a 'struct object_directory *' directly, 'get_commit_graph_filename()' does not need to normalize, because all paths are relative to the current working directory since they are always read from the '->path' of an object directory. [1]: https://lore.kernel.org/git/20191027042116.GA5801@sigill.intra.peff.net. [2]: The bug here is that 'get_commit_graph_filename()' returns the result of 'normalize_path_copy()' without checking the return value. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
13c2499249 |
commit-graph.h: store object directory in 'struct commit_graph'
In a previous patch, the 'char *object_dir' in 'struct commit_graph' was replaced with a 'struct object_directory'. This patch applies the same treatment to 'struct commit_graph', which is another intermediate step towards getting rid of all path normalization in 'commit-graph.c'. Instead of taking a 'char *object_dir', functions that construct a 'struct commit_graph' now take a 'struct object_directory *'. Any code that needs an object directory path use '->path' instead. This ensures that all calls to functions that perform path normalization are given arguments which do not themselves require normalization. This prepares those functions to drop their normalization entirely, which will occur in the subsequent patch. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
0bd52e27e3 |
commit-graph.h: store an odb in 'struct write_commit_graph_context'
There are lots of places in 'commit-graph.h' where a function either has (or almost has) a full 'struct object_directory *', accesses '->path', and then throws away the rest of the struct. This can cause headaches when comparing the locations of object directories across alternates (e.g., in the case of deciding if two commit-graph layers can be merged). These paths are normalized with 'normalize_path_copy()' which mitigates some comparison issues, but not all [1]. Replace usage of 'char *object_dir' with 'odb->path' by storing a 'struct object_directory *' in the 'write_commit_graph_context' structure. This is an intermediate step towards getting rid of all path normalization in 'commit-graph.c'. Resolving a user-provided '--object-dir' argument now requires that we compare it to the known alternates for equality. Prior to this patch, an unknown '--object-dir' argument would silently exit with status zero. This can clearly lead to unintended behavior, such as verifying commit-graphs that aren't in a repository's own object store (or one of its alternates), or causing a typo to mask a legitimate commit-graph verification failure. Make this error non-silent by 'die()'-ing when the given '--object-dir' does not match any known alternate object store. [1]: In my testing, for example, I can get one side of the commit-graph code to fill object_dir with "./objects" and the other with just "objects". Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
e53ffe2704 |
sparse-checkout: escape all glob characters on write
The sparse-checkout patterns allow special globs according to fnmatch(3). When writing cone-mode patterns for paths containing these characters, they must be escaped. Use is_glob_special() to check which characters must be escaped this way, and add a path to the tests that contains all glob characters at once. Note that ']' is not special, since the initial bracket '[' is escaped. Reported-by: Jeff King <peff@peff.net> Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
e55682ea26 |
sparse-checkout: use C-style quotes in 'list' subcommand
When in cone mode, the 'git sparse-checkout list' subcommand lists the directories included in the sparse cone. When these directories contain odd characters, such as a backslash, then we need to use C-style quotes similar to 'git ls-tree'. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
bd64de42de |
sparse-checkout: unquote C-style strings over --stdin
If a user somehow creates a directory with an asterisk (*) or backslash (\), then the "git sparse-checkout set" command will struggle to provide the correct pattern in the sparse-checkout file. When not in cone mode, the provided pattern is written directly into the sparse-checkout file. However, in cone mode we expect a list of paths to directories and then we convert those into patterns. Even more specifically, the goal is to always allow the following from the root of a repo: git ls-tree --name-only -d HEAD | git sparse-checkout set --stdin The ls-tree command provides directory names with an unescaped asterisk. It also quotes the directories that contain an escaped backslash. We must remove these quotes, then keep the escaped backslashes. Use unquote_c_style() when parsing lines from stdin. Command-line arguments will be parsed as-is, assuming the user can do the correct level of escaping from their environment to match the exact directory names. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
d585f0e799 |
sparse-checkout: write escaped patterns in cone mode
If a user somehow creates a directory with an asterisk (*) or backslash (\), then the "git sparse-checkout set" command will struggle to provide the correct pattern in the sparse-checkout file. When not in cone mode, the provided pattern is written directly into the sparse-checkout file. However, in cone mode we expect a list of paths to directories and then we convert those into patterns. However, there is some care needed for the timing of these escapes. The in-memory pattern list is used to update the working directory before writing the patterns to disk. Thus, we need the command to have the unescaped names in the hashsets for the cone comparisons, then escape the patterns later. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
145136a95a |
C: use skip_prefix() to avoid hardcoded string length
We often skip an optional prefix in a string with a hardcoded constant, e.g. if (starts_with(string, "prefix")) string += 6; which is less error prone when written skip_prefix(string, "prefix", &string); Note that this changes a few error messages from "git reflog expire --expire=nonsense.timestamp", which used to complain by saying '--expire=nonsense.timestamp' is not a valid timestamp but with this change, we say 'nonsense.timestamp' is not a valid timestamp which is more technically correct (the string with --expire= as a prefix obviously cannot be a valid timestamp, but the error is about the part of the input without that prefix). Helped-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
b98d188581 |
sha1-file: allow check_object_signature() to handle any repo
Some callers of check_object_signature() can work on arbitrary repositories, but the repo does not get passed to this function. Instead, the_repository is always used internally. To fix possible inconsistencies, allow the function to receive a struct repository and make those callers pass on the repo being handled. Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
2dcde20e1c |
sha1-file: pass git_hash_algo to hash_object_file()
Allow hash_object_file() to work on arbitrary repos by introducing a git_hash_algo parameter. Change callers which have a struct repository pointer in their scope to pass on the git_hash_algo from the said repo. For all other callers, pass on the_hash_algo, which was already being used internally at hash_object_file(). This functionality will be used in the following patch to make check_object_signature() be able to work on arbitrary repos (which, in turn, will be used to fix an inconsistency at object.c:parse_object()). Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
c8123e72f6 |
streaming: allow open_istream() to handle any repo
Some callers of open_istream() at archive-tar.c and archive-zip.c are capable of working on arbitrary repositories but the repo struct is not passed down to open_istream(), which uses the_repository internally. For now, that's not a problem since the said callers are only being called with the_repository. But to be consistent and avoid future problems, let's allow open_istream() to receive a struct repository and use that instead of the_repository. This parameter addition will also be used in a future patch to make sha1-file.c:check_object_signature() be able to work on arbitrary repos. Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
2df1aa239c |
fetch: forgo full connectivity check if --filter
If a filter is specified, we do not need a full connectivity check on the contents of the packfile we just fetched; we only need to check that the objects referenced are promisor objects. This significantly speeds up fetches into repositories that have many promisor objects, because during the connectivity check, all promisor objects are enumerated (to mark them UNINTERESTING), and that takes a significant amount of time. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
50033772d5 |
connected: verify promisor-ness of partial clone
Commit
|
5 years ago |
![]() |
c56c48dd07 |
grep: ignore --recurse-submodules if --no-index is given
Since grep learned to recurse into submodules in
|
5 years ago |
![]() |
3b2885ec9b |
submodule: fix status of initialized but not cloned submodules
Original bash helper for "submodule status" was doing a check for initialized but not cloned submodules and prefixed the status with a minus sign in case no .git file or folder was found inside the submodule directory. This check was missed when the original port of the functionality from bash to C was done. Signed-off-by: Peter Kaestle <peter.kaestle@nokia.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
47dbf10d8a |
clone: fix --sparse option with URLs
The --sparse option was added to the clone builtin in
|
5 years ago |
![]() |
3c754067a1 |
sparse-checkout: create leading directories
The 'git init' command creates the ".git/info" directory and fills it with some default files. However, 'git worktree add' does not create the info directory for that worktree. This causes a problem when running "git sparse-checkout init" inside a worktree. While care was taken to allow the sparse-checkout config to be specific to a worktree, this initialization was untested. Safely create the leading directories for the sparse-checkout file. This is the safest thing to do even without worktrees, as a user could delete their ".git/info" directory and expect Git to recover safely. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
329e6ec397 |
config: fix typo in variable name
In git config use of the end_null variable to determine if we should be null terminating our output. While it is correct to say a string is "null terminated" the character is actually the "nul" character, so this malapropism is being fixed. Signed-off-by: Matthew Rogers <mattr94@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
767a9c417e |
rebase -i: stop checking out the tip of the branch to rebase
One of the first things done when using a sequencer-based rebase (ie. `rebase -i', `rebase -r', or `rebase -m') is to make a todo list. This requires knowledge of the commit range to rebase. To get the oid of the last commit of the range, the tip of the branch to rebase is checked out with prepare_branch_to_be_rebased(), then the oid of the head is read. After this, the tip of the branch is not even modified. The `am' backend, on the other hand, does not check out the branch. On big repositories, it's a performance penalty: with `rebase -i', the user may have to wait before editing the todo list while git is extracting the branch silently, and "quiet" rebases will be slower than `am'. Since we already have the oid of the tip of the branch in `opts->orig_head', it's useless to switch to this commit. This removes the call to prepare_branch_to_be_rebased() in do_interactive_rebase(), and adds a `orig_head' parameter to get_revision_ranges(). prepare_branch_to_be_rebased() is removed as it is no longer used. This introduces a visible change: as we do not switch on the tip of the branch to rebase, no reflog entry is created at the beginning of the rebase for it. Unscientific performance measurements, performed on linux.git, are as follow: Before this patch: $ time git rebase -m --onto v4.18 463fa44eec2fef50~ 463fa44eec2fef50 real 0m8,940s user 0m6,830s sys 0m2,121s After this patch: $ time git rebase -m --onto v4.18 463fa44eec2fef50~ 463fa44eec2fef50 real 0m1,834s user 0m0,916s sys 0m0,206s Reported-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Alban Gruin <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
92fb0db94c |
pack-objects: add checks for duplicate objects
Additional checks are added in have_duplicate_entry() and obj_is_packed() to avoid duplicate objects in the reuse bitmap. It was probably buggy to not have such a check before. Git as a client would never both asks for a tag by sha1 and specify "include-tag", but libgit2 will, so a libgit2 client cloning from a Git server would trigger the bug. If a client both asks for a tag by sha1 and specifies "include-tag", we may end up including the tag in the reuse bitmap (due to the first thing), and then later adding it to the packlist (due to the second). This results in duplicate objects in the pack, which git chokes on. We should notice that we are already including it when doing the include-tag portion, and avoid adding it to the packlist. The simplest place to fix this is right in add_ref_tag(), where we could avoid peeling the tag at all if we know that we are already including it. However, this pushes the check instead into have_duplicate_entry(). This fixes not only this case, but also means that we cannot have any similar problems lurking in other code. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
bb514de356 |
pack-objects: improve partial packfile reuse
The old code to reuse deltas from an existing packfile just tried to dump a whole segment of the pack verbatim. That's faster than the traditional way of actually adding objects to the packing list, but it didn't kick in very often. This new code is really going for a middle ground: do _some_ per-object work, but way less than we'd traditionally do. The general strategy of the new code is to make a bitmap of objects from the packfile we'll include, and then iterate over it, writing out each object exactly as it is in our on-disk pack, but _not_ adding it to our packlist (which costs memory, and increases the search space for deltas). One complication is that if we're omitting some objects, we can't set a delta against a base that we're not sending. So we have to check each object in try_partial_reuse() to make sure we have its delta. About performance, in the worst case we might have interleaved objects that we are sending or not sending, and we'd have as many chunks as objects. But in practice we send big chunks. For instance, packing torvalds/linux on GitHub servers now reused 6.5M objects, but only needed ~50k chunks. Helped-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
ff483026a9 |
builtin/pack-objects: introduce obj_is_packed()
Let's refactor the way we check if an object is packed by introducing obj_is_packed(). This function is now a simple wrapper around packlist_find(), but it will evolve in a following commit. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
e704fc7978 |
pack-objects: introduce pack.allowPackReuse
Let's make it possible to configure if we want pack reuse or not. The main reason it might not be wanted is probably debugging and performance testing, though pack reuse _might_ cause larger packs, because we wouldn't consider the reused objects as bases for finding new deltas. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
22a69fda19 |
git-rebase.txt: update description of --allow-empty-message
Commit
|
5 years ago |
![]() |
f1928f04b2 |
grep: use no. of cores as the default no. of threads
When --threads is not specified, git-grep will use 8 threads by default. This fixed number may be too many for machines with fewer cores and too little for machines with more cores. So, instead, use the number of logical cores available in the machine, which seems to result in the best overall performance: The following measurements correspond to the mean elapsed times for 30 git-grep executions in chromium's repository[1] with a 95% confidence interval (each set of 30 were performed after 2 warmup runs). Regex 1 is 'abcd[02]' and Regex 2 is '(static|extern) (int|double) \*'. | Working tree | Object Store ------|-------------------------------|-------------------------------- #ths | Regex 1 | Regex 2 | Regex 1 | Regex 2 ------|---------------|---------------|----------------|--------------- 32 | 2.92s ± 0.01 | 3.72s ± 0.21 | 5.36s ± 0.01 | 6.07s ± 0.01 16 | 2.84s ± 0.01 | 3.57s ± 0.21 | 5.05s ± 0.01 | 5.71s ± 0.01 > 8 | 2.53s ± 0.00 | 3.24s ± 0.21 | 4.86s ± 0.01 | 5.48s ± 0.01 4 | 2.43s ± 0.02 | 3.22s ± 0.20 | 5.22s ± 0.02 | 6.03s ± 0.02 2 | 3.06s ± 0.20 | 4.52s ± 0.01 | 7.52s ± 0.01 | 9.06s ± 0.01 1 | 6.16s ± 0.01 | 9.25s ± 0.02 | 14.10s ± 0.01 | 17.22s ± 0.01 The above tests were performed in a desktop running Debian 10.0 with Intel(R) Xeon(R) CPU E3-1230 V2 (4 cores w/ hyper-threading), 32GB of RAM and a 7200 rpm, SATA 3.1 HDD. Bellow, the tests were repeated for a machine with SSD: a Manjaro laptop with Intel(R) i7-7700HQ (4 cores w/ hyper-threading) and 16GB of RAM: | Working tree | Object Store ------|--------------------------------|-------------------------------- #ths | Regex 1 | Regex 2 | Regex 1 | Regex 2 ------|---------------|----------------|----------------|--------------- 32 | 3.29s ± 0.21 | 4.30s ± 0.01 | 6.30s ± 0.01 | 7.30s ± 0.02 16 | 3.19s ± 0.20 | 4.14s ± 0.02 | 5.91s ± 0.01 | 6.83s ± 0.01 > 8 | 2.90s ± 0.04 | 3.82s ± 0.20 | 5.70s ± 0.02 | 6.53s ± 0.01 4 | 2.84s ± 0.02 | 3.77s ± 0.20 | 6.19s ± 0.02 | 7.18s ± 0.02 2 | 3.73s ± 0.21 | 5.57s ± 0.02 | 9.28s ± 0.01 | 11.22s ± 0.01 1 | 7.48s ± 0.02 | 11.36s ± 0.03 | 17.75s ± 0.01 | 21.87s ± 0.08 [1]: chromium’s repo at commit 03ae96f (“Add filters testing at DSF=2”, 04-06-2019), after a 'git gc' execution. Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
70a9fef240 |
grep: move driver pre-load out of critical section
In builtin/grep.c:add_work() we pre-load the userdiff drivers before adding the grep_source in the todo list. This operation is currently being performed after acquiring the grep_mutex, but as it's already thread-safe, we don't need to protect it here. So let's move it out of the critical section which should avoid thread contention and improve performance. Running[1] `git grep --threads=8 abcd[02] HEAD` on chromium's repository[2], I got the following mean times for 30 executions after 2 warmups: Original | 6.2886s -------------------------|----------- Out of critical section | 5.7852s [1]: Tests performed on an i7-7700HQ with 16GB of RAM and SSD, running Manjaro Linux. [2]: chromium’s repo at commit 03ae96f (“Add filters testing at DSF=2”, 04-06-2019), after a 'git gc' execution. Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
1184a95ea2 |
grep: re-enable threads in non-worktree case
They were disabled at
|
5 years ago |
![]() |
6c307626f1 |
grep: protect packed_git [re-]initialization
Some fields in struct raw_object_store are lazy initialized by the thread-unsafe packfile.c:prepare_packed_git(). Although this function is present in the call stack of git-grep threads, all paths to it are currently protected by obj_read_lock() (and the main thread usually indirectly calls it before firing the worker threads, anyway). However, it's possible that future modifications add new unprotected paths to it, introducing a race condition. Because errors derived from it wouldn't happen often, it could be hard to detect. So to prevent future headaches, let's force eager initialization of packed_git when setting git-grep up. There'll be a small overhead in the cases where we didn't really need to prepare packed_git during execution but this shouldn't be very noticeable. Also, packed_git may be re-initialized by packfile.c:reprepare_packed_git(). Again, all paths to it in git-grep are already protected by obj_read_lock() but it may suffer from the same problem in the future. So let's also internally protect it with obj_read_lock() (which is a recursive mutex). Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
c441ea4edc |
grep: allow submodule functions to run in parallel
Now that object reading operations are internally protected, the submodule initialization functions at builtin/grep.c:grep_submodule() are very close to being thread-safe. Let's take a look at each call and remove from the critical section what we can, for better performance: - submodule_from_path() and is_submodule_active() cannot be called in parallel yet only because they call repo_read_gitmodules() which contains, in its call stack, operations that would otherwise be in race condition with object reading (for example parse_object() and is_promisor_remote()). However, they only call repo_read_gitmodules() if it wasn't read before. So let's pre-read it before firing the threads and allow these two functions to safely be called in parallel. - repo_submodule_init() is already thread-safe, so remove it from the critical section without other necessary changes. - The repo_read_gitmodules(&subrepo) call at grep_submodule() is safe as no other thread is performing object reading operations in the subrepo yet. However, threads might be working in the superproject, and this function calls add_to_alternates_memory() internally, which is racy with object readings in the superproject. So it must be kept protected for now. Let's add a "NEEDSWORK" to it, informing why it cannot be removed from the critical section yet. - Finally, add_to_alternates_memory() must be kept protected for the same reason as the item above. Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
d7992421e1 |
submodule-config: add skip_if_read option to repo_read_gitmodules()
Currently, submodule-config.c doesn't have an externally accessible function to read gitmodules only if it wasn't already read. But this exact behavior is internally implemented by gitmodules_read_check(), to perform a lazy load. Let's merge this function with repo_read_gitmodules() adding a 'skip_if_read' which allows both internal and external callers to access this functionality. This simplifies a little the code. The added option will also be used in the following patch. Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
1d1729caeb |
grep: replace grep_read_mutex by internal obj read lock
git-grep uses 'grep_read_mutex' to protect its calls to object reading operations. But these have their own internal lock now, which ensures a better performance (allowing parallel access to more regions). So, let's remove the former and, instead, activate the latter with enable_obj_read_lock(). Sections that are currently protected by 'grep_read_mutex' but are not internally protected by the object reading lock should be surrounded by obj_read_lock() and obj_read_unlock(). These guarantee mutual exclusion with object reading operations, keeping the current behavior and avoiding race conditions. Namely, these places are: In grep.c: - fill_textconv() at fill_textconv_grep(). - userdiff_get_textconv() at grep_source_1(). In builtin/grep.c: - parse_object_or_die() and the submodule functions at grep_submodule(). - deref_tag() and gitmodules_config_oid() at grep_objects(). If these functions become thread-safe, in the future, we might remove the locking and probably get some speedup. Note that some of the submodule functions will already be thread-safe (or close to being thread-safe) with the internal object reading lock. However, as some of them will require additional modifications to be removed from the critical section, this will be done in its own patch. Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
d5b0bac528 |
grep: fix racy calls in grep_objects()
deref_tag() calls is_promisor_object() and parse_object(), both of which perform lazy initializations and other thread-unsafe operations. If it was only called by grep_objects() this wouldn't be a problem as the latter is only executed by the main thread. However, deref_tag() is also present in read_object_file()'s call stack. So calling deref_tag() in grep_objects() without acquiring the grep_read_mutex may incur in a race condition with object reading operations (such as the ones internally performed by fill_textconv(), called at fill_textconv_grep()). The same problem happens with the call to gitmodules_config_oid() which also has parse_object() in its call stack. Fix that protecting both calls with the said grep_read_mutex. Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
faf123c730 |
grep: fix race conditions at grep_submodule()
There're currently two function calls in builtin/grep.c:grep_submodule() which might result in race conditions: - submodule_from_path(): it has config_with_options() in its call stack which, in turn, may have read_object_file() in its own. Therefore, calling the first function without acquiring grep_read_mutex may end up causing a race condition with other object read operations performed by worker threads (for example, at the fill_textconv() call in grep.c:fill_textconv_grep()). - parse_object_or_die(): it falls into the same problem, having repo_has_object_file(the_repository, ...) in its call stack. Besides that, parse_object(), which is also called by parse_object_or_die(), is thread-unsafe and also called by object reading functions. It's unlikely to really fall into a data race with these operations as the volume of calls to them is usually very low. But we better protect ourselves against this possibility, anyway. So, to solve these issues, move both of these function calls into the critical section of grep_read_mutex. Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |
![]() |
54887b4689 |
gpg-interface: add minTrustLevel as a configuration option
Previously, signature verification for merge and pull operations checked
if the key had a trust-level of either TRUST_NEVER or TRUST_UNDEFINED in
verify_merge_signature(). If that was the case, the process die()d.
The other code paths that did signature verification relied entirely on
the return code from check_commit_signature(). And signatures made with
a good key, irregardless of its trust level, was considered valid by
check_commit_signature().
This difference in behavior might induce users to erroneously assume
that the trust level of a key in their keyring is always considered by
Git, even for operations where it is not (e.g. during a verify-commit or
verify-tag).
The way it worked was by gpg-interface.c storing the result from the
key/signature status *and* the lowest-two trust levels in the `result`
member of the signature_check structure (the last of these status lines
that were encountered got written to `result`). These are documented in
GPG under the subsection `General status codes` and `Key related`,
respectively [1].
The GPG documentation says the following on the TRUST_ status codes [1]:
"""
These are several similar status codes:
- TRUST_UNDEFINED <error_token>
- TRUST_NEVER <error_token>
- TRUST_MARGINAL [0 [<validation_model>]]
- TRUST_FULLY [0 [<validation_model>]]
- TRUST_ULTIMATE [0 [<validation_model>]]
For good signatures one of these status lines are emitted to
indicate the validity of the key used to create the signature.
The error token values are currently only emitted by gpgsm.
"""
My interpretation is that the trust level is conceptionally different
from the validity of the key and/or signature. That seems to also have
been the assumption of the old code in check_signature() where a result
of 'G' (as in GOODSIG) and 'U' (as in TRUST_NEVER or TRUST_UNDEFINED)
were both considered a success.
The two cases where a result of 'U' had special meaning were in
verify_merge_signature() (where this caused git to die()) and in
format_commit_one() (where it affected the output of the %G? format
specifier).
I think it makes sense to refactor the processing of TRUST_ status lines
such that users can configure a minimum trust level that is enforced
globally, rather than have individual parts of git (e.g. merge) do it
themselves (except for a grace period with backward compatibility).
I also think it makes sense to not store the trust level in the same
struct member as the key/signature status. While the presence of a
TRUST_ status code does imply that the signature is good (see the first
paragraph in the included snippet above), as far as I can tell, the
order of the status lines from GPG isn't well-defined; thus it would
seem plausible that the trust level could be overwritten with the
key/signature status if they were stored in the same member of the
signature_check structure.
This patch introduces a new configuration option: gpg.minTrustLevel. It
consolidates trust-level verification to gpg-interface.c and adds a new
`trust_level` member to the signature_check structure.
Backward-compatibility is maintained by introducing a special case in
verify_merge_signature() such that if no user-configurable
gpg.minTrustLevel is set, then the old behavior of rejecting
TRUST_UNDEFINED and TRUST_NEVER is enforced. If, on the other hand,
gpg.minTrustLevel is set, then that value overrides the old behavior.
Similarly, the %G? format specifier will continue show 'U' for
signatures made with a key that has a trust level of TRUST_UNDEFINED or
TRUST_NEVER, even though the 'U' character no longer exist in the
`result` member of the signature_check structure. A new format
specifier, %GT, is also introduced for users that want to show all
possible trust levels for a signature.
Another approach would have been to simply drop the trust-level
requirement in verify_merge_signature(). This would also have made the
behavior consistent with other parts of git that perform signature
verification. However, requiring a minimum trust level for signing keys
does seem to have a real-world use-case. For example, the build system
used by the Qubes OS project currently parses the raw output from
verify-tag in order to assert a minimum trust level for keys used to
sign git tags [2].
[1] https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=doc/doc/DETAILS;h=bd00006e933ac56719b1edd2478ecd79273eae72;hb=refs/heads/master
[2]
|
5 years ago |
![]() |
bf66db37f1 |
add: use advise function to display hints
Use the advise function in advice.c to display hints to the users, as it provides a neat and a standard format for hint messages, i.e: the text is colored in yellow and the line starts by the word "hint:". Also this will enable us to control the messages using advice.* configuration variables. Signed-off-by: Heba Waly <heba.waly@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> |
5 years ago |