summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIbrahim Serdar Acikgoz <serdaracikgoz86@gmail.com>2018-11-30 15:10:19 +0300
committerIbrahim Serdar Acikgoz <serdaracikgoz86@gmail.com>2018-11-30 16:57:32 +0300
commitb979bfadefd82f258faea98b9abdc5f57e68aa51 (patch)
treeb7fa3a04587e5dce090f1023e4a5d0012c036ef6
parentminor change on hash limit and moved the code to more cohesive pkg (diff)
downloadgitbatch-b979bfadefd82f258faea98b9abdc5f57e68aa51.tar.gz
added some documentation for git package
-rw-r--r--pkg/git/branch.go30
-rw-r--r--pkg/git/commit.go19
-rw-r--r--pkg/git/git-commands.go10
-rw-r--r--pkg/git/load.go2
-rw-r--r--pkg/git/remote.go6
-rw-r--r--pkg/git/remotebranch.go8
-rw-r--r--pkg/git/repository.go25
7 files changed, 80 insertions, 20 deletions
diff --git a/pkg/git/branch.go b/pkg/git/branch.go
index b1d0204..3a4f7ce 100644
--- a/pkg/git/branch.go
+++ b/pkg/git/branch.go
@@ -8,6 +8,10 @@ import (
"regexp"
)
+// Branch is the wrapper of go-git's Reference struct. In addition to that, it
+// also holds name of the branch, pullable and pushable commit count from the
+// branchs' upstream. It also tracks if the repository has unstaged or uncommit-
+// ed changes
type Branch struct {
Name string
Reference *plumbing.Reference
@@ -16,6 +20,8 @@ type Branch struct {
Clean bool
}
+// returns the active branch of the repository entity by simply getting the
+// head reference and searching it from the entities branch slice
func (entity *RepoEntity) getActiveBranch() (branch *Branch) {
headRef, _ := entity.Repository.Head()
for _, lb := range entity.Branches {
@@ -26,6 +32,9 @@ func (entity *RepoEntity) getActiveBranch() (branch *Branch) {
return nil
}
+// search for branches in go-git way. It is useful to do so that checkout and
+// checkout error handling can be handled by code rather than struggling with
+// git cammand and its output
func (entity *RepoEntity) loadLocalBranches() error {
lbs := make([]*Branch, 0)
branches, err := entity.Repository.Branches()
@@ -46,6 +55,7 @@ func (entity *RepoEntity) loadLocalBranches() error {
return err
}
+// checkouts the next branch
func (entity *RepoEntity) NextBranch() *Branch {
currentBranch := entity.Branch
currentBranchIndex := 0
@@ -60,6 +70,8 @@ func (entity *RepoEntity) NextBranch() *Branch {
return entity.Branches[currentBranchIndex+1]
}
+// checkout to given branch. If any errors occur, the method returns it instead
+// of returning nil
func (entity *RepoEntity) Checkout(branch *Branch) error {
if branch.Name == entity.Branch.Name {
return nil
@@ -73,6 +85,8 @@ func (entity *RepoEntity) Checkout(branch *Branch) error {
}); err != nil {
return err
}
+
+ // after checking out we need to refresh some values such as;
entity.loadCommits()
entity.Commit = entity.Commits[0]
entity.Branch = branch
@@ -86,17 +100,10 @@ func (entity *RepoEntity) Checkout(branch *Branch) error {
return nil
}
+// checking the branch if it has any changes from its head revision. Initially
+// I implemented this with go-git but it was incredibly slow and there is also
+// an issue about it: https://github.com/src-d/go-git/issues/844
func (entity *RepoEntity) isClean() bool {
- // this method is painfully slow
- // worktree, err := entity.Repository.Worktree()
- // if err != nil {
- // return true
- // }
- // status, err := worktree.Status()
- // if err != nil {
- // return false
- // }
- // return status.IsClean()
status := entity.StatusWithGit()
status = utils.TrimTrailingNewline(status)
if status != "?" {
@@ -109,10 +116,13 @@ func (entity *RepoEntity) isClean() bool {
return false
}
+// refreshes the active branchs pushable and pullable count
func (entity *RepoEntity) RefreshPushPull() {
entity.Branch.Pushables, entity.Branch.Pullables = UpstreamDifferenceCount(entity.AbsPath)
}
+// this function creates the commit entities according to active branchs diffs
+// to *its* configured upstream
func (entity *RepoEntity) pullDiffsToUpstream() ([]*Commit, error) {
remoteCommits := make([]*Commit, 0)
hashes := UpstreamPullDiffs(entity.AbsPath)
diff --git a/pkg/git/commit.go b/pkg/git/commit.go
index 2021a0c..9045555 100644
--- a/pkg/git/commit.go
+++ b/pkg/git/commit.go
@@ -8,10 +8,9 @@ import (
"gopkg.in/src-d/go-git.v4/plumbing/object"
)
-var (
- Hashlimit = 7
-)
-
+// Commit is the lightweight version of go-git's Reference struct. it holds
+// hash of the commit, author's e-mail address, Message (subject and body
+// combined) commit date and commit type wheter it is local commit or a remote
type Commit struct {
Hash string
Author string
@@ -20,6 +19,7 @@ type Commit struct {
CommitType CommitType
}
+// type of the commit; it can be local or remote (upstream diff)
type CommitType string
const (
@@ -27,6 +27,8 @@ const (
RemoteCommit CommitType = "remote"
)
+// iterate over next commit of a branch
+// TODO: the commits entites can tied to branch instead ot the repository
func (entity *RepoEntity) NextCommit() error {
currentCommitIndex := 0
for i, cs := range entity.Commits {
@@ -42,6 +44,8 @@ func (entity *RepoEntity) NextCommit() error {
return nil
}
+// loads the local commits by simply using git log way. ALso, gets the upstream
+// diff commits
func (entity *RepoEntity) loadCommits() error {
r := entity.Repository
entity.Commits = make([]*Commit, 0)
@@ -83,6 +87,9 @@ func (entity *RepoEntity) loadCommits() error {
return nil
}
+
+// returns the diff to previous commit detail of the given hash of a specific
+// commit
func (entity *RepoEntity) Diff(hash string) (diff string, err error) {
currentCommitIndex := 0
@@ -95,8 +102,9 @@ func (entity *RepoEntity) Diff(hash string) (diff string, err error) {
return "there is no diff", nil
}
+ // maybe we dont need to log the repo again?
commits, err := entity.Repository.Log(&git.LogOptions{
- From: plumbing.NewHash(entity.Commit.Hash), //plumbing.NewHash(entity.Commits[currentCommitIndex].Hash),
+ From: plumbing.NewHash(entity.Commit.Hash),
Order: git.LogOrderCommitterTime,
})
if err != nil {
@@ -126,6 +134,7 @@ func (entity *RepoEntity) Diff(hash string) (diff string, err error) {
return "", err
}
+ // here we collect the actual diff
for _, c := range changes {
patch, err := c.Patch()
if err != nil {
diff --git a/pkg/git/git-commands.go b/pkg/git/git-commands.go
index 82dad46..7216b17 100644
--- a/pkg/git/git-commands.go
+++ b/pkg/git/git-commands.go
@@ -23,6 +23,7 @@ func UpstreamDifferenceCount(repoPath string) (string, string) {
return strings.TrimSpace(pushableCount), strings.TrimSpace(pullableCount)
}
+// Instead of returning the count, this method returns the hash list
func UpstreamPushDiffs(repoPath string) string {
args := []string{"rev-list", "@{u}..HEAD"}
pushableCount, err := command.RunCommandWithOutput(repoPath, "git", args)
@@ -32,6 +33,7 @@ func UpstreamPushDiffs(repoPath string) string {
return pushableCount
}
+// Instead of returning the count, this method returns the hash list
func UpstreamPullDiffs(repoPath string) string {
args := []string{"rev-list", "HEAD..@{u}"}
pullableCount, err := command.RunCommandWithOutput(repoPath, "git", args)
@@ -41,6 +43,7 @@ func UpstreamPullDiffs(repoPath string) string {
return pullableCount
}
+// Conventional git show command without any argument
func GitShow(repoPath, hash string) string {
args := []string{"show", hash}
diff, err := command.RunCommandWithOutput(repoPath, "git", args)
@@ -50,6 +53,7 @@ func GitShow(repoPath, hash string) string {
return diff
}
+// get author's e-mail with git show command
func GitShowEmail(repoPath, hash string) string {
args := []string{"show", "--quiet", "--pretty=format:%ae", hash}
diff, err := command.RunCommandWithOutput(repoPath, "git", args)
@@ -59,6 +63,7 @@ func GitShowEmail(repoPath, hash string) string {
return diff
}
+// get body of the commit with git show
func GitShowBody(repoPath, hash string) string {
args := []string{"show", "--quiet", "--pretty=format:%B", hash}
diff, err := command.RunCommandWithOutput(repoPath, "git", args)
@@ -68,6 +73,7 @@ func GitShowBody(repoPath, hash string) string {
return diff
}
+// get commit's date with git show as string
func GitShowDate(repoPath, hash string) string {
args := []string{"show", "--quiet", "--pretty=format:%ai", hash}
diff, err := command.RunCommandWithOutput(repoPath, "git", args)
@@ -77,6 +83,7 @@ func GitShowDate(repoPath, hash string) string {
return diff
}
+// wrapper of the git fetch <remote> command
func (entity *RepoEntity) FetchWithGit(remote string) error {
args := []string{"fetch", remote}
_, err := command.RunCommandWithOutput(entity.AbsPath, "git", args)
@@ -86,6 +93,7 @@ func (entity *RepoEntity) FetchWithGit(remote string) error {
return nil
}
+// wrapper of the git pull <remote>/<branch> command
func (entity *RepoEntity) PullWithGit(remote, branch string) error {
args := []string{"pull", remote, branch}
_, err := command.RunCommandWithOutput(entity.AbsPath, "git", args)
@@ -95,6 +103,7 @@ func (entity *RepoEntity) PullWithGit(remote, branch string) error {
return nil
}
+// wrapper of the git merge <branch> command
func (entity *RepoEntity) MergeWithGit(mergeFrom string) error {
args := []string{"merge", mergeFrom}
_, err := command.RunCommandWithOutput(entity.AbsPath, "git", args)
@@ -104,6 +113,7 @@ func (entity *RepoEntity) MergeWithGit(mergeFrom string) error {
return nil
}
+// wrapper of the git checkout <branch> command
func (entity *RepoEntity) CheckoutWithGit(branch string) error {
args := []string{"checkout", branch}
_, err := command.RunCommandWithOutput(entity.AbsPath, "git", args)
diff --git a/pkg/git/load.go b/pkg/git/load.go
index f8032e8..dd92ec5 100644
--- a/pkg/git/load.go
+++ b/pkg/git/load.go
@@ -4,6 +4,8 @@ import (
"sync"
)
+// initializes the go-git's repository obejcts with given slice of paths. since
+// this job is done parallel, the order of the directories is not kept
func LoadRepositoryEntities(directories []string) (entities []*RepoEntity, err error) {
entities = make([]*RepoEntity, 0)
diff --git a/pkg/git/remote.go b/pkg/git/remote.go
index 6beef29..b7bd907 100644
--- a/pkg/git/remote.go
+++ b/pkg/git/remote.go
@@ -1,5 +1,8 @@
package git
+// this struct is simply a collection of remote branches and wraps it with the
+// name of the remote and fetch/push urls. It also holds the *selected* remote
+// branch
type Remote struct {
Name string
URL []string
@@ -7,6 +10,7 @@ type Remote struct {
Branches []*RemoteBranch
}
+// iterate over next branch of a remote
func (entity *RepoEntity) NextRemote() error {
currentRemoteIndex := 0
for i, remote := range entity.Remotes {
@@ -27,6 +31,8 @@ func (entity *RepoEntity) NextRemote() error {
return nil
}
+// search for remotes in go-git way. It is the short way to get remotes but it
+// does not give any insght about remote branches
func (entity *RepoEntity) loadRemotes() error {
r := entity.Repository
entity.Remotes = make([]*Remote, 0)
diff --git a/pkg/git/remotebranch.go b/pkg/git/remotebranch.go
index 583c323..b37d3b7 100644
--- a/pkg/git/remotebranch.go
+++ b/pkg/git/remotebranch.go
@@ -9,11 +9,14 @@ import (
"gopkg.in/src-d/go-git.v4/plumbing/storer"
)
+// RemoteBranch is the wrapper of go-git's Reference struct. In addition to
+// that, it also holds name of the remote branch
type RemoteBranch struct {
Name string
Reference *plumbing.Reference
}
+// iterates to the next remote branch
func (remote *Remote) NextRemoteBranch() error {
currentRemoteIndex := 0
for i, rb := range remote.Branches {
@@ -30,6 +33,8 @@ func (remote *Remote) NextRemoteBranch() error {
return nil
}
+// search for the remote branches of the remote. It takes the go-git's repo
+// pointer in order to get storer struct
func (remote *Remote) loadRemoteBranches(r *git.Repository) error {
remote.Branches = make([]*RemoteBranch, 0)
bs, err := remoteBranchesIter(r.Storer)
@@ -52,6 +57,8 @@ func (remote *Remote) loadRemoteBranches(r *git.Repository) error {
return err
}
+// create an iterator for the references. it checks if the reference is a hash
+// reference
func remoteBranchesIter(s storer.ReferenceStorer) (storer.ReferenceIter, error) {
refs, err := s.IterReferences()
if err != nil {
@@ -66,6 +73,7 @@ func remoteBranchesIter(s storer.ReferenceStorer) (storer.ReferenceIter, error)
}, refs), nil
}
+// switches to the given remote branch
func (remote *Remote) switchRemoteBranch(remoteBranchName string) error {
for _, rb := range remote.Branches {
if rb.Name == remoteBranchName {
diff --git a/pkg/git/repository.go b/pkg/git/repository.go
index f019731..33fdcbd 100644
--- a/pkg/git/repository.go
+++ b/pkg/git/repository.go
@@ -9,6 +9,9 @@ import (
"gopkg.in/src-d/go-git.v4"
)
+// the main entity of the application. The repository name is actually the name
+// of its folder in the host's filesystem. It holds the go-git repository entity
+// along with critic entites such as remote/branches and commits
type RepoEntity struct {
RepoID string
Name string
@@ -23,6 +26,7 @@ type RepoEntity struct {
State RepoState
}
+// it is the state of the repository for an operation
type RepoState uint8
const (
@@ -33,6 +37,7 @@ const (
Fail RepoState = 4
)
+// initializee a RepoEntity struct with its belongings.
func InitializeRepository(directory string) (entity *RepoEntity, err error) {
file, err := os.Open(directory)
if err != nil {
@@ -52,14 +57,19 @@ func InitializeRepository(directory string) (entity *RepoEntity, err error) {
Repository: *r,
State: Available,
}
+ // after we intiate the struct we can fill its values
entity.loadLocalBranches()
entity.loadCommits()
+ // handle if there is no commit, maybe?
if len(entity.Commits) > 0 {
+ // select first commit
entity.Commit = entity.Commits[0]
} else {
return entity, errors.New("There is no commit for this repository: " + directory)
}
+ // lets load remotes this time
entity.loadRemotes()
+ // set the active branch to repositories HEAD
entity.Branch = entity.getActiveBranch()
if len(entity.Remotes) > 0 {
// TODO: tend to take origin/master as default
@@ -69,11 +79,15 @@ func InitializeRepository(directory string) (entity *RepoEntity, err error) {
// probably couldn't find, but its ok.
}
} else {
+ // if there is no remote, this project is totally useless actually
return entity, errors.New("There is no remote for this repository: " + directory)
}
return entity, nil
}
+// Incorporates changes from a remote repository into the current branch. In
+// its default mode, git pull is shorthand for git fetch followed by git merge
+// <branch>
func (entity *RepoEntity) Pull() error {
// TODO: Migrate this code to src-d/go-git
// 2018-11-25: tried but it fails, will investigate.
@@ -91,11 +105,8 @@ func (entity *RepoEntity) Pull() error {
return nil
}
-func (entity *RepoEntity) PullTest() error {
- time.Sleep(5 * time.Second)
- return nil
-}
-
+// Fetch branches refs from one or more other repositories, along with the
+// objects necessary to complete their histories
func (entity *RepoEntity) Fetch() error {
rm := entity.Remote.Name
if err := entity.FetchWithGit(rm); err != nil {
@@ -106,6 +117,8 @@ func (entity *RepoEntity) Fetch() error {
return nil
}
+// Incorporates changes from the named commits or branches into the current
+// branch
func (entity *RepoEntity) Merge() error {
entity.Checkout(entity.Branch)
if err := entity.MergeWithGit(entity.Remote.Branch.Name); err != nil {
@@ -116,6 +129,8 @@ func (entity *RepoEntity) Merge() error {
return nil
}
+// refresh the belongings of a repositoriy, this function is called right after
+// fetch/pull/merge operations
func (entity *RepoEntity) Refresh() error {
r, err := git.PlainOpen(entity.AbsPath)
if err != nil {