aboutsummaryrefslogtreecommitdiffstats
path: root/_examples
diff options
context:
space:
mode:
Diffstat (limited to '_examples')
-rw-r--r--_examples/README.md14
-rw-r--r--_examples/clone/main.go34
-rw-r--r--_examples/common.go32
-rw-r--r--_examples/common_test.go127
-rw-r--r--_examples/custom_http/main.go53
-rw-r--r--_examples/log/main.go39
-rw-r--r--_examples/open/main.go35
-rw-r--r--_examples/progress/main.go29
-rw-r--r--_examples/push/main.go20
-rw-r--r--_examples/remotes/main.go71
-rw-r--r--_examples/showcase/main.go62
11 files changed, 516 insertions, 0 deletions
diff --git a/_examples/README.md b/_examples/README.md
new file mode 100644
index 0000000..334664f
--- /dev/null
+++ b/_examples/README.md
@@ -0,0 +1,14 @@
+# go-git: examples
+
+Here you can find a list of annotated _go-git_ examples:
+
+### Basic
+- [showcase](showcase/main.go) - A small showcase of the capabilities of _go-git_
+- [open](open/main.go) - Opening a existing repository cloned by _git_
+- [clone](clone/main.go) - Cloning a repository
+- [remotes](remotes/main.go) - Working with remotes: adding, removing, etc
+- [progress](progress/main.go) - Priting the progress information from the sideband
+
+### Advanced
+- [custom_http](custom_http/main.go) - Replacing the HTTP client using a custom one
+- [storage](storage/main.go) - Implementing a custom storage system
diff --git a/_examples/clone/main.go b/_examples/clone/main.go
new file mode 100644
index 0000000..7d48c40
--- /dev/null
+++ b/_examples/clone/main.go
@@ -0,0 +1,34 @@
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "srcd.works/go-git.v4"
+ . "srcd.works/go-git.v4/examples"
+)
+
+func main() {
+ CheckArgs("<url>", "<directory>")
+ url := os.Args[1]
+ directory := os.Args[2]
+
+ // Clone the given repository to the given directory
+ Info("git clone %s %s", url, directory)
+
+ r, err := git.PlainClone(directory, false, &git.CloneOptions{
+ URL: url,
+ Depth: 1,
+ })
+
+ CheckIfError(err)
+
+ // ... retrieving the branch being pointed by HEAD
+ ref, err := r.Head()
+ CheckIfError(err)
+ // ... retrieving the commit object
+ commit, err := r.Commit(ref.Hash())
+ CheckIfError(err)
+
+ fmt.Println(commit)
+}
diff --git a/_examples/common.go b/_examples/common.go
new file mode 100644
index 0000000..971b0f6
--- /dev/null
+++ b/_examples/common.go
@@ -0,0 +1,32 @@
+package examples
+
+import (
+ "os"
+ "strings"
+
+ "github.com/fatih/color"
+)
+
+func CheckArgs(arg ...string) {
+ if len(os.Args) < len(arg)+1 {
+ Warning("Usage: %s %s", os.Args[0], strings.Join(arg, " "))
+ os.Exit(1)
+ }
+}
+
+func CheckIfError(err error) {
+ if err == nil {
+ return
+ }
+
+ color.Red("error: %s", err)
+ os.Exit(1)
+}
+
+func Info(format string, args ...interface{}) {
+ color.Blue(format, args...)
+}
+
+func Warning(format string, args ...interface{}) {
+ color.Cyan(format, args...)
+}
diff --git a/_examples/common_test.go b/_examples/common_test.go
new file mode 100644
index 0000000..b218e07
--- /dev/null
+++ b/_examples/common_test.go
@@ -0,0 +1,127 @@
+package examples
+
+import (
+ "flag"
+ "fmt"
+ "go/build"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "testing"
+)
+
+var examplesTest = flag.Bool("examples", false, "run the examples tests")
+
+var defaultURL = "https://github.com/mcuadros/basic.git"
+
+var args = map[string][]string{
+ "showcase": []string{defaultURL, tempFolder()},
+ "custom_http": []string{defaultURL},
+ "clone": []string{defaultURL, tempFolder()},
+ "progress": []string{defaultURL, tempFolder()},
+ "open": []string{cloneRepository(defaultURL, tempFolder())},
+ "push": []string{setEmptyRemote(cloneRepository(defaultURL, tempFolder()))},
+}
+
+var ignored = map[string]bool{}
+
+var tempFolders = []string{}
+
+func TestExamples(t *testing.T) {
+ flag.Parse()
+ if !*examplesTest && os.Getenv("CI") == "" {
+ t.Skip("skipping examples tests, pass --examples to execute it")
+ return
+ }
+
+ defer deleteTempFolders()
+
+ examples, err := filepath.Glob(examplesFolder())
+ if err != nil {
+ t.Errorf("error finding tests: %s", err)
+ }
+
+ for _, example := range examples {
+ _, name := filepath.Split(filepath.Dir(example))
+
+ if ignored[name] {
+ continue
+ }
+
+ t.Run(name, func(t *testing.T) {
+ testExample(t, name, example)
+ })
+ }
+}
+
+func tempFolder() string {
+ path, err := ioutil.TempDir("", "")
+ CheckIfError(err)
+
+ tempFolders = append(tempFolders, path)
+ return path
+}
+
+func packageFolder() string {
+ return filepath.Join(
+ build.Default.GOPATH,
+ "src", "srcd.works/go-git.v4",
+ )
+}
+
+func examplesFolder() string {
+ return filepath.Join(
+ packageFolder(),
+ "examples", "*", "main.go",
+ )
+}
+
+func cloneRepository(url, folder string) string {
+ cmd := exec.Command("git", "clone", url, folder)
+ err := cmd.Run()
+ CheckIfError(err)
+
+ return folder
+}
+
+func createBareRepository(dir string) string {
+ cmd := exec.Command("git", "init", "--bare", dir)
+ err := cmd.Run()
+ CheckIfError(err)
+
+ return dir
+}
+
+func setEmptyRemote(dir string) string {
+ remote := createBareRepository(tempFolder())
+ setRemote(dir, fmt.Sprintf("file://%s", remote))
+ return dir
+}
+
+func setRemote(local, remote string) {
+ cmd := exec.Command("git", "remote", "set-url", "origin", remote)
+ cmd.Dir = local
+ err := cmd.Run()
+ CheckIfError(err)
+}
+
+func testExample(t *testing.T, name, example string) {
+ cmd := exec.Command("go", append([]string{
+ "run", filepath.Join(example),
+ }, args[name]...)...)
+
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+
+ if err := cmd.Run(); err != nil {
+ t.Errorf("error running cmd %q", err)
+ }
+}
+
+func deleteTempFolders() {
+ for _, folder := range tempFolders {
+ err := os.RemoveAll(folder)
+ CheckIfError(err)
+ }
+}
diff --git a/_examples/custom_http/main.go b/_examples/custom_http/main.go
new file mode 100644
index 0000000..ee8b96b
--- /dev/null
+++ b/_examples/custom_http/main.go
@@ -0,0 +1,53 @@
+package main
+
+import (
+ "crypto/tls"
+ "fmt"
+ "net/http"
+ "os"
+ "time"
+
+ "srcd.works/go-git.v4"
+ . "srcd.works/go-git.v4/examples"
+ "srcd.works/go-git.v4/plumbing/transport/client"
+ githttp "srcd.works/go-git.v4/plumbing/transport/http"
+ "srcd.works/go-git.v4/storage/memory"
+)
+
+// Here is an example to configure http client according to our own needs.
+func main() {
+ CheckArgs("<url>")
+ url := os.Args[1]
+
+ // Create a custom http(s) client with your config
+ customClient := &http.Client{
+ // accept any certificate (might be useful for testing)
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ },
+
+ // 15 second timeout
+ Timeout: 15 * time.Second,
+
+ // don't follow redirect
+ CheckRedirect: func(req *http.Request, via []*http.Request) error {
+ return http.ErrUseLastResponse
+ },
+ }
+
+ // Override http(s) default protocol to use our custom client
+ client.InstallProtocol("https", githttp.NewClient(customClient))
+
+ // Clone repository using the new client if the protocol is https://
+ Info("git clone %s", url)
+
+ r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{URL: url})
+ CheckIfError(err)
+
+ // Retrieve the branch pointed by HEAD
+ Info("git rev-parse HEAD")
+
+ head, err := r.Head()
+ CheckIfError(err)
+ fmt.Println(head.Hash())
+}
diff --git a/_examples/log/main.go b/_examples/log/main.go
new file mode 100644
index 0000000..486e8c9
--- /dev/null
+++ b/_examples/log/main.go
@@ -0,0 +1,39 @@
+package main
+
+import (
+ "fmt"
+
+ "srcd.works/go-git.v4"
+ . "srcd.works/go-git.v4/examples"
+ "srcd.works/go-git.v4/storage/memory"
+)
+
+func main() {
+ // Clones the given repository, creating the remote, the local branches
+ // and fetching the objects, everything in memory:
+ Info("git clone https://github.com/src-d/go-siva")
+ r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
+ URL: "https://github.com/src-d/go-siva",
+ })
+ CheckIfError(err)
+
+ // Gets the HEAD history from HEAD, just like does:
+ Info("git log")
+
+ // ... retrieves the branch pointed by HEAD
+ ref, err := r.Head()
+ CheckIfError(err)
+
+ // ... retrieves the commit object
+ commit, err := r.Commit(ref.Hash())
+ CheckIfError(err)
+
+ // ... retrieves the commit history
+ history, err := commit.History()
+ CheckIfError(err)
+
+ // ... just iterates over the commits, printing it
+ for _, c := range history {
+ fmt.Println(c)
+ }
+}
diff --git a/_examples/open/main.go b/_examples/open/main.go
new file mode 100644
index 0000000..aa51935
--- /dev/null
+++ b/_examples/open/main.go
@@ -0,0 +1,35 @@
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "srcd.works/go-git.v4"
+ . "srcd.works/go-git.v4/examples"
+)
+
+func main() {
+ CheckArgs("<path>")
+ path := os.Args[1]
+
+ // We instance a new repository targeting the given path (the .git folder)
+ r, err := git.PlainOpen(path)
+ CheckIfError(err)
+
+ // Length of the HEAD history
+ Info("git rev-list HEAD --count")
+
+ // ... retrieving the HEAD reference
+ ref, err := r.Head()
+ CheckIfError(err)
+
+ // ... retrieving the commit object
+ commit, err := r.Commit(ref.Hash())
+ CheckIfError(err)
+
+ // ... calculating the commit history
+ commits, err := commit.History()
+ CheckIfError(err)
+
+ fmt.Println(len(commits))
+}
diff --git a/_examples/progress/main.go b/_examples/progress/main.go
new file mode 100644
index 0000000..a06de54
--- /dev/null
+++ b/_examples/progress/main.go
@@ -0,0 +1,29 @@
+package main
+
+import (
+ "os"
+
+ "srcd.works/go-git.v4"
+ . "srcd.works/go-git.v4/examples"
+)
+
+func main() {
+ CheckArgs("<url>", "<directory>")
+ url := os.Args[1]
+ directory := os.Args[2]
+
+ // Clone the given repository to the given directory
+ Info("git clone %s %s", url, directory)
+
+ _, err := git.PlainClone(directory, false, &git.CloneOptions{
+ URL: url,
+ Depth: 1,
+
+ // as git does, when you make a clone, pull or some other operations the
+ // server sends information via the sideband, this information can being
+ // collected provinding a io.Writer to the CloneOptions options
+ Progress: os.Stdout,
+ })
+
+ CheckIfError(err)
+}
diff --git a/_examples/push/main.go b/_examples/push/main.go
new file mode 100644
index 0000000..cfae064
--- /dev/null
+++ b/_examples/push/main.go
@@ -0,0 +1,20 @@
+package main
+
+import (
+ "os"
+
+ "srcd.works/go-git.v4"
+ . "srcd.works/go-git.v4/examples"
+)
+
+func main() {
+ CheckArgs("<repository-path>")
+ path := os.Args[1]
+
+ r, err := git.PlainOpen(path)
+ CheckIfError(err)
+
+ Info("git push")
+ err = r.Push(&git.PushOptions{})
+ CheckIfError(err)
+}
diff --git a/_examples/remotes/main.go b/_examples/remotes/main.go
new file mode 100644
index 0000000..362244b
--- /dev/null
+++ b/_examples/remotes/main.go
@@ -0,0 +1,71 @@
+package main
+
+import (
+ "fmt"
+
+ "srcd.works/go-git.v4"
+ "srcd.works/go-git.v4/config"
+ . "srcd.works/go-git.v4/examples"
+ "srcd.works/go-git.v4/plumbing"
+ "srcd.works/go-git.v4/storage/memory"
+)
+
+func main() {
+ // Create a new repository
+ Info("git init")
+ r, err := git.Init(memory.NewStorage(), nil)
+ CheckIfError(err)
+
+ // Add a new remote, with the default fetch refspec
+ Info("git remote add example https://github.com/git-fixtures/basic.git")
+ _, err = r.CreateRemote(&config.RemoteConfig{
+ Name: "example",
+ URL: "https://github.com/git-fixtures/basic.git",
+ })
+
+ CheckIfError(err)
+
+ // List remotes from a repository
+ Info("git remotes -v")
+
+ list, err := r.Remotes()
+ CheckIfError(err)
+
+ for _, r := range list {
+ fmt.Println(r)
+ }
+
+ // Pull using the create repository
+ Info("git pull example")
+ err = r.Pull(&git.PullOptions{
+ RemoteName: "example",
+ })
+
+ CheckIfError(err)
+
+ // List the branches
+ // > git show-ref
+ Info("git show-ref")
+
+ refs, err := r.References()
+ CheckIfError(err)
+
+ err = refs.ForEach(func(ref *plumbing.Reference) error {
+ // The HEAD is omitted in a `git show-ref` so we ignore the symbolic
+ // references, the HEAD
+ if ref.Type() == plumbing.SymbolicReference {
+ return nil
+ }
+
+ fmt.Println(ref)
+ return nil
+ })
+
+ CheckIfError(err)
+
+ // Delete the example remote
+ Info("git remote rm example")
+
+ err = r.DeleteRemote("example")
+ CheckIfError(err)
+}
diff --git a/_examples/showcase/main.go b/_examples/showcase/main.go
new file mode 100644
index 0000000..e70de61
--- /dev/null
+++ b/_examples/showcase/main.go
@@ -0,0 +1,62 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "strings"
+
+ "srcd.works/go-git.v4"
+ "srcd.works/go-git.v4/plumbing/object"
+
+ . "srcd.works/go-git.v4/examples"
+)
+
+func main() {
+ CheckArgs("<url> <path>")
+ url := os.Args[1]
+ path := os.Args[2]
+
+ // Clone the given repository, creating the remote, the local branches
+ // and fetching the objects, exactly as:
+ Info("git clone %s %s", url, path)
+
+ r, err := git.PlainClone(path, false, &git.CloneOptions{URL: url})
+ CheckIfError(err)
+
+ // Getting the latest commit on the current branch
+ Info("git log -1")
+
+ // ... retrieving the branch being pointed by HEAD
+ ref, err := r.Head()
+ CheckIfError(err)
+
+ // ... retrieving the commit object
+ commit, err := r.Commit(ref.Hash())
+ CheckIfError(err)
+ fmt.Println(commit)
+
+ // List the tree from HEAD
+ Info("git ls-tree -r HEAD")
+
+ // ... retrieve the tree from the commit
+ tree, err := commit.Tree()
+ CheckIfError(err)
+
+ // ... get the files iterator and print the file
+ tree.Files().ForEach(func(f *object.File) error {
+ fmt.Printf("100644 blob %s %s\n", f.Hash, f.Name)
+ return nil
+ })
+
+ // List the history of the repository
+ Info("git log --oneline")
+
+ commits, err := commit.History()
+ CheckIfError(err)
+
+ for _, c := range commits {
+ hash := c.Hash.String()
+ line := strings.Split(c.Message, "\n")
+ fmt.Println(hash[:7], line[0])
+ }
+}