Skip to content

v1.0.0-beta.3 #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion command.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func (c *Command) RunInDirPipelineWithTimeout(timeout time.Duration, stdout, std
}()

cmd := exec.CommandContext(ctx, c.name, c.args...)
if c.envs != nil {
if len(c.envs) > 0 {
cmd.Env = append(os.Environ(), c.envs...)
}
cmd.Dir = dir
Expand Down
72 changes: 54 additions & 18 deletions repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,17 +221,25 @@ type PushOptions struct {
Timeout time.Duration
}

// Push pushs local changes to given remote and branch for the repository.
func (r *Repository) Push(remote, branch string, opts ...PushOptions) error {
// RepoPush pushs local changes to given remote and branch for the repository
// in given path.
func RepoPush(repoPath, remote, branch string, opts ...PushOptions) error {
var opt PushOptions
if len(opts) > 0 {
opt = opts[0]
}

_, err := NewCommand("push", remote, branch).AddEnvs(opt.Envs...).RunInDirWithTimeout(opt.Timeout, r.path)
_, err := NewCommand("push", remote, branch).
AddEnvs(opt.Envs...).
RunInDirWithTimeout(opt.Timeout, repoPath)
return err
}

// Push pushs local changes to given remote and branch for the repository.
func (r *Repository) Push(remote, branch string, opts ...PushOptions) error {
return RepoPush(r.path, remote, branch, opts...)
}

// CheckoutOptions contains optional arguments for checking out to a branch.
// Docs: https://git-scm.com/docs/git-checkout
type CheckoutOptions struct {
Expand All @@ -242,8 +250,8 @@ type CheckoutOptions struct {
Timeout time.Duration
}

// Checkout checks out to given branch for the repository.
func (r *Repository) Checkout(branch string, opts ...CheckoutOptions) error {
// Checkout checks out to given branch for the repository in given path.
func RepoCheckout(repoPath, branch string, opts ...CheckoutOptions) error {
var opt CheckoutOptions
if len(opts) > 0 {
opt = opts[0]
Expand All @@ -258,10 +266,15 @@ func (r *Repository) Checkout(branch string, opts ...CheckoutOptions) error {
cmd.AddArgs(opt.BaseBranch)
}

_, err := cmd.RunInDirWithTimeout(opt.Timeout, r.path)
_, err := cmd.RunInDirWithTimeout(opt.Timeout, repoPath)
return err
}

// Checkout checks out to given branch for the repository.
func (r *Repository) Checkout(branch string, opts ...CheckoutOptions) error {
return RepoCheckout(r.path, branch, opts...)
}

// ResetOptions contains optional arguments for resetting a branch.
// Docs: https://git-scm.com/docs/git-reset
type ResetOptions struct {
Expand All @@ -272,8 +285,8 @@ type ResetOptions struct {
Timeout time.Duration
}

// Reset resets working tree to given revision for the repository.
func (r *Repository) Reset(rev string, opts ...ResetOptions) error {
// RepoReset resets working tree to given revision for the repository in given path.
func RepoReset(repoPath, rev string, opts ...ResetOptions) error {
var opt ResetOptions
if len(opts) > 0 {
opt = opts[0]
Expand All @@ -284,10 +297,15 @@ func (r *Repository) Reset(rev string, opts ...ResetOptions) error {
cmd.AddArgs("--hard")
}

_, err := cmd.AddArgs(rev).RunInDir(r.path)
_, err := cmd.AddArgs(rev).RunInDir(repoPath)
return err
}

// Reset resets working tree to given revision for the repository.
func (r *Repository) Reset(rev string, opts ...ResetOptions) error {
return RepoReset(r.path, rev, opts...)
}

// MoveOptions contains optional arguments for moving a file, a directory, or a symlink.
// Docs: https://git-scm.com/docs/git-mv
type MoveOptions struct {
Expand All @@ -296,17 +314,24 @@ type MoveOptions struct {
Timeout time.Duration
}

// Move moves a file, a directory, or a symlink file or directory from source to destination.
func (r *Repository) Move(src, dst string, opts ...MoveOptions) error {
// RepoMove moves a file, a directory, or a symlink file or directory from source to
// destination for the repository in given path.
func RepoMove(repoPath, src, dst string, opts ...MoveOptions) error {
var opt MoveOptions
if len(opts) > 0 {
opt = opts[0]
}

_, err := NewCommand("mv", src, dst).RunInDirWithTimeout(opt.Timeout, r.path)
_, err := NewCommand("mv", src, dst).RunInDirWithTimeout(opt.Timeout, repoPath)
return err
}

// Move moves a file, a directory, or a symlink file or directory from source to destination
// for the repository.
func (r *Repository) Move(src, dst string, opts ...MoveOptions) error {
return RepoMove(r.path, src, dst, opts...)
}

// AddOptions contains optional arguments for adding local changes.
// Docs: https://git-scm.com/docs/git-add
type AddOptions struct {
Expand All @@ -319,8 +344,8 @@ type AddOptions struct {
Timeout time.Duration
}

// Add adds local changes to index for the repository.
func (r *Repository) Add(opts ...AddOptions) error {
// RepoAdd adds local changes to index for the repository in given path.
func RepoAdd(repoPath string, opts ...AddOptions) error {
var opt AddOptions
if len(opts) > 0 {
opt = opts[0]
Expand All @@ -334,10 +359,15 @@ func (r *Repository) Add(opts ...AddOptions) error {
cmd.AddArgs("--")
cmd.AddArgs(opt.Pathsepcs...)
}
_, err := cmd.RunInDirWithTimeout(opt.Timeout, r.path)
_, err := cmd.RunInDirWithTimeout(opt.Timeout, repoPath)
return err
}

// Add adds local changes to index for the repository.
func (r *Repository) Add(opts ...AddOptions) error {
return RepoAdd(r.path, opts...)
}

// CommitOptions contains optional arguments to commit changes.
// Docs: https://git-scm.com/docs/git-commit
type CommitOptions struct {
Expand All @@ -348,8 +378,9 @@ type CommitOptions struct {
Timeout time.Duration
}

// Commit commits local changes with given author, committer and message for the repository.
func (r *Repository) Commit(committer *Signature, message string, opts ...CommitOptions) error {
// RepoCommit commits local changes with given author, committer and message for the
// repository in given path.
func RepoCommit(repoPath string, committer *Signature, message string, opts ...CommitOptions) error {
var opt CommitOptions
if len(opts) > 0 {
opt = opts[0]
Expand All @@ -363,14 +394,19 @@ func (r *Repository) Commit(committer *Signature, message string, opts ...Commit
}
cmd.AddArgs("-m", message)

_, err := cmd.RunInDirWithTimeout(opt.Timeout, r.path)
_, err := cmd.RunInDirWithTimeout(opt.Timeout, repoPath)
// No stderr but exit status 1 means nothing to commit.
if err != nil && err.Error() == "exit status 1" {
return nil
}
return err
}

// Commit commits local changes with given author, committer and message for the repository.
func (r *Repository) Commit(committer *Signature, message string, opts ...CommitOptions) error {
return RepoCommit(r.path, committer, message, opts...)
}

// NameStatus contains name status of a commit.
type NameStatus struct {
Added []string
Expand Down
29 changes: 24 additions & 5 deletions repo_commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package git
import (
"bytes"
"errors"
"fmt"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -139,8 +140,19 @@ func escapePath(path string) string {
return path
}

// Log returns a list of commits in the state of given revision. The returned list is in reverse
// chronological order.
// RepoLog returns a list of commits in the state of given revision of the repository
// in given path. The returned list is in reverse chronological order.
func RepoLog(repoPath, rev string, opts ...LogOptions) ([]*Commit, error) {
r, err := Open(repoPath)
if err != nil {
return nil, fmt.Errorf("open: %v", err)
}

return r.Log(rev, opts...)
}

// Log returns a list of commits in the state of given revision of the repository.
// The returned list is in reverse chronological order.
func (r *Repository) Log(rev string, opts ...LogOptions) ([]*Commit, error) {
var opt LogOptions
if len(opts) > 0 {
Expand Down Expand Up @@ -300,8 +312,9 @@ type DiffNameOnlyOptions struct {
Timeout time.Duration
}

// DiffNameOnly returns a list of changed files between base and head revisions of the repository.
func (r *Repository) DiffNameOnly(base, head string, opts ...DiffNameOnlyOptions) ([]string, error) {
// RepoDiffNameOnly returns a list of changed files between base and head revisions of
// the repository in given path.
func RepoDiffNameOnly(repoPath, base, head string, opts ...DiffNameOnlyOptions) ([]string, error) {
var opt DiffNameOnlyOptions
if len(opts) > 0 {
opt = opts[0]
Expand All @@ -318,7 +331,7 @@ func (r *Repository) DiffNameOnly(base, head string, opts ...DiffNameOnlyOptions
cmd.AddArgs(escapePath(opt.Path))
}

stdout, err := cmd.RunInDirWithTimeout(opt.Timeout, r.path)
stdout, err := cmd.RunInDirWithTimeout(opt.Timeout, repoPath)
if err != nil {
return nil, err
}
Expand All @@ -335,6 +348,12 @@ func (r *Repository) DiffNameOnly(base, head string, opts ...DiffNameOnlyOptions
return names, nil
}

// DiffNameOnly returns a list of changed files between base and head revisions of the
// repository.
func (r *Repository) DiffNameOnly(base, head string, opts ...DiffNameOnlyOptions) ([]string, error) {
return RepoDiffNameOnly(r.path, base, head, opts...)
}

// RevListCountOptions contains optional arguments for counting commits.
// Docs: https://git-scm.com/docs/git-rev-list#Documentation/git-rev-list.txt---count
type RevListCountOptions struct {
Expand Down
7 changes: 7 additions & 0 deletions repo_commit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ func TestRepository_Log(t *testing.T) {
}

assert.Equal(t, test.expCommitIDs, commitsToIDs(commits))

commits, err = RepoLog(testrepo.path, test.rev, test.opt)
if err != nil {
t.Fatal(err)
}

assert.Equal(t, test.expCommitIDs, commitsToIDs(commits))
})
}
}
Expand Down
27 changes: 13 additions & 14 deletions repo_hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package git
import (
"io/ioutil"
"os"
"path"
"path/filepath"
)

Expand All @@ -23,11 +22,15 @@ func (r *Repository) NewHook(name HookName) *Hook {
}
}

// Hook returns a Git hook by given name in the repository. It returns an os.ErrNotExist
// if both active and sample hook do not exist.
func (r *Repository) Hook(name HookName) (*Hook, error) {
// Hook returns a Git hook by given name in the repository. Giving empty directory
// will use the default directory.It returns an os.ErrNotExist if both active and
// sample hook do not exist.
func (r *Repository) Hook(dir string, name HookName) (*Hook, error) {
if dir == "" {
dir = DefaultHooksDir
}
// 1. Check if there is an active hook.
fpath := filepath.Join(r.path, DefaultHooksDir, string(name))
fpath := filepath.Join(r.path, dir, string(name))
if isFile(fpath) {
p, err := ioutil.ReadFile(fpath)
if err != nil {
Expand All @@ -41,7 +44,7 @@ func (r *Repository) Hook(name HookName) (*Hook, error) {
}

// 2. Check if a sample file exists.
spath := fpath + ".sample"
spath := filepath.Join(r.path, DefaultHooksDir, string(name)+".sample")
if isFile(spath) {
p, err := ioutil.ReadFile(spath)
if err != nil {
Expand All @@ -58,16 +61,12 @@ func (r *Repository) Hook(name HookName) (*Hook, error) {
return nil, os.ErrNotExist
}

// Hooks returns a list of Git hooks found in the repository. It may return an empty slice
// when no hooks found.
func (r *Repository) Hooks() ([]*Hook, error) {
if !isDir(path.Join(r.path, DefaultHooksDir)) {
return []*Hook{}, nil
}

// Hooks returns a list of Git hooks found in the repository. Giving empty directory
// will use the default directory. It may return an empty slice when no hooks found.
func (r *Repository) Hooks(dir string) ([]*Hook, error) {
hooks := make([]*Hook, 0, len(ServerSideHooks))
for _, name := range ServerSideHooks {
h, err := r.Hook(name)
h, err := r.Hook(dir, name)
if err != nil {
if err == os.ErrNotExist {
continue
Expand Down
8 changes: 4 additions & 4 deletions repo_hook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

func TestRepository_Hooks(t *testing.T) {
t.Run("invalid hook", func(t *testing.T) {
h, err := testrepo.Hook("bad_hook")
h, err := testrepo.Hook("", "bad_hook")
assert.Equal(t, os.ErrNotExist, err)
assert.Nil(t, h)
})
Expand All @@ -30,7 +30,7 @@ func TestRepository_Hooks(t *testing.T) {
t.Fatal(err)
}

hooks, err := r.Hooks()
hooks, err := r.Hooks("")
if err != nil {
t.Fatal(err)
}
Expand All @@ -57,7 +57,7 @@ func TestRepository_Hooks(t *testing.T) {
_ = os.RemoveAll(dir)
}()

hooks, err := r.Hooks()
hooks, err := r.Hooks("")
if err != nil {
t.Fatal(err)
}
Expand All @@ -75,7 +75,7 @@ func TestRepository_Hooks(t *testing.T) {
t.Fatal(err)
}

hooks, err := testrepo.Hooks()
hooks, err := testrepo.Hooks("")
if err != nil {
t.Fatal(err)
}
Expand Down
12 changes: 9 additions & 3 deletions repo_pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ type MergeBaseOptions struct {
Timeout time.Duration
}

// MergeBase returns merge base between base and head revisions.
func (r *Repository) MergeBase(base, head string, opts ...MergeBaseOptions) (string, error) {
// RepoMergeBase returns merge base between base and head revisions of the repository
// in given path.
func RepoMergeBase(repoPath, base, head string, opts ...MergeBaseOptions) (string, error) {
var opt MergeBaseOptions
if len(opts) > 0 {
opt = opts[0]
}

stdout, err := NewCommand("merge-base", base, head).RunInDirWithTimeout(opt.Timeout, r.path)
stdout, err := NewCommand("merge-base", base, head).RunInDirWithTimeout(opt.Timeout, repoPath)
if err != nil {
if strings.Contains(err.Error(), "exit status 1") {
return "", ErrNoMergeBase
Expand All @@ -33,3 +34,8 @@ func (r *Repository) MergeBase(base, head string, opts ...MergeBaseOptions) (str
}
return strings.TrimSpace(string(stdout)), nil
}

// MergeBase returns merge base between base and head revisions of the repository.
func (r *Repository) MergeBase(base, head string, opts ...MergeBaseOptions) (string, error) {
return RepoMergeBase(r.path, base, head, opts...)
}
Loading