diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2019-06-14 05:51:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-14 05:51:32 +0200 |
commit | 26b54e8c7bc9678bf87c6ba298edf38d34b51d25 (patch) | |
tree | 87d02875aa79bb1e6372c21d20a1afed0844ab41 /_examples/merge_base/main.go | |
parent | 6142bc316a5ade48044c95f5be92872e7e00b7d6 (diff) | |
parent | 56af959fab24bced5dd9da383d6b12f125526017 (diff) | |
download | go-git-26b54e8c7bc9678bf87c6ba298edf38d34b51d25.tar.gz |
Merge pull request #1096 from dpordomingo/merge-base-command
Add merge base command
Diffstat (limited to '_examples/merge_base/main.go')
-rw-r--r-- | _examples/merge_base/main.go | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/_examples/merge_base/main.go b/_examples/merge_base/main.go new file mode 100644 index 0000000..fe6abc6 --- /dev/null +++ b/_examples/merge_base/main.go @@ -0,0 +1,124 @@ +package main + +import ( + "os" + + "gopkg.in/src-d/go-git.v4" + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/plumbing/object" +) + +type exitCode int + +const ( + exitCodeSuccess exitCode = iota + exitCodeNotFound + exitCodeWrongSyntax + exitCodeCouldNotOpenRepository + exitCodeCouldNotParseRevision + exitCodeUnexpected + + cmdDesc = "Returns the merge-base between two commits:" + + helpShortMsg = ` + usage: %_COMMAND_NAME_% <path> <commitRev> <commitRev> + or: %_COMMAND_NAME_% <path> --independent <commitRev>... + or: %_COMMAND_NAME_% <path> --is-ancestor <commitRev> <commitRev> + or: %_COMMAND_NAME_% --help + + params: + <path> path to the git repository + <commitRev> git revision as supported by go-git + +options: + (no options) lists the best common ancestors of the two passed commits + --independent list commits not reachable from the others + --is-ancestor is the first one ancestor of the other? + --help show the full help message of %_COMMAND_NAME_% +` +) + +// Command that mimics `git merge-base --all <baseRev> <headRev>` +// Command that mimics `git merge-base --is-ancestor <baseRev> <headRev>` +// Command that mimics `git merge-base --independent <commitRev>...` +func main() { + if len(os.Args) == 1 { + helpAndExit("Returns the merge-base between two commits:", helpShortMsg, exitCodeSuccess) + } + + if os.Args[1] == "--help" || os.Args[1] == "-h" { + helpAndExit("Returns the merge-base between two commits:", helpLongMsg, exitCodeSuccess) + } + + if len(os.Args) < 4 { + helpAndExit("Wrong syntax", helpShortMsg, exitCodeWrongSyntax) + } + + path := os.Args[1] + + var modeIndependent, modeAncestor bool + var commitRevs []string + var res []*object.Commit + + switch os.Args[2] { + case "--independent": + modeIndependent = true + commitRevs = os.Args[3:] + case "--is-ancestor": + modeAncestor = true + commitRevs = os.Args[3:] + if len(commitRevs) != 2 { + helpAndExit("Wrong syntax", helpShortMsg, exitCodeWrongSyntax) + } + default: + commitRevs = os.Args[2:] + if len(commitRevs) != 2 { + helpAndExit("Wrong syntax", helpShortMsg, exitCodeWrongSyntax) + } + } + + // Open a git repository from current directory + repo, err := git.PlainOpen(path) + checkIfError(err, exitCodeCouldNotOpenRepository, "not in a git repository") + + // Get the hashes of the passed revisions + var hashes []*plumbing.Hash + for _, rev := range commitRevs { + hash, err := repo.ResolveRevision(plumbing.Revision(rev)) + checkIfError(err, exitCodeCouldNotParseRevision, "could not parse revision '%s'", rev) + hashes = append(hashes, hash) + } + + // Get the commits identified by the passed hashes + var commits []*object.Commit + for _, hash := range hashes { + commit, err := repo.CommitObject(*hash) + checkIfError(err, exitCodeUnexpected, "could not find commit '%s'", hash.String()) + commits = append(commits, commit) + } + + if modeAncestor { + isAncestor, err := commits[0].IsAncestor(commits[1]) + checkIfError(err, exitCodeUnexpected, "could not traverse the repository history") + + if !isAncestor { + os.Exit(int(exitCodeNotFound)) + } + + os.Exit(int(exitCodeSuccess)) + } + + if modeIndependent { + res, err = object.Independents(commits) + checkIfError(err, exitCodeUnexpected, "could not traverse the repository history") + } else { + res, err = commits[0].MergeBase(commits[1]) + checkIfError(err, exitCodeUnexpected, "could not traverse the repository history") + + if len(res) == 0 { + os.Exit(int(exitCodeNotFound)) + } + } + + printCommits(res) +} |