Syndication Icon
Published December 30, 2020 Updated October 23, 2021
Git+ Icon

Git+

Git Badge
Alchemists Style Guide
Circle CI Status

Provides a Ruby Object API to various Git commands so you can stay within your favorite language when working with Git. This project is an extraction of work originally implemented within the following projects:

If you are looking for alternatives within this problem space, you might find the following projects of benefit too:

Features

Provides Ruby wrappers to Git commands such as:

Requirements

  1. Git.

  2. Ruby.

Setup

To set up the project, run:

bin/setup

Usage

This project provides a common API within a single object via the Repository object. Example:

repository = GitPlus::Repository.new

repository.branch          # Delegates to `GitPlus::Commands::Branch#call`.
repository.branch_default  # Delegates to `GitPlus::Commands::Branch#default`.
repository.branch_name     # Delegates to `GitPlus::Commands::Branch#name`.
repository.commits         # Delegates to `GitPlus::Parsers::Commits::Saved::History#call`.
repository.config          # Delegates to `GitPlus::Commands::Config#call`.
repository.config_get      # Delegates to `GitPlus::Commands::Config#get`.
repository.config_origin?  # Delegates to `GitPlus::Commands::Config#origin?`.
repository.config_set      # Delegates to `GitPlus::Commands::Config#set`.
repository.fetch           # Delegates to `GitPlus::Commands::Fetch#call`.
repository.log             # Delegates to `GitPlus::Commands::Log#call`.
repository.rev_parse       # Delegates to `GitPlus::Commands::RevParse#call`.
repository.exist?          # Delegates to `GitPlus::Commands::RevParse#directory?`.
repository.show            # Delegates to `GitPlus::Commands::Show#call`.
repository.tag             # Delegates to `GitPlus::Commands::Tag#call`.
repository.tag_exist?      # Delegates to `GitPlus::Commands::Tag#exist?`.
repository.tag_last        # Delegates to `GitPlus::Commands::Tag#last`.
repository.tag_local?      # Delegates to `GitPlus::Commands::Tag#local?`.
repository.tag_push        # Delegates to `GitPlus::Commands::Tag#push`.
repository.tag_remote?     # Delegates to `GitPlus::Commands::Tag#remote?`.
repository.tag_sign        # Delegates to `GitPlus::Commands::Tag#sign`.
repository.tag_unsign      # Delegates to `GitPlus::Commands::Tag#unsign`.
repository.tagged?         # Delegates to `GitPlus::Commands::Tag#tagged?`.
repository.trailers        # Delegates to `GitPlus::Commands::Trailers#call`.
repository.trailers_list   # Delegates to `GitPlus::Commands::Trailers#list`.
repository.unsaved         # Delegates to `GitPlus::Parsers::Commits::Unsaved::History#call`.

Should you want to use individual commands instead of interacting with the Repository object, you can leverage any of the objects in the Commands namespace:

All of the above commands share the same Command Pattern interface via #call.

Branch

Handles branches.

branch = GitPlus::Commands::Branch.new

# Answers branch default (via Git `init.defaultBranch` configuration).
branch.default

# Accepts any argument you'd send to `git branch`.
# Example: branch.call "--edit-description"
stdout, stderr, status = branch.call

# Answers branch name
branch.name

Config

Handles global and local configurations.

config = GitPlus::Commands::Config.new

# Accepts any argument you'd send to `git config`.
# Example: branch.call "--add", "user.email", "test@example.com"
stdout, stderr, status = config.call

# Answers value for key with support for fallback value or block manipulation.
config.get "user.email"
config.get "user.email", "fallback"
config.get("user.email") { |stdout| puts stdout }
config.get("user.email") { |stdout, stderr| puts "#{stdout} - #{stderr}" }

# Answers true or false if origin is defined.
config.origin?

# Sets configuration key and value.
config.set

Fetch

Handles downloading of objects and refs from remote repository.

fetch = GitPlus::Commands::Fetch.new

# Accepts any argument you'd send to `git fetch`.
# Example: fetch.call "--tags"
stdout, stderr, status = fetch.call

Log

Handles commit history.

log = GitPlus::Commands::Log.new

# Accepts any argument you'd send to `git log`.
# Example: log.call "--oneline", "0.1.0..HEAD"
stdout, stderr, status = log.call

RevParse

Handles parsing of revision information.

rev_parse = GitPlus::Commands::RevParse.new

# Accepts any argument you'd send to `git rev-parse`.
# Example: rev_parse.call "--quiet", "--verify", "release"
stdout, stderr, status = rev_parse.call

# Answers true or false if `.git` directory is found.
rev_parse.directory?

Show

Handles showing of specific commit or collection of commits.

show = GitPlus::Commands::Show.new

# Accepts any argument you'd send to `git show`.
# Example: show.call "--stat", "2b47d4e36093"
stdout, stderr, status = show.call

Tag

Handles the tagging/versioning of commits.

tag = GitPlus::Commands::Tag.new

# Accepts any argument you'd send to `git tag`.
# Example: tag.call "--list"
stdout, stderr, status = tag.call

# Answers true or false base on whether local and remote tag exist.
tag.exist? "0.1.0"

# Answers last tag for repository.
tag.last

# Answers if local tag exists.
tag.local? "0.1.0"

# Pushes tags to remote repository.
tag.push

# Answers if remote tag exists.
tag.remote? "0.1.0"

# Creates a new, GPG signed, tag.
tag.sign "0.1.0", "Version 0.1.0"

# Answers true or false based on whether repository is tagged.
tag.tagged?

# Creates a new tag without any GPG signed verification.
tag.unsign "0.1.0", "Version 0.1.0"

Trailers

Handles the adding or parsing of structured information in commit messages.

trailers = GitPlus::Commands::Trailers.new

# Accepts any argument you'd send to `git interpret-trailers`.
# Example: trailers.call "--only-trailers"
stdout, stderr, status = trailers.call

# Answers an array of trailers, otherwise an empty array. Accepts same parameters as `#call`.
trailers.list

Development

You can also use the IRB console for direct access to all objects:

bin/console

Tests

To test, run:

bundle exec rake

Versioning

Read Semantic Versioning for details. Briefly, it means:

  • Major (X.y.z) - Incremented for any backwards incompatible public API changes.

  • Minor (x.Y.z) - Incremented for new, backwards compatible, public API enhancements/fixes.

  • Patch (x.y.Z) - Incremented for small, backwards compatible, bug fixes.

Code of Conduct

Read Code of Conduct for details.

Contributions

Read Contributions for details.

License

Read License for details.

History

Read Changes for details.

Credits

Engineered by Brooke Kuhlmann.