diff options
| author | Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com> | 2018-11-30 15:10:19 +0300 |
|---|---|---|
| committer | Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com> | 2018-11-30 16:57:32 +0300 |
| commit | b979bfadefd82f258faea98b9abdc5f57e68aa51 (patch) | |
| tree | b7fa3a04587e5dce090f1023e4a5d0012c036ef6 | |
| parent | minor change on hash limit and moved the code to more cohesive pkg (diff) | |
| download | gitbatch-b979bfadefd82f258faea98b9abdc5f57e68aa51.tar.gz | |
added some documentation for git package
| -rw-r--r-- | pkg/git/branch.go | 30 | ||||
| -rw-r--r-- | pkg/git/commit.go | 19 | ||||
| -rw-r--r-- | pkg/git/git-commands.go | 10 | ||||
| -rw-r--r-- | pkg/git/load.go | 2 | ||||
| -rw-r--r-- | pkg/git/remote.go | 6 | ||||
| -rw-r--r-- | pkg/git/remotebranch.go | 8 | ||||
| -rw-r--r-- | pkg/git/repository.go | 25 |
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 { |
