Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Git infrastructure with Go
Search
David Calavera
February 21, 2015
Programming
3
590
Git infrastructure with Go
Talk for Gophercon India 2015 about using Go to manage large git data system.
David Calavera
February 21, 2015
Tweet
Share
More Decks by David Calavera
See All by David Calavera
The language of Chatops
calavera
0
150
How GitHub develops, ships and supports GitHub Enterprise
calavera
2
460
Project Warbird
calavera
1
160
Trinidad
calavera
0
42
JRuby hacking guide
calavera
0
72
My name is Trinidad
calavera
0
66
Other Decks in Programming
See All in Programming
AWS re:Invent 2025参加 直前 Seattle-Tacoma Airport(SEA)におけるハードウェア紛失インシデントLT
tetutetu214
2
110
副作用をどこに置くか問題:オブジェクト指向で整理する設計判断ツリー
koxya
1
610
AIエージェントのキホンから学ぶ「エージェンティックコーディング」実践入門
masahiro_nishimi
5
430
360° Signals in Angular: Signal Forms with SignalStore & Resources @ngLondon 01/2026
manfredsteyer
PRO
0
120
16年目のピクシブ百科事典を支える最新の技術基盤 / The Modern Tech Stack Powering Pixiv Encyclopedia in its 16th Year
ahuglajbclajep
5
1k
Amazon Bedrockを活用したRAGの品質管理パイプライン構築
tosuri13
4
500
Fluid Templating in TYPO3 14
s2b
0
130
AgentCoreとHuman in the Loop
har1101
5
230
AIによる開発の民主化を支える コンテキスト管理のこれまでとこれから
mulyu
3
250
カスタマーサクセス業務を変革したヘルススコアの実現と学び
_hummer0724
0
690
Automatic Grammar Agreementと Markdown Extended Attributes について
kishikawakatsumi
0
180
なぜSQLはAIぽく見えるのか/why does SQL look AI like
florets1
0
460
Featured
See All Featured
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.2k
The Curse of the Amulet
leimatthew05
1
8.4k
KATA
mclloyd
PRO
34
15k
Ethics towards AI in product and experience design
skipperchong
2
190
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.1k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
My Coaching Mixtape
mlcsv
0
47
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.6k
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
170
Designing Powerful Visuals for Engaging Learning
tmiket
0
230
Done Done
chrislema
186
16k
Typedesign – Prime Four
hannesfritz
42
2.9k
Transcript
High performance git infrastructure with Go David Calavera Code Climate
None
2005
(╯°□°)╯︵ ┻━┻
2008
2010…
How do we make git faster?
* system(“git log …”) * Ruby for brevity
git fetch origin
None
github.com/libgit2/git2go Disclaimer: examples do not handle errors
// Load with side effects. // Initialize libgit2’s TLS: //
// func init() { // C.git_libgit2_init() // } // // Import package “git”, which is // not very goimports friendly. import “github.com/libgit2/git2go”
// Create a new repository. // Do not use a
working directory. path := “/var/git/repository” bare := true r, _ := git.InitRepository(path, bare) ! // Clone a repository. url := “git://github.com/golang/go” opts := git.CloneOptions{Bare: bare} r, _ := git.Clone(url, path, &opts)
// Create a new remote ref. name := “my-fork” url
:= “git://github.com/wadus/go” rm, _ := r.CreateRemote(name, url) ! // Fetch all refs from a remote. var refspecs []string rm.Fetch(refspecs, nil, nil)
// Search for objects. sha := “4c279186e24f7b3a59aa682a870747df6eaca013” oid := git.NewOid(sha)
! c, _ := r.LookupCommit(oid) b, _ := r.LookupBlob(oid) t, _ := r.LookupTree(oid) ! o, _ := r.Lookup(oid) fmt.Printf(“ %v\n”, o.Type())
// Read commit data. sha := “4c279186e24f7b3a59aa682a870747df6eaca013” oid := git.NewOid(sha)
path := “src/os/exec.go” ! c, _ := r.LookupCommit(oid) t, _ := c.Tree() e, _ := t.EntryByPath(path) ! b, _ := r.LookupBlob(e.Id()) fmt.Printf(“ %q\n”, b.Contents())
// Commit new changes. idx, _ := r.Index() idx.AddByPath(“src/os/exec.go”) t,
_ := idx.WriteTree() idx.Write() ! h, _ := r.Head() c, _ := r.LookupCommit(h) ! s := &git.Signature{“me”, “
[email protected]
”, time.Now()} m := “Add moar changes” r.CreateCommit(“”, s, s, m, t, c)
None
None
Designing a distributed git storage
Application Git Service
Constraint your data model
// protocol buffers schema. message Branch { required string name
= 1; } ! message Repository { optional string name = 1; repeated Branch branches = 2; }
// Read branches. var branches []*pb.Branch ! f := func(b
*git.Branch, t git.BranchType) error { n, _ := b.Name() p := &pb.Branch{ Name: &n, } branches = append(branches, p) return nil } ! b, _ := r.NewBranchIterator(git.BranchRemote) b.ForEach(f)
// Read branches via http. h := func(w http.ResponseWriter, r
*http.Request) { pbBranches := readBranches(r) pbRepo := &pb.Repository{ Branches: pbBranches, } ! data, _ := proto.Marshal(pbRepo) w.Write(data) } ! http.HandleFunc(“/r/foo/branches”, h)
Design from first principles
A shared-data system can have at most two of the
three following properties: Consistency, Availability, and tolerance to network Partitions Dr. Eric Brewer
You Can’t Sacrifice Partition Tolerance Coda Hale
github.com/afex/hystrix-go" github.com/rubyist/circuitbreaker" github.com/eapache/go-resiliency/braker
// Read branches via http. import “github.com/rubyist/circuitbreaker” ! out :=
5 * time.Second url := “http://git-server/r/foo/branches” c := circuit.NewHTTPClient(out, 10, nil) ! c.BreakerTripped = func() { // Handle partition error response. } ! resp, _ := c.Get(url)
Replication Consistency Vs Availability
Application Git Service Git Service Primary Replica
Application Git Service Git Service Primary Replica Fetch!
Application Git Service Git Service Primary Replica Fetch!
Application Git Service Git Service Primary Replica Done!
Application Git Service Git Service Primary Replica Done!
// Handle fetch requests. h := func(w http.ResponseWriter, r *http.Request)
{ peerChannel := replicateRequest(r) rm, _ := repo.LoadRemote(“origin”) var refspecs []string rm.Fetch(refspecs, nil, nil) ! if peersChannel != nil { waitForPeers(peerChannel) } w.WriteHeader(201) } ! http.HandleFunc(“/r/foo/fetch”, h)
// Replicate request. func replicateRequest(r *http.Request) chan int { if
req.Header.Get(“X-GIT-REPLICATE”) != “” { return nil } peerChannel := make(chan int) replicaURL, err := url.Parse(replicaHost) replicaURL.Path = r.Path replicaURL.Header.Set(“X-GIT-REPLICATE”, “true") req, _ := http.NewRequest(“POST”, replicaURL.String(), nil) ! go func() { resp, _ := httpClient.Do(req) peerChannel <- resp.StatusCode }() return peerChannel }
// Wait for replica response. func waitForPeers(channel chan int) error
{ replicaStatus := <- channel switch replicaStatus { case 201: // default: // ☔️ ☔️ } ! return nil }
git architectures are fun
Thank you! @calavera