Slide 1

Slide 1 text

GIT LFS @ LIGHT SPEED - The story of a Git contribution - Lars Schneider Autodesk Taylor Blau GitHub

Slide 2

Slide 2 text

@kit3bus Previous version Current version GIT LFS @ LIGHT SPEED

Slide 3

Slide 3 text

@kit3bus Recap: Why Git LFS*? * Git Large File Storage = 100 MB video file

Slide 4

Slide 4 text

@kit3bus Clone: Git without LFS 0 MB

Slide 5

Slide 5 text

@kit3bus Clone: Git without LFS 101 MB master 1 MB 100 MB

Slide 6

Slide 6 text

@kit3bus Clone: Git without LFS 201 MB master + 100 MB 1 MB 100 MB 1 MB 100 MB

Slide 7

Slide 7 text

@kit3bus Clone: Git without LFS master 301MB + 100 MB + 100 MB 1 MB 100 MB 1 MB 100 MB 1 MB 100 MB

Slide 8

Slide 8 text

@kit3bus Clone: Git with LFS 0 MB

Slide 9

Slide 9 text

@kit3bus LFS Server Clone: Git with LFS 1MB master 1 MB 100 MB 0 MB

Slide 10

Slide 10 text

@kit3bus LFS Server Clone: Git with LFS 1MB master 1 MB 100 MB 1 MB 100 MB 0 MB 0 MB

Slide 11

Slide 11 text

@kit3bus LFS Server Clone: Git with LFS 1MB master 1 MB 100 MB 1 MB 1 MB 100 MB 0 MB 0 MB 0 MB 100 MB

Slide 12

Slide 12 text

@kit3bus LFS Server Git with LFS master 1 MB 100 MB 1 MB 1 MB 100 MB 0 MB 0 MB 0 MB 100 MB Clone: 1 MB

Slide 13

Slide 13 text

@kit3bus LFS Server Git with LFS master 1 MB 100 MB 1 MB 1 MB 100 MB 0 MB 0 MB 0 MB 100 MB Clone: 1 MB + Checkout: 100 MB

Slide 14

Slide 14 text

@kit3bus LFS Server Git with LFS master 1 MB 100 MB 1 MB 1 MB 100 MB 0 MB 0 MB 0 MB 100 MB Clone: 1 MB + Checkout: 100 MB 60% bandwidth saving!

Slide 15

Slide 15 text

@kit3bus Git Checkout Git

Slide 16

Slide 16 text

@kit3bus Git Checkout Git Git LFS Git clean / smudge filter

Slide 17

Slide 17 text

@kit3bus Git Git Checkout Git LFS Git LFS

Slide 18

Slide 18 text

@kit3bus Git LFS Git LFS Git LFS One-Shot Filter: Many Git LFS invocations Git Checkout Git

Slide 19

Slide 19 text

@kit3bus Git LFS Filter Protocol: One Git LFS invocation Git Checkout Git

Slide 20

Slide 20 text

@kit3bus Taylor Code Design Decisions Lars Git Contribution Process Git Checkout Git LFS Git

Slide 21

Slide 21 text

@kit3bus How to Contribute to Git Core

Slide 22

Slide 22 text

@kit3bus Subscribe to the Mailing List Send an email to "[email protected]" with an empty subject line and the words "subscribe git" in the message body.

Slide 23

Slide 23 text

@kit3bus Search the Mailing List Archive http://public-inbox.org/git/

Slide 24

Slide 24 text

@kit3bus Write an RFC* Pro Tip:
 Measure 
 performance * Request for Comment

Slide 25

Slide 25 text

@kit3bus Mailing List Tips & Tricks Inline replies Text only

Slide 26

Slide 26 text

@kit3bus Make Commits $ git checkout -b myfeature master ... feature ... ... tests ... ... docs ... $ git commit maint for bugfixes Read Documentation/CodingGuidelines

Slide 27

Slide 27 text

@kit3bus Make Commits area: short description Explain the problem. Explain the solution. Signed-off-by: Lars Schneider Pro Tip:
 Use a spell checker!

Slide 28

Slide 28 text

@kit3bus Check Commits make git rebase master -x "make" make test git diff --check master...HEAD ... https://github.com/larsxschneider/git-list-helper prepare-patch.sh master Lazy?

Slide 29

Slide 29 text

@kit3bus Check Commits Pro Tip:
 Enable TravisCI

Slide 30

Slide 30 text

@kit3bus Prepare Patch Emails git format-patch master From ea25a1834be7e2da36fd00f4abc403a56d6b35bc Mon Sep 17 00:00:00 2001 From: Lars Schneider Date: Mon, 21 Nov 2016 13:44:08 +0100 Subject: [PATCH v1] short description Detailed commit message. Signed-off-by: Lars Schneider --- Hi, message to mailing list! Cheers, Lars apply.c | 2 +- archive.c | 2 +- 2 files changed, 145 insertions(+), 24 deletions(-) diff --git a/apply.c b/apply.c index 2ed808d429..aa7e6e4359 100644 --- a/apply.c +++ b/apply.c @@ -4328,7 +4328,7 @@ static int try_create_file - if (convert_to_working_tree(path, buf, size, &nbuf)) { + if (convert_to_working_tree(path, buf, size, &nbuf, NULL)) { } -- 2.11.0 Commit Message Additional explanations/ cover letter Diff statistics Patch Your Git version Email header

Slide 31

Slide 31 text

@kit3bus Prepare Patch Emails prepare-patch.sh master From ea25a1834be7e2da36fd00f4abc403a56d6b35bc Mon Sep 17 00:00:00 2001 From: Lars Schneider Date: Mon, 21 Nov 2016 13:44:08 +0100 Subject: [PATCH v1] short description Detailed commit message. Signed-off-by: Lars Schneider --- Notes: Base Commit: 787f75f056 (master) Diff on Web: https://github.com/larsxschneider/git/commit/a8ec423355 Checkout: git fetch https://... demo && git checkout a8ec423355 apply.c | 2 +- archive.c | 2 +- 2 files changed, 145 insertions(+), 24 deletions(-) diff --git a/apply.c b/apply.c index 2ed808d429..aa7e6e4359 100644 --- a/apply.c +++ b/apply.c @@ -4328,7 +4328,7 @@ static int try_create_file - if (convert_to_working_tree(path, buf, size, &nbuf)) { + if (convert_to_working_tree(path, buf, size, &nbuf, NULL)) { } -- 2.11.0 Additional explanations/ cover letter

Slide 32

Slide 32 text

@kit3bus git send-email /patches/* [email protected] git send-email /patches/* [email protected] [email protected] Send Patch Emails Pro Tip:
 Find reviewers
 with git blame prepare-patch.sh master Lazy?

Slide 33

Slide 33 text

@kit3bus Wait...

Slide 34

Slide 34 text

@kit3bus Respond to Reviews

Slide 35

Slide 35 text

@kit3bus Respond to Reviews 1. Find agreement 2. Update commits 3. Check commits 4. Prepare patch emails Pro Tip:
 Make notes https://github.com/larsxschneider/git-list-helper prepare-patch.sh master 2

Slide 36

Slide 36 text

@kit3bus Respond to Reviews 1. Find agreement 2. Update commits 3. Check commits 4. Prepare patch emails 5. Send patch emails and CC reviewers Pro Tip:
 Make notes

Slide 37

Slide 37 text

@kit3bus v1 Contribution Cycle Take in
 reviews Send patches RFC

Slide 38

Slide 38 text

@kit3bus v1 v2 ... Contribution Cycle Take in
 reviews Send patches RFC

Slide 39

Slide 39 text

@kit3bus v1 v2 ... v11 Contribution Cycle Take in
 reviews next master Release! Send patches RFC More: Documentation/SubmittingPatches

Slide 40

Slide 40 text

@kit3bus Filter Protocol Statistics 1,628 changes 11 iterations 380 emails 6 months Pro Tip:
 Don't give up!

Slide 41

Slide 41 text

34 Git LFS Next steps

Slide 42

Slide 42 text

38 October, 2016 December, 2016 November, 2016 filter process is merged into git/next Git v2.11 release

Slide 43

Slide 43 text

39 (master) $ git checkout my-feature (my-feature) $ ...

Slide 44

Slide 44 text

40 (master) $ GIT_TRACE_PACKET=1 git checkout my-feature packet: git> command=smudge packet: git> pathname=foo/bar.dat packet: git> 0000 packet: git> CONTENT packet: git> 0000 packet: git< status=success packet: git< 0000 packet: git< SMUDGED_CONTENT packet: git< 0000 packet: git< 0000 (my-feature) $ ...

Slide 45

Slide 45 text

44 3 1 2

Slide 46

Slide 46 text

Start small. 45

Slide 47

Slide 47 text

Validate quickly. 46

Slide 48

Slide 48 text

Iterate later. 47

Slide 49

Slide 49 text

49 Integration tests

Slide 50

Slide 50 text

50

Slide 51

Slide 51 text

51 Integration tests pkt-line protocol

Slide 52

Slide 52 text

52

Slide 53

Slide 53 text

53 Integration tests pkt-line protocol process filter protocol

Slide 54

Slide 54 text

54

Slide 55

Slide 55 text

59 for scanner.Scan() { req := scan.Request() switch req.Header[“command”] { case “clean”: case “smudge”: default: } } if err := scan.Err(); err != nil { // ... }

Slide 56

Slide 56 text

60 type Request struct { Header map[string]string Payload []byte }

Slide 57

Slide 57 text

62 Integration tests pkt-line protocol process filter protocol pkt-line I/O pt. I

Slide 58

Slide 58 text

63

Slide 59

Slide 59 text

64 type io.Reader interface { Read(p []byte) (n int, err error) }

Slide 60

Slide 60 text

65 type Pktline struct { ... } func (p *Pktline) Pkt() ([]byte, error) { // ... }

Slide 61

Slide 61 text

72 type PktlineReader struct { ... } func (r *PktlineReader) Read(p []byte) (n int, err error) { for { pkt, err := r.pkt() if err != nil { return n, err } copy(p[n:], pkt) } return n, nil }

Slide 62

Slide 62 text

73 for scanner.Scan() { req := scanner.Request() sig := sha256.New() io.Copy(sig, req.Body) fmt.Fprintln(“OID: %x”, sig.Sum(nil)) }

Slide 63

Slide 63 text

77 Integration tests pkt-line protocol process filter protocol pkt-line I/O pt. II pkt-line I/O pt. I

Slide 64

Slide 64 text

78

Slide 65

Slide 65 text

79 type io.Writer interface { Write(p []byte) (n int, err error) }

Slide 66

Slide 66 text

87 type PktlineWriter struct { ... } func (w *PktlineWriter) Write(p []byte) (n int, err error) { var n int for n < len(p) { c := min(len(p[n:]), MaxPacketLength) if err := w.writePkt(p[n:c]); err != nil { return n, err } n += c } return n, nil }

Slide 67

Slide 67 text

92 func smudge(out io.Writer, oid string) (n int, err error) { path := lfs.LocalMediaPath(oid) f, err := os.Open(path) if err != nil { return 0, err } return io.Copy(out, f) }

Slide 68

Slide 68 text

93 Integration tests pkt-line protocol process filter protocol pkt-line I/O pt. II pkt-line I/O pt. I

Slide 69

Slide 69 text

! Release! 94

Slide 70

Slide 70 text

80x faster. 95

Slide 71

Slide 71 text

Next steps? • Promise capability (discussion in git-core) • File-path exchange • ??? 100

Slide 72

Slide 72 text

Thank you. 101