Skip to content
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

Show log(x).since combination in README #699

Merged
merged 11 commits into from
Mar 19, 2024
40 changes: 22 additions & 18 deletions .github/workflows/continuous_integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,43 @@ name: CI

on:
push:
branches: [master]
branches: [master,v1]
pull_request:
branches: [master]
branches: [master,v1]
workflow_dispatch:

jobs:
continuous_integration_build:
continue-on-error: true
build:
name: Ruby ${{ matrix.ruby }} on ${{ matrix.operating-system }}
runs-on: ${{ matrix.operating-system }}
continue-on-error: ${{ matrix.experimental == 'Yes' }}
env: { JAVA_OPTS: -Djdk.io.File.enableADS=true }

strategy:
fail-fast: false
matrix:
ruby: [2.7, 3.0, 3.1, 3.2]
# Only the latest versions of JRuby and TruffleRuby are tested
ruby: ["3.0", "3.1", "3.2", "3.3", "truffleruby-24.0.0", "jruby-9.4.5.0"]
operating-system: [ubuntu-latest]
experimental: [No]
include:
- ruby: head
- # Building against head version of Ruby is considered experimental
ruby: head
operating-system: ubuntu-latest
- ruby: truffleruby-head
operating-system: ubuntu-latest
- ruby: 2.7
operating-system: windows-latest
- ruby: jruby-head
operating-system: windows-latest
experimental: Yes

name: Ruby ${{ matrix.ruby }} on ${{ matrix.operating-system }}

runs-on: ${{ matrix.operating-system }}
- # Only test with minimal Ruby version on Windows
ruby: 3.0
operating-system: windows-latest

env:
JAVA_OPTS: -Djdk.io.File.enableADS=true
- # Since JRuby on Windows is known to not work, consider this experimental
ruby: jruby-9.4.5.0
operating-system: windows-latest
experimental: Yes

steps:
- name: Checkout Code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Setup Ruby
uses: ruby/setup-ruby@v1
Expand Down
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,33 @@

# Change Log

## v2.0.0.pre3 (2024-03-15)

[Full Changelog](https://github.com/ruby-git/ruby-git/compare/v2.0.0.pre2..v2.0.0.pre3)

Changes since v2.0.0.pre2:

* 5d4b34e Allow allow_unrelated_histories option for Base#pull

## v2.0.0.pre2 (2024-02-24)

[Full Changelog](https://github.com/ruby-git/ruby-git/compare/v2.0.0.pre1..v2.0.0.pre2)

Changes since v2.0.0.pre1:

* 023017b Add a timeout for git commands (#692)
* 8286ceb Refactor the Error heriarchy (#693)

## v2.0.0.pre1 (2024-01-15)

[Full Changelog](https://github.com/ruby-git/ruby-git/compare/v1.19.1..v2.0.0.pre1)

Changes since v1.19.1:

* 7585c39 Change how the git CLI subprocess is executed (#684)
* f93e042 Update instructions for releasing a new version of the git gem (#686)
* f48930d Update minimum required version of Ruby and Git (#685)

## v1.19.1 (2024-01-13)

[Full Changelog](https://github.com/ruby-git/ruby-git/compare/v1.19.0..v1.19.1)
Expand Down
190 changes: 153 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,32 @@
[![Build Status](https://github.com/ruby-git/ruby-git/workflows/CI/badge.svg?branch=master)](https://github.com/ruby-git/ruby-git/actions?query=workflow%3ACI)
[![Code Climate](https://codeclimate.com/github/ruby-git/ruby-git.png)](https://codeclimate.com/github/ruby-git/ruby-git)

* [Summary](#summary)
* [v2.0.0 pre-release](#v200-pre-release)
* [Install](#install)
* [Major Objects](#major-objects)
* [Errors Raised By This Gem](#errors-raised-by-this-gem)
* [Specifying And Handling Timeouts](#specifying-and-handling-timeouts)
* [Examples](#examples)
* [Ruby version support policy](#ruby-version-support-policy)
* [License](#license)

## Summary

The [git gem](https://rubygems.org/gems/git) provides an API that can be used to
create, read, and manipulate Git repositories by wrapping system calls to the `git`
command line. The API can be used for working with Git in complex interactions
including branching and merging, object inspection and manipulation, history, patch
generation and more.

Get started by obtaining a repository object by:

* opening an existing working copy with [Git.open](https://rubydoc.info/gems/git/Git#open-class_method)
* initializing a new repository with [Git.init](https://rubydoc.info/gems/git/Git#init-class_method)
* cloning a repository with [Git.clone](https://rubydoc.info/gems/git/Git#clone-class_method)

Methods that can be called on a repository object are documented in [Git::Base](https://rubydoc.info/gems/git/Git/Base)

## v2.0.0 pre-release

git 2.0.0 is available as a pre-release version for testing! Please give it a try.
Expand All @@ -32,7 +52,7 @@ The changes coming in this major release include:
* Update the required Git command line version to at least 2.28
* Update how CLI commands are called to use the [process_executer](https://github.com/main-branch/process_executer)
gem which is built on top of [Kernel.spawn](https://ruby-doc.org/3.3.0/Kernel.html#method-i-spawn).
See [PR #617](https://github.com/ruby-git/ruby-git/pull/617) for more details
See [PR #684](https://github.com/ruby-git/ruby-git/pull/684) for more details
on the motivation for this implementation.

The tentative plan is to release `2.0.0` near the end of March 2024 depending on
Expand All @@ -41,36 +61,19 @@ the feedback received during the pre-release period.
The `master` branch will be used for `2.x` development. If needed, fixes for `1.x`
version will be done on the `v1` branch.

## Homepage

The project source code is at:

http://github.com/ruby-git/ruby-git

## Documentation

Detailed documentation can be found at:

https://rubydoc.info/gems/git/Git.html

Get started by obtaining a repository object by:

* opening an existing working copy with [Git.open](https://rubydoc.info/gems/git/Git#open-class_method)
* initializing a new repository with [Git.init](https://rubydoc.info/gems/git/Git#init-class_method)
* cloning a repository with [Git.clone](https://rubydoc.info/gems/git/Git#clone-class_method)

Methods that can be called on a repository object are documented in [Git::Base](https://rubydoc.info/gems/git/Git/Base)

## Install

You can install Ruby/Git like this:
Install the gem and add to the application's Gemfile by executing:

```
sudo gem install git
```shell
bundle add git
```

## Code Status
If bundler is not being used to manage dependencies, install the gem by executing:

```shell
gem install git
```

## Major Objects

Expand Down Expand Up @@ -99,17 +102,119 @@ Pass the `--all` option to `git log` as follows:

**Git::Worktrees** - Enumerable object that holds `Git::Worktree objects`.

## Examples
## Errors Raised By This Gem

Here are a bunch of examples of how to use the Ruby/Git package.
This gem raises custom errors that derive from `Git::Error`. These errors are
arranged in the following class heirarchy:

Error heirarchy:

```text
Error
└── CommandLineError
├── FailedError
└── SignaledError
└── TimeoutError
```

Ruby < 1.9 will require rubygems to be loaded.
Other standard errors may also be raised like `ArgumentError`. Each method should
document the errors it may raise.

Description of each Error class:

* `Error`: This catch-all error serves as the base class for other custom errors in this
gem. Errors of this class are raised when no more approriate specific error to
raise.
* `CommandLineError`: This error is raised when there's a problem executing the git
command line. This gem will raise a more specific error depending on how the
command line failed.
* `FailedError`: This error is raised when the git command line exits with a non-zero
status code that is not expected by the git gem.
* `SignaledError`: This error is raised when the git command line is terminated as a
result of receiving a signal. This could happen if the process is forcibly
terminated or if there is a serious system error.
* `TimeoutError`: This is a specific type of `SignaledError` that is raised when the
git command line operation times out and is killed via the SIGKILL signal. This
happens if the operation takes longer than the timeout duration configured in
`Git.config.timeout` or via the `:timeout` parameter given in git methods that
support this parameter.

`Git::GitExecuteError` remains as an alias for `Git::Error`. It is considered
deprecated as of git-2.0.0.

Here is an example of catching errors when using the git gem:

```ruby
require 'rubygems'
begin
timeout_duration = 0.001 # seconds
repo = Git.clone('https://github.com/ruby-git/ruby-git', 'ruby-git-temp', timeout: timeout_duration)
rescue Git::TimeoutError => e # Catch the more specific error first!
puts "Git clone took too long and timed out #{e}"
rescue Git::Error => e
puts "Received the following error: #{e}"
```

## Specifying And Handling Timeouts

The timeout feature was added in git gem version `2.0.0`.

A timeout for git operations can be set either globally or for specific method calls
that accept a `:timeout` parameter.

The timeout value must be a real, non-negative `Numeric` value that specifies a
number of seconds a `git` command will be given to complete before being sent a KILL
signal. This library may hang if the `git` command does not terminate after receiving
the KILL signal.

When a command times out, a `Git::TimeoutError` is raised.

If the timeout value is `0` or `nil`, no timeout will be enforced.

If a method accepts a `:timeout` parameter and a receives a non-nil value, it will
override the global timeout value. In this context, a value of `nil` (which is
usually the default) will use the global timeout value and a value of `0` will turn
off timeout enforcement for that method call no matter what the global value is.

To set a global timeout, use the `Git.config` object:

```ruby
Git.config.timeout = nil # a value of nil or 0 means no timeout is enforced
Git.config.timeout = 1.5 # can be any real, non-negative Numeric interpreted as number of seconds
```

The global timeout can be overridden for a specific method if the method accepts a
`:timeout` parameter:

```ruby
repo_url = 'https://github.com/ruby-git/ruby-git.git'
Git.clone(repo_url) # Use the global timeout value
Git.clone(repo_url, timeout: nil) # Also uses the global timeout value
Git.clone(repo_url, timeout: 0) # Do not enforce a timeout
Git.clone(repo_url, timeout: 10.5) # Timeout after 10.5 seconds raising Git::SignaledError
```

If the command takes too long, a `Git::SignaledError` will be raised:

```ruby
begin
Git.clone(repo_url, timeout: 10)
rescue Git::TimeoutError => e
result = e.result
result.class #=> Git::CommandLineResult
result.status #=> #<Process::Status: pid 62173 SIGKILL (signal 9)>
result.status.timeout? #=> true
result.git_cmd # The git command ran as an array of strings
result.stdout # The command's output to stdout until it was terminated
result.stderr # The command's output to stderr until it was terminated
end
```

## Examples

Here are a bunch of examples of how to use the Ruby/Git package.

Require the 'git' gem.

```ruby
require 'git'
```
Expand Down Expand Up @@ -139,9 +244,12 @@ g.index.writable?
g.repo
g.dir

g.log # returns a Git::Log object, which is an Enumerator of Git::Commit objects
g.log(200)
g.log.since('2 weeks ago')
# log - returns a Git::Log object, which is an Enumerator of Git::Commit objects
# default configuration returns a max of 30 commits
g.log
g.log(200) # 200 most recent commits
g.log.since('2 weeks ago') # default count of commits since 2 weeks ago.
g.log(200).since('2 weeks ago') # commits since 2 weeks ago, limited to 200.
g.log.between('v2.5', 'v2.6')
g.log.each {|l| puts l.sha }
g.gblob('v2.5:Makefile').log.since('2 weeks ago')
Expand Down Expand Up @@ -276,11 +384,11 @@ g.add(:all=>true) # git add --all -- "."
g.add('file_path') # git add -- "file_path"
g.add(['file_path_1', 'file_path_2']) # git add -- "file_path_1" "file_path_2"

g.remove() # git rm -f -- "."
g.remove('file.txt') # git rm -f -- "file.txt"
g.remove(['file.txt', 'file2.txt']) # git rm -f -- "file.txt" "file2.txt"
g.remove('file.txt', :recursive => true) # git rm -f -r -- "file.txt"
g.remove('file.txt', :cached => true) # git rm -f --cached -- "file.txt"
g.remove() # git rm -f -- "."
g.remove('file.txt') # git rm -f -- "file.txt"
g.remove(['file.txt', 'file2.txt']) # git rm -f -- "file.txt" "file2.txt"
g.remove('file.txt', :recursive => true) # git rm -f -r -- "file.txt"
g.remove('file.txt', :cached => true) # git rm -f --cached -- "file.txt"

g.commit('message')
g.commit_all('message')
Expand Down Expand Up @@ -422,6 +530,14 @@ g.with_temp_working(dir) do
end
```

## Ruby version support policy

This gem will be expected to function correctly on:

* All non-EOL versions of the MRI Ruby on Mac, Linux, and Windows
* The latest version of JRuby on Linux and Windows
* The latest version of Truffle Ruby on Linus

## License

licensed under MIT License Copyright (c) 2008 Scott Chacon. See LICENSE for further details.