fork of go-git with some jj specific features

_examples: Add performance focused clone example This example focuses on the least consumptiong of memory, while also taking into account the total operation time.

The go-git compared to its git CLI counterpart:

go run _examples/clone/fast/main.go https://github.com/go-git/go-git /tmp/go-git-clone
GIT_TRACE_PERFORMANCE=true git clone --no-tags --depth 1 --single-branch https://github.com/go-git/go-git /tmp/go-git-clone
10:15:50.616532 upload_pack.go:41: performance: 0.234388589 s: upload_pack
Enumerating objects: 582, done.
Counting objects: 100% (582/582), done.
Compressing objects: 100% (531/531), done.
Total 582 (delta 31), reused 165 (delta 10), pack-reused 0 (from 0)
10:15:50.683061 common.go:32: performance: 0.066241589 s: update_obj_storage
10:15:50.811161 worktree.go:366: performance: 0.127937022 s: reset_worktree
10:15:50.811257 repository.go:489: performance: 0.597924171 s: git command: git clone https://github.com/go-git/go-git
commit 9973a38aa942b2f177416d0e4b07832bb15e621e

GIT_TRACE_PERFORMANCE=true git clone --depth 1 --single-branch https://github.com/go-git/go-git /tmp/git-cli-clone
Cloning into '/tmp/git-cli-clone'...
remote: Enumerating objects: 582, done.
remote: Counting objects: 100% (582/582), done.
remote: Compressing objects: 100% (531/531), done.
remote: Total 582 (delta 31), reused 165 (delta 10), pack-reused 0 (from 0)
Receiving objects: 100% (582/582), 654.33 KiB | 6.00 MiB/s, done.
Resolving deltas: 100% (31/31), done.
10:23:04.662692 trace.c:416 performance: 0.205806146 s: git command: /usr/libexec/git/git --shallow-file /tmp/git-cli-clone/.git/shallow.lock index-pack --stdin -v --fix-thin '--keep=fetch-pack 122550 on localhost.localdomain'
10:23:04.662821 trace.c:416 performance: 0.607833632 s: git command: /usr/libexec/git/git remote-https origin https://github.com/go-git/go-git
10:23:04.664931 trace.c:416 performance: 0.000640393 s: git command: /usr/libexec/git/git rev-list --objects --stdin --not --all --quiet --alternate-refs '--progress=Checking connectivity'
10:23:04.667253 unpack-trees.c:2009 performance: 0.000710704 s: traverse_trees
10:23:04.678219 unpack-trees.c:511 performance: 0.010950771 s: check_updates
10:23:04.678465 cache-tree.c:491 performance: 0.000228486 s: cache_tree_update
10:23:04.678472 unpack-trees.c:2106 performance: 0.011949092 s: unpack_trees
10:23:04.678728 read-cache.c:3114 performance: 0.000251809 s: write index, changed mask = 2a
10:23:04.678772 trace.c:416 performance: 0.628392351 s: git command: git clone --depth 1 --single-branch https://github.com/go-git/go-git /tmp/git-cli-clone

Signed-off-by: Paulo Gomes <pjbgf@linux.com>

Changed files
+66
_examples
performance
clone
+1
_examples/README.md
··· 34 34 - [storage](storage/README.md) - Implementing a custom storage system. 35 35 - [sha256](sha256/main.go) - Init and committing repositories that use sha256 as object format. 36 36 - [memory](memory/main.go) - Clone a repository into an in-memory dotgit storage and worktree. 37 + - [perf-clone](performance/clone/main.go) - Clone a repository with the least time and space complexity.
+1
_examples/common_test.go
··· 28 28 "memory": {defaultURL}, 29 29 "merge_base": {cloneRepository(defaultURL, tempFolder()), "--is-ancestor", "HEAD~3", "HEAD^"}, 30 30 "open": {cloneRepository(defaultURL, tempFolder())}, 31 + "perf-clone": {cloneRepository(defaultURL, tempFolder())}, 31 32 "progress": {defaultURL, tempFolder()}, 32 33 "pull": {createRepositoryWithRemote(tempFolder(), defaultURL)}, 33 34 "push": {setEmptyRemote(cloneRepository(defaultURL, tempFolder()))},
+64
_examples/performance/clone/main.go
··· 1 + package main 2 + 3 + import ( 4 + "crypto" 5 + "crypto/sha1" 6 + "fmt" 7 + "os" 8 + 9 + "github.com/go-git/go-git/v5" 10 + . "github.com/go-git/go-git/v5/_examples" 11 + "github.com/go-git/go-git/v5/plumbing/hash" 12 + "github.com/go-git/go-git/v5/utils/trace" 13 + ) 14 + 15 + // Expands the Basic example focusing in performance. 16 + func main() { 17 + CheckArgs("<url>", "<directory>") 18 + url := os.Args[1] 19 + directory := os.Args[2] 20 + 21 + // Replace sha1cd with Golang's sha1 implementation, which is faster. 22 + // SHA1 as a hash algorithm is broken, so Git implementations tend to use 23 + // an alternative implementation that includes collision detection - which 24 + // is the default on go-git and in the git cli. 25 + // 26 + // This operation is only safe when interacting with trustworthy Git servers, 27 + // such as GitHub and GitLab. If your application needs to interact with 28 + // custom servers or does not impose any sort of constraints on the target 29 + // server, this is not recommended. 30 + hash.RegisterHash(crypto.SHA1, sha1.New) 31 + 32 + // Clone the given repository to the given directory 33 + Info("GIT_TRACE_PERFORMANCE=true git clone --no-tags --depth 1 --single-branch %s %s", url, directory) 34 + 35 + // Enable performance metrics. This is only to show the break down per 36 + // operation, and can be removed. Like in the git CLI, this can be enabled 37 + // at runtime by environment variable: 38 + // GIT_TRACE_PERFORMANCE=true 39 + trace.SetTarget(trace.Performance) 40 + 41 + r, err := git.PlainClone(directory, false, &git.CloneOptions{ 42 + URL: url, 43 + // Differently than the git CLI, by default go-git downloads 44 + // all tags and its related objects. To avoid unnecessary 45 + // data transmission and processing, opt-out tags. 46 + Tags: git.NoTags, 47 + // Shallow clones the repository, returning a single commit. 48 + Depth: 1, 49 + // Depth 1 implies single branch, so this is largely redundant. 50 + SingleBranch: true, 51 + // Not a net positive change for performance, this was added 52 + // to better align the output when compared with the git CLI. 53 + Progress: os.Stdout, 54 + }) 55 + 56 + CheckIfError(err) 57 + 58 + ref, err := r.Head() 59 + CheckIfError(err) 60 + commit, err := r.CommitObject(ref.Hash()) 61 + CheckIfError(err) 62 + 63 + fmt.Println(commit) 64 + }