module Git
Define Git::Deprecation before requiring the rest of the library to ensure that any deprecation warnings emitted during the loading of the library are properly configured according to the GIT_DEPRECATION_BEHAVIOR environment variable.
Constants
- AuthorInfo
-
Immutable value object representing an author or committer identity
This is a lightweight, immutable data structure holding the identity data git records for commit authors, committers, and taggers.
@example Construct from individual values
info = Git::AuthorInfo.new( name: 'John Doe', email: 'john.doe@example.com', date: Time.at(1627849923) ) info.name #=> 'John Doe'
@example Parse from a raw git author string
info = Git::AuthorInfo.parse('John Doe <john.doe@example.com> 1627849923 +0200') info.email #=> 'john.doe@example.com' info.date.to_i #=> 1627849923
@see Git::Object::Commit#author
@see Git::Object::Commit#committer
@api public
@!attribute [r] name
@return [String, nil] the person's name, or `nil` if not available
@!attribute [r] email
@return [String, nil] the person's email address, or `nil` if not available
@!attribute [r] date
@return [Time, nil] the timestamp of the change, or `nil` if not available
- BRANCH_REFNAME_REGEXP
-
Regular expression for parsing branch refnames
Captures:
- remote_name: the remote name (e.g., 'origin') for remote branches, nil for local - branch_name: the branch name without the remote prefix
@example Parse branch refnames
'main' => { remote_name: nil, branch_name: 'main' } 'refs/heads/main' => { remote_name: nil, branch_name: 'main' } 'remotes/origin/main' => { remote_name: 'origin', branch_name: 'main' } 'refs/remotes/origin/main' => { remote_name: 'origin', branch_name: 'main' } 'feature/foo' => { remote_name: nil, branch_name: 'feature/foo' } 'remotes/origin/feature/bar' => { remote_name: 'origin', branch_name: 'feature/bar' }
@note This regex handles both raw full refs (e.g., ârefs/heads/main`) as stored in
{Git::BranchInfo#refname} and normalized short-form refs (e.g., `main`, `remotes/origin/main`) used elsewhere.@note This regex is a fallback for branch refnames parsed without configured
remote context. Remote names containing '/' can only be resolved reliably when the parser is given the configured remote names. See: https://github.com/ruby-git/ruby-git/issues/919
@api private
- BranchDeleteFailure
-
Represents a branch that failed to be deleted
This is an immutable data object returned as part of {Git::BranchDeleteResult} when one or more branches could not be deleted.
@example
failure = Git::BranchDeleteFailure.new( name: 'nonexistent', error_message: "branch 'nonexistent' not found." ) failure.name #=> 'nonexistent' failure.error_message #=> "branch 'nonexistent' not found."
@see
Git::Commands::Branch::Delete@api public
@!attribute [r] name
The name of the branch that failed to be deleted @return [String]
@!attribute [r] error_message
The error message from git explaining why the branch could not be deleted @return [String]
- BranchDeleteResult
-
Represents the result of a branch delete operation
This is an immutable data object returned by {Git::Commands::Branch::Delete#call}. It contains information about which branches were successfully deleted and which failed to be deleted, along with the reason for each failure.
Gitâs âgit branch -d` command uses âbest effortâ semantics - it deletes as many branches as possible and reports errors for those that couldnât be deleted. This result object reflects that behavior, allowing callers to inspect both successes and failures.
@example Successful deletion of all branches
result = branch_delete.call('feature-1', 'feature-2') result.success? #=> true result.deleted.map(&:name) #=> ['feature-1', 'feature-2'] result.not_deleted #=> []
@example Partial failure (some branches deleted, some not found)
result = branch_delete.call('feature-1', 'nonexistent', 'feature-2') result.success? #=> false result.deleted.map(&:name) #=> ['feature-1', 'feature-2'] result.not_deleted.first.name #=> 'nonexistent' result.not_deleted.first.error_message #=> "branch 'nonexistent' not found."
@see
Git::BranchInfo@see
Git::Commands::Branch::Delete@api public
@!attribute [r] deleted
Branches that were successfully deleted @return [Array<Git::BranchInfo>]
@!attribute [r] not_deleted
Branches that could not be deleted, with the reason for each failure @return [Array<Git::BranchDeleteFailure>]
- BranchInfo
-
Value object representing branch metadata from git branch output
This is a lightweight, immutable data structure returned by branch listing commands. It contains only the data parsed from git output without any repository context or operations.
@example Local branch with upstream tracking
info = Git::BranchInfo.new( refname: 'refs/heads/main', target_oid: 'abc123def456789012345678901234567890abcd', current: true, worktree_path: nil, symref: nil, upstream: 'refs/remotes/origin/main' ) info.current? #=> true info.remote? #=> false info.short_name #=> 'main' info.upstream #=> 'refs/remotes/origin/main'
@example Remote-tracking branch
info = Git::BranchInfo.new( refname: 'refs/remotes/origin/main', target_oid: 'abc123def456789012345678901234567890abcd', current: false, worktree_path: nil, symref: nil, upstream: nil ) info.remote? #=> true info.remote_name #=> 'origin' info.short_name #=> 'main'
@see
Git::Repository::Branching#branch_listfor the repository method that returns these@see
Git::Commands::Branch::Listfor the command that produces these@api public
@!attribute [r] refname
The full reference name of the branch Must be the full refname as returned by git (e.g., 'refs/heads/main', 'refs/remotes/origin/main') because the short name alone is not guaranteed to be unique (e.g., 'main' could exist as both a local and remote branch). @return [String] the branch refname (e.g., 'refs/heads/main', 'refs/remotes/origin/main')
@!attribute [r] remote_name
@return [String, nil] the resolved or fallback-derived remote name, or nil for local branches
@!attribute [r] target_oid
The commit object ID (SHA) that this branch points to (aka HEAD) @return [String, nil] the full 40-character object ID, or nil if branch is unborn (no commits yet)
@!attribute [r] current
Whether this branch is currently checked out in the current worktree @return [Boolean] true if this is the current branch @note A branch can be current ({#current?} true) or in another worktree ({#other_worktree?} true), but never both. A branch not checked out anywhere has both false.@!attribute [r] worktree_path
The absolute path of the *other* linked worktree this branch is checked out in, or nil. This is nil in two distinct cases: - The branch is the current branch in this worktree (use {#current?} to distinguish that case) - The branch is not checked out in any worktree This path is suppressed for the current branch even though git reports it via `%(worktreepath)`, because the current worktree's path is already known from the repository object and storing it here would make {#other_worktree?} incorrect. @return [String, nil] the absolute path of the linked worktree root directory (e.g., `'/home/user/projects/my-repo-hotfix'`), or nil if the branch is not checked out in a different linked worktree@!attribute [r] symref
The target reference if this is a symbolic reference @return [String, nil] the target ref (e.g., 'refs/heads/main'), or nil if not a symref
@!attribute [r] upstream
The configured upstream/tracking branch refname as reported by git @return [String, nil] the raw upstream refname from `%(upstream)` (e.g., `'refs/remotes/origin/main'`), or nil if no upstream is configured @note Remote-tracking branches (e.g., `'refs/remotes/origin/main'`) have upstream: nil @note This is the raw refname snapshot from when the branch list was read. It does not reflect live git state after the snapshot was taken.
- ConfigEntryInfo
-
Represents a single
Gitconfiguration entryReturned by {Git::Configuring} read operations such as {Git::Configuring#config_get}, {Git::Configuring#config_get_all}, {Git::Configuring#config_list}, and their related methods.
@example Create a
ConfigEntryInfoentry = Git::ConfigEntryInfo.new( scope: 'local', origin: 'file:.git/config', key: 'remote.origin.url', value: 'https://github.com/ruby-git/ruby-git' ) entry.section # => "remote" entry.subsection # => "origin" entry.variable # => "url"
@api public
@!attribute [r] scope
The scope of the configuration entry May be one of `"system"`, `"global"`, `"local"`, `"worktree"`, `"command"`, `"file"`, or `"blob"`. The `"command"` scope is used for values supplied via the command line (including default values from `--default`). @return [String] the config scope string (e.g. `"local"`, `"global"`)
@!attribute [r] origin
Where the configuration entry originates The origin is in the format `<origin-type>:<actual-origin>` and is never blank. The origin type prefix is one of `file:`, `blob:`, `command line:`, or `standard input:`. `nil` when the git command used to retrieve this entry does not support `--show-origin` (currently only `--get-urlmatch`). @return [String, nil] the origin path in the format `<type>:<path>`, or `nil`
@!attribute [r] key
The full dotted key name of the configuration entry (e.g., `remote.origin.url`) @return [String] the full dotted key name (e.g. `remote.origin.url`)
@!attribute [r] value
The value of the configuration entry @return [String] the string value of this entry
- DetachedHeadInfo
-
Value object representing a detached HEAD state
When HEAD points directly to a commit rather than a branch reference, the repository is in a âdetached HEADâ state. This object captures that state along with the commit SHA that HEAD points to.
This class shares a minimal interface with {Git::BranchInfo} to allow polymorphic usage where appropriate:
-
âshort_name` - returns âHEADâ
-
âtarget_oid` - returns the commit SHA
-
âto_s` - returns âHEADâ
-
âdetached?` - returns true
@example Detecting detached HEAD state
head = repo.show_current if head.detached? puts "HEAD detached at #{head.target_oid[0, 7]}" else puts "On branch #{head.short_name}" end
@example Polymorphic usage
head = repo.show_current puts "Checked out: #{head.short_name}" # Works for both types system("git log #{head.short_name}") # Works for both types
@see
Git::BranchInfofor the branch counterpart@see
Git::Commands::Branch::ShowCurrentfor the command that produces this@api private
Work in progress; this class is internal for now and may be made public in a future release.
@!attribute [r] target_oid
The commit object ID (SHA) that HEAD points to @return [String] the full 40-character object ID
-
- DiffFileNumstatInfo
-
Immutable value object representing stats for a single file from git numstat output
@api private
Work in progress; this class is internal for now and may be made public in a future release.
@!attribute [r] path
@return [String] the file path (destination path for renames)
@!attribute [r] src_path
@return [String, nil] the source path for renamed files, nil otherwise
@!attribute [r] insertions
@return [Integer] number of lines inserted
@!attribute [r] deletions
@return [Integer] number of lines deleted
- DiffFilePatchInfo
-
Immutable value object representing a single fileâs patch information
DiffFilePatchInfoencapsulates the parsed data from a unified diff for one file, including source and destination file references, the patch text, change type, and line statistics.@example A modified file patch
patch_info = Git::DiffFilePatchInfo.new( src: Git::FileRef.new(mode: '100644', sha: 'abc1234', path: 'lib/foo.rb'), dst: Git::FileRef.new(mode: '100644', sha: 'def5678', path: 'lib/foo.rb'), patch: "diff --git a/lib/foo.rb b/lib/foo.rb\n...", status: :modified, similarity: nil, binary: false, insertions: 10, deletions: 5 )
@example A new file patch (src is nil)
patch_info = Git::DiffFilePatchInfo.new( src: nil, dst: Git::FileRef.new(mode: '100644', sha: 'abc1234', path: 'lib/new.rb'), patch: "diff --git a/lib/new.rb b/lib/new.rb\nnew file mode 100644\n...", status: :added, similarity: nil, binary: false, insertions: 20, deletions: 0 )
@!attribute [r] src
@return [FileRef, nil] the source file reference, or nil for new/added files
@!attribute [r] dst
@return [FileRef, nil] the destination file reference, or nil for deleted files
@!attribute [r] patch
@return [String] the full unified diff patch text for this file
@!attribute [r] status
@return [Symbol] the change status (:added, :modified, :deleted, :renamed, :copied, :type_changed)
@!attribute [r] similarity
@return [Integer, nil] similarity percentage for renames/copies (0-100), nil otherwise
@!attribute [r] binary
@return [Boolean] whether this is a binary file
@!attribute [r] insertions
@return [Integer] number of lines inserted
@!attribute [r] deletions
@return [Integer] number of lines deleted
@api private
Work in progress; this class is internal for now and may be made public in a future release.
- DiffFileRawInfo
-
Immutable value object representing status info for a single file from git raw diff output
Contains the source and destination file references, change status, similarity percentage (for renames/copies), and line change statistics.
@example A modified file
info = Git::DiffFileRawInfo.new( src: Git::FileRef.new(mode: '100644', sha: 'abc1234', path: 'lib/foo.rb'), dst: Git::FileRef.new(mode: '100644', sha: 'def5678', path: 'lib/foo.rb'), status: :modified, similarity: nil, insertions: 5, deletions: 2, binary: false )
@example A new file (src is nil)
info = Git::DiffFileRawInfo.new( src: nil, dst: Git::FileRef.new(mode: '100644', sha: 'abc1234', path: 'lib/new.rb'), status: :added, similarity: nil, insertions: 10, deletions: 0, binary: false )
@example A renamed file
info = Git::DiffFileRawInfo.new( src: Git::FileRef.new(mode: '100644', sha: 'abc1234', path: 'lib/old.rb'), dst: Git::FileRef.new(mode: '100644', sha: 'def5678', path: 'lib/new.rb'), status: :renamed, similarity: 95, insertions: 2, deletions: 1, binary: false )
@!attribute [r] src
@return [FileRef, nil] the source file reference, or nil for new/added files
@!attribute [r] dst
@return [FileRef, nil] the destination file reference, or nil for deleted files
@!attribute [r] status
@return [Symbol] the change status (:added, :modified, :deleted, :renamed, :copied, :type_changed)
@!attribute [r] similarity
@return [Integer, nil] similarity percentage for renames/copies (0-100), nil otherwise
@!attribute [r] insertions
@return [Integer] number of lines inserted
@!attribute [r] deletions
@return [Integer] number of lines deleted
@!attribute [r] binary
@return [Boolean] whether this is a binary file
@api private
Work in progress; this class is internal for now and may be made public in a future release.
- DiffInfo
-
Immutable value object representing diff statistics and optional file patches
DiffInfoencapsulates the parsed output from various git commands that produce diff statistics (like âgit stash show âstat`). When patches are requested, it also includes the full patch information for each file.The stats hash structure:
-
â:total` - Hash with `:insertions`, `:deletions`, `:lines`, `:files` keys
-
â:files` - Hash mapping file paths to `{ insertions:, deletions: }` hashes
@example Create a
DiffInfofrom parsed stats outputinfo = Git::DiffInfo.new( stats: { total: { insertions: 10, deletions: 5, lines: 15, files: 2 }, files: { 'lib/foo.rb' => { insertions: 8, deletions: 3 }, 'lib/bar.rb' => { insertions: 2, deletions: 2 } } }, file_patches: [] )
@example Access statistics
info.insertions # => 10 info.deletions # => 5 info.lines # => 15 info.file_count # => 2
@api private
Work in progress; this class is internal for now and may be made public in a future release.
@!attribute [r] stats
@return [Hash] the statistics hash with :total and :files keys
@!attribute [r] file_patches
@return [Array<FileDiffInfo>] array of file diff info objects (empty if patch not requested)
-
- DiffResult
-
Immutable result object from git diff commands
Contains summary statistics and per-file information from various diff formats. The âfiles` array contains one of:
-
DiffFileNumstatInfo(from ânumstat) -
DiffFileRawInfo(from âraw) -
DiffFilePatchInfo(from âpatch)
@api private
Work in progress; this class is internal for now and may be made public in a future release.
@!attribute [r] files_changed
@return [Integer] number of files changed (from --shortstat)
@!attribute [r] total_insertions
@return [Integer] total lines inserted across all files (from --shortstat)
@!attribute [r] total_deletions
@return [Integer] total lines deleted across all files (from --shortstat)
@!attribute [r] files
@return [Array<DiffFileNumstatInfo, DiffFileRawInfo, DiffFilePatchInfo>] per-file information
@!attribute [r] dirstat
@return [DirstatInfo, nil] directory statistics if requested, nil otherwise
-
- DirstatEntry
-
Immutable value object representing a single directoryâs contribution to a diff
@example Create a
DirstatEntryinfo = Git::DirstatEntry.new(directory: 'lib/commands/', percentage: 45.2) info.directory #=> "lib/commands/" info.percentage #=> 45.2
@api private
Work in progress; this class is internal for now and may be made public in a future release.
@!attribute [r] directory
@return [String] the directory path (always ends with '/')
@!attribute [r] percentage
@return [Float] the percentage of changes in this directory (0.0-100.0)
- DirstatInfo
-
Immutable result object from git âdirstat output
Contains the list of directories and their contribution percentages to the diff.
@example Create a
DirstatInfodirstat = Git::DirstatInfo.new( entries: [ Git::DirstatEntry.new(directory: 'lib/commands/', percentage: 45.2), Git::DirstatEntry.new(directory: 'spec/unit/', percentage: 30.1) ] ) dirstat.entries.first.directory #=> "lib/commands/" dirstat['lib/commands/'] #=> 45.2 dirstat.to_h #=> { "lib/commands/" => 45.2, "spec/unit/" => 30.1 }
@api private
Work in progress; this class is internal for now and may be made public in a future release.
@!attribute [r] entries
@return [Array<DirstatEntry>] directory statistics in order from git output
- FileDiffInfo
-
Immutable value object representing a single fileâs diff information
FileDiffInfoencapsulates the parsed data from a unified diff for one file, including the file path, patch text, mode changes, object identifiers, and type.This class is used by
DiffInfofor the legacy diff API.@example Create a
FileDiffInfofrom parsed diff outputdiff_info = Git::FileDiffInfo.new( path: 'lib/example.rb', patch: "diff --git a/lib/example.rb b/lib/example.rb\n...", mode: '100644', src: 'abc1234', dst: 'def5678', type: 'modified', binary: false )
@!attribute [r] path
@return [String] the file path relative to the repository root
@!attribute [r] patch
@return [String] the full unified diff patch text for this file
@!attribute [r] mode
@return [String] the file mode (e.g., '100644' for regular files)
@!attribute [r] src
@return [String] the source blob object identifier
@!attribute [r] dst
@return [String] the destination blob object identifier
@!attribute [r] type
@return [String] the type of change: 'modified', 'new', 'deleted', 'renamed'
@!attribute [r] binary
@return [Boolean] whether this is a binary file
@api private
Work in progress; this class is internal for now and may be made public in a future release.
- FileRef
-
Immutable value object representing a reference to a file at a specific point in time
FileRefencapsulates the mode, SHA, and path of a file as it exists on one side of a diff. This is used to represent either the source (before) or destination (after) state of a file in a diff operation.When a file doesnât exist on a side of the diff (e.g., src for new files, dst for deleted files), the entire
FileRefshould be nil rather than having aFileRefwith nil attributes.@example A modified fileâs source reference
src = Git::FileRef.new(mode: '100644', sha: 'abc1234', path: 'lib/foo.rb')
@example A new file (src would be nil, not a
FileRef)# src = nil dst = Git::FileRef.new(mode: '100644', sha: 'def5678', path: 'lib/new_file.rb')
@api private
Work in progress; this class is internal for now and may be made public in a future release.
@!attribute [r] mode
@return [String] the file mode (e.g., '100644' for regular file, '100755' for executable, '120000' for symlink)
@!attribute [r] sha
@return [String] the blob SHA (object identifier)
@!attribute [r] path
@return [String] the file path relative to repository root
- GitExecuteError
-
An alias for
Git::ErrorGit::GitExecuteErroris an alias forGit::Errorkept for backwards compatibility. It is an ActiveSupport::Deprecation::DeprecatedConstantProxy, so any use of it, including instantiating it and matching it in a ârescue` clause, emits a deprecation warning through Git::Deprecation. The reflective methods that debuggers and IRB call, such as `inspect` and `name`, do not warn. It will be removed in a future major release.@deprecated Use
Git::Errorinstead. Will be removed in a future major release. - REMOTE_NAME_NOT_GIVEN
-
Sentinel for distinguishing omitted
BranchInforemote_name from explicit nil - RemoteInfo
-
Value object representing a configured git remote
Each instance holds the parsed configuration for a single remote as read from the repositoryâs git config. Multi-value fields (â:url`, `:push_url`, `:fetch`, `:push`) are always `Array<String>` (never `nil`; may be empty). Those arrays are frozen copies of the values given, so the set of URLs and refspecs cannot change after construction; use `with` to derive a modified copy. The immutability is shallow, as with any `Data` member: the strings inside those arrays and the scalar members are the objects the caller passed in, not copies. All other fields are nilable except `:name`.
@example Minimal remote (fetch-only, one
URL)info = Git::RemoteInfo.new( name: 'origin', url: ['https://github.com/ruby-git/ruby-git.git'], push_url: [], fetch: ['+refs/heads/*:refs/remotes/origin/*'], push: [] ) info.name # => "origin" info.url # => ["https://github.com/ruby-git/ruby-git.git"] info.prune # => nil
@api public
@!attribute [r] name
@return [String] the name of the remote (e.g. `'origin'`)
@!attribute [r] url
@return [Array<String>] the fetch URL(s) for this remote (`remote.<name>.url`)
@!attribute [r] push_url
@return [Array<String>] the push URL(s) for this remote (`remote.<name>.pushurl`)
@!attribute [r] fetch
@return [Array<String>] the fetch refspec(s) for this remote (`remote.<name>.fetch`)
@!attribute [r] push
@return [Array<String>] the push refspec(s) for this remote (`remote.<name>.push`)
@!attribute [r] mirror
@return [Boolean, nil] `true`/`false` per `remote.<name>.mirror`, or `nil` when not set
@!attribute [r] skip_default_update
@return [Boolean, nil] `true`/`false` per `remote.<name>.skipDefaultUpdate`, or `nil` when not set
@!attribute [r] tag_opt
@return [String, nil] the tag-fetching option (`remote.<name>.tagOpt`), or `nil` when not set
@!attribute [r] prune
@return [Boolean, nil] `true`/`false` per `remote.<name>.prune`; `nil` inherits `fetch.prune`
@!attribute [r] prune_tags
@return [Boolean, nil] `true`/`false` per `remote.<name>.pruneTags`; `nil` inherits `fetch.pruneTags`
@!attribute [r] receivepack
@return [String, nil] the `git-receive-pack` path on the remote (`remote.<name>.receivepack`)
@!attribute [r] uploadpack
@return [String, nil] the `git-upload-pack` path on the remote (`remote.<name>.uploadpack`)
@!attribute [r] promisor
@return [Boolean, nil] `true`/`false` per `remote.<name>.promisor`, or `nil` when not set
@!attribute [r] partial_clone_filter
@return [String, nil] the partial-clone object filter (`remote.<name>.partialclonefilter`)
@!attribute [r] vcs
@return [String, nil] the VCS type for git-remote helpers (`remote.<name>.vcs`)
- StashInfo
-
Immutable value object representing stash entry information
StashInfoencapsulates the parsed data from âgit stash list` output. Each entry contains comprehensive information about the stash including its index, reference name, commit SHA, branch, message, and the author and committer identities.The author and committer are nested {Git::AuthorInfo} values. Their âdate` is a `Time` parsed from gitâs ISO 8601 output, not an ISO 8601 string.
@example Create a
StashInfofrom parsed stash list outputinfo = Git::StashInfo.new( index: 0, name: 'stash@{0}', oid: 'abc123def456789...', short_oid: 'abc123d', branch: 'main', message: 'WIP on main: abc123 Initial commit', author: Git::AuthorInfo.new( name: 'Jane Doe', email: 'jane@example.com', date: Time.iso8601('2026-01-24T10:30:00-08:00') ), committer: Git::AuthorInfo.new( name: 'Jane Doe', email: 'jane@example.com', date: Time.iso8601('2026-01-24T10:30:00-08:00') ) ) info.index # => 0 info.name # => 'stash@{0}' info.oid # => 'abc123def456789...' info.short_oid # => 'abc123d' info.branch # => 'main' info.message # => 'WIP on main: abc123 Initial commit' info.author.name # => 'Jane Doe' info.author.email # => 'jane@example.com' info.author.date # => 2026-01-24 10:30:00 -0800 info.committer.name # => 'Jane Doe'
@see
Git::AuthorInfofor the nested author and committer identities@api public
@!attribute [r] index
@return [Integer] the stash index (0, 1, 2, ...)
@!attribute [r] name
@return [String] the stash reference name (e.g., 'stash@\\{0\\}')@!attribute [r] oid
@return [String] the full 40-character object identifier of the stash
@!attribute [r] short_oid
@return [String] the abbreviated object identifier (typically 7 characters)
@!attribute [r] branch
@return [String, nil] the branch name where the stash was created, or nil for custom stash messages
@!attribute [r] message
@return [String] the stash message (e.g., 'WIP on main: abc123 commit msg')
@!attribute [r] author
The identity of the stash author; the nested `date` is a `Time`. @return [Git::AuthorInfo] the author of the stash commit
@!attribute [r] committer
The identity of the stash committer; the nested `date` is a `Time`. @return [Git::AuthorInfo] the committer of the stash commit
- StatusFileInfo
-
Immutable value object for the status of one path in the index and working tree
Each member holds one field of the entry âgit status âporcelain=v2` reports for the path. `index_status` and `worktree_status` are the `X` and `Y` characters of that entry: `.` unmodified, `M` modified, `T` type changed, `A` added, `D` deleted, `R` renamed, `C` copied, or `U` unmerged. Untracked entries carry `?` in both and ignored entries carry `!` in both, mirroring the `??` and `!!` codes of the short status format.
The mode and SHA members are ânil` for untracked and ignored entries. For unmerged entries the per-stage modes and SHAs live in `unmerged_stages` and `mode_head`, `mode_index`, `sha_head`, and `sha_index` are `nil`. `original_path` and `rename_score` are set only for rename and copy entries.
The predicates follow these rules: âadded?` when `index_status` is `A`, `deleted?` when either status is `D`, `changed?` when either status is `M` or `T`, `renamed?` when either status is `R`, `untracked?` and `ignored?` from the `?` and `!` codes, and `unmerged?` when `unmerged_stages` is set.
Every String member is a frozen copy of the value given, and âunmerged_stages` is a deeply frozen copy, so an entry cannot be changed through a member the caller still references.
@example Inspect the status of one path
file = repo.status_info['lib/foo.rb'] file.index_status #=> "M" file.worktree_status #=> "." file.changed? #=> true file.sha_index #=> "2bdf67abb163a4ffb2d7f3f0880c9fe5068ce782"
@example Read the original path of a rename
file = repo.status_info['lib/new_name.rb'] file.renamed? #=> true file.original_path #=> "lib/old_name.rb" file.rename_score #=> 100
@example Read the stages of a merge conflict
file = repo.status_info['lib/conflict.rb'] file.unmerged? #=> true file.unmerged_stages[2] #=> { mode: "100644", sha: "ba2906d0666c..." }
@see
Git::StatusInfo@see
Git::Repository#status_info@see git-scm.com/docs/git-status#_porcelain_format_version_2
@api public
@!attribute [r] path
@return [String] the repository-relative path
@!attribute [r] index_status
@return [String] the `X` status character (HEAD versus index), `?` for untracked and `!` for ignored entries
@!attribute [r] worktree_status
@return [String] the `Y` status character (index versus working tree), `?` for untracked and `!` for ignored entries
@!attribute [r] submodule
@return [String, nil] the four-character submodule state (`N...` for a regular file), or `nil` for untracked and ignored entries
@!attribute [r] mode_head
@return [String, nil] the octal file mode in HEAD (`000000` when the path is not in HEAD), or `nil` for untracked, ignored, and unmerged entries
@!attribute [r] mode_index
@return [String, nil] the octal file mode in the index (`000000` when the path is not in the index), or `nil` for untracked, ignored, and unmerged entries
@!attribute [r] mode_worktree
@return [String, nil] the octal file mode in the working tree (`000000` when the path is not in the working tree), or `nil` for untracked and ignored entries
@!attribute [r] sha_head
@return [String, nil] the object name of the blob in HEAD (all zeros when the path is not in HEAD), or `nil` for untracked, ignored, and unmerged entries
@!attribute [r] sha_index
@return [String, nil] the object name of the blob in the index (all zeros when the path is not in the index), or `nil` for untracked, ignored, and unmerged entries
@!attribute [r] original_path
@return [String, nil] the path the entry was renamed or copied from, or `nil` for every other entry
@!attribute [r] rename_score
@return [Integer, nil] the similarity score of a rename or copy entry, or `nil` for every other entry
@!attribute [r] unmerged_stages
@return [Hash{Integer => Hash{Symbol => String}}, nil] the mode and SHA of each conflict stage keyed by stage number (1 for the merge base, 2 for "ours", 3 for "theirs"), as frozen `\\{ mode:, sha: }` hashes, or `nil` for every other entry - StatusInfo
-
Immutable value object for the status of a repositoryâs index and working tree
Holds one {Git::StatusFileInfo} per path that âgit status` reports, in the order git listed them, together with the repositoryâs âcore.ignoreCase` setting. The derived readers (`changed`, `added`, `deleted`, `untracked`, `unmerged`) return the matching files keyed by path and are computed on each call. The path predicates (`changed?`, `added?`, `deleted?`, `untracked?`) compare paths case-insensitively when `ignore_case` is `true`.
@example Inspect repository status
status = repo.status_info status.changed.each_key { |path| puts "Modified: #{path}" } status.added.each_key { |path| puts "Added: #{path}" } status.deleted.each_key { |path| puts "Deleted: #{path}" } status.untracked.each_key { |path| puts "Untracked: #{path}" }
@example Check one path
status = repo.status_info status.changed?('lib/foo.rb') #=> true status['lib/foo.rb'].worktree_status #=> "M"
@see
Git::StatusFileInfo@see
Git::Repository#status_info@api public
@!attribute [r] files
@return [Array<Git::StatusFileInfo>] every reported path in git's output order; the array is frozen
@!attribute [r] ignore_case
@return [Boolean] `true` when the repository's `core.ignoreCase` is true, making the path predicates compare paths case-insensitively
- TagDeleteFailure
-
Represents a tag that failed to be deleted
This is an immutable data object returned as part of {Git::TagDeleteResult} when one or more tags could not be deleted.
@example
failure = Git::TagDeleteFailure.new( name: 'nonexistent', error_message: "tag 'nonexistent' not found." ) failure.name #=> 'nonexistent' failure.error_message #=> "tag 'nonexistent' not found."
@see
Git::TagDeleteResult@see
Git::Commands::Tag::Delete@api public
@!attribute [r] name
The name of the tag that failed to be deleted @return [String]
@!attribute [r] error_message
The error message from git explaining why the tag could not be deleted @return [String]
- TagDeleteResult
-
Represents the result of a tag delete operation
This is an immutable data object returned by {Git::Commands::Tag::Delete#call}. It contains information about which tags were successfully deleted and which failed to be deleted, along with the reason for each failure.
Gitâs âgit tag -d` command uses âbest effortâ semantics - it deletes as many tags as possible and reports errors for those that couldnât be deleted. This result object reflects that behavior, allowing callers to inspect both successes and failures.
@example Successful deletion of all tags
result = tag_delete.call('v1.0.0', 'v2.0.0') result.success? #=> true result.deleted.map(&:name) #=> ['v1.0.0', 'v2.0.0'] result.not_deleted #=> []
@example Partial failure (some tags deleted, some not found)
result = tag_delete.call('v1.0.0', 'nonexistent', 'v2.0.0') result.success? #=> false result.deleted.map(&:name) #=> ['v1.0.0', 'v2.0.0'] result.not_deleted.first.name #=> 'nonexistent' result.not_deleted.first.error_message #=> "tag 'nonexistent' not found."
@see
Git::TagInfo@see
Git::Commands::Tag::Delete@api public
@!attribute [r] deleted
Tags that were successfully deleted @return [Array<Git::TagInfo>]
@!attribute [r] not_deleted
Tags that could not be deleted, with the reason for each failure @return [Array<Git::TagDeleteFailure>]
- TagInfo
-
Value object representing tag metadata from git tag output
This is a lightweight, immutable data structure returned by tag listing commands. It contains only the data parsed from git output without any repository context or operations.
The tagger identity is a nested {Git::AuthorInfo}. Its âdate` is a `Time` parsed from gitâs strict ISO 8601 output, not an ISO 8601 string.
@example Annotated tag
info = Git::TagInfo.new( name: 'v1.0.0', oid: 'abc123def456', # tag object's ID target_oid: 'def456abc789', # commit it points to objecttype: 'tag', tagger: Git::AuthorInfo.new( name: 'John Doe', email: 'john@example.com', date: Time.iso8601('2024-01-15T10:30:00-08:00') ), message: 'Release version 1.0.0' ) info.annotated? #=> true info.tagger.name #=> 'John Doe' info.tagger.date #=> 2024-01-15 10:30:00 -0800
@example Lightweight tag
info = Git::TagInfo.new( name: 'v1.0.0', oid: nil, # no tag object exists target_oid: 'def456abc789', # commit ID objecttype: 'commit', tagger: nil, message: nil ) info.lightweight? #=> true info.tagger #=> nil
@see
Git::Repository::ObjectOperations#tag_listfor the repository methodthat returns these
@see
Git::Commands::Tag::Listfor the command that produces these@see
Git::AuthorInfofor the nested tagger identity@api public
@!attribute [r] name
@return [String] the tag name (e.g., 'v1.0.0')
@!attribute [r] oid
The object ID of the tag object itself. For annotated tags, this is the tag object's ID. For lightweight tags, this is nil because lightweight tags are not objects in the git database. @return [String, nil] the tag object's ID, or nil for lightweight tags
@!attribute [r] target_oid
The object ID of the commit this tag ultimately points to. For both annotated and lightweight tags, this is the commit ID that the tag resolves to (i.e., the dereferenced target). @return [String] the commit ID this tag points to
@!attribute [r] objecttype
@return [String] 'tag' for annotated tags, 'commit' for lightweight tags
@!attribute [r] tagger
The identity of the person who created the tag object. Lightweight tags have no tag object and therefore no tagger. The nested `email` has no angle brackets and the nested `date` is a `Time`. @return [Git::AuthorInfo, nil] the tagger, or nil for lightweight tags
@!attribute [r] message
@return [String, nil] the tag message, or nil for lightweight tags
- VERSION
-
The current gem version
@return [String] the current gem version
- Version
-
Represents a git version with major, minor, and patch components
Gitversions follow a strict major.minor.patch format. This class provides parsing from git command output (which may include platform suffixes) and comparison operations for version gating.@!attribute [r] major
The major version number @return [Integer]
@!attribute [r] minor
The minor version number @return [Integer]
@!attribute [r] patch
The patch version number @return [Integer]
@example Creating a version directly
version = Git::Version.new(2, 42, 1) version.to_s #=> "2.42.1"
@example Parsing from git version output
Git::Version.parse('git version 2.42.1') #=> Git::Version.new(2, 42, 1) Git::Version.parse('2.39.2 (Apple Git-143)') #=> Git::Version.new(2, 39, 2)
@example Parsing versions with platform suffixes
Git::Version.parse('2.42.0.windows.1') #=> Git::Version.new(2, 42, 0)
@example Comparing versions
Git::Version.new(2, 42, 1) > Git::Version.new(2, 28, 0) #=> true
@api public
- VersionConstraint
-
Represents a git version constraint with minimum and upper bound versions
Used by {Git::Commands::Base.requires_git_version} to declare version requirements and by {Git::VersionError} to report constraint violations.
@example Minimum version only
constraint = Git::VersionConstraint.new(min: Git::Version.parse('2.30.0')) constraint.too_old?(Git::Version.parse('2.28.0')) #=> true constraint.too_new?(Git::Version.parse('2.28.0')) #=> false
@example Upper bound only
constraint = Git::VersionConstraint.new(before: Git::Version.parse('2.50.0')) constraint.too_old?(Git::Version.parse('2.51.0')) #=> false constraint.too_new?(Git::Version.parse('2.51.0')) #=> true
@example Both bounds
constraint = Git::VersionConstraint.new( min: Git::Version.parse('2.30.0'), before: Git::Version.parse('2.50.0') ) constraint.satisfied_by?(Git::Version.parse('2.40.0')) #=> true
@api public
- WorktreeInfo
-
Immutable value object for one entry of âgit worktree list`
Each entry carries what âgit worktree list âporcelain` reports for a worktree: its path, the checked-out HEAD and branch, and whether it is bare, detached, locked, or prunable, with the reason git gives for the last two.
@example A locked linked worktree with a branch checked out
info = Git::WorktreeInfo.new( path: '/tmp/wt/linked', head: 'f3e2c1ffb860086504eeb27b77a1d0028b68fd8f', branch: 'refs/heads/linked', bare: false, detached: false, locked: true, lock_reason: 'on purpose', prunable: false, prune_reason: nil ) info.path # => '/tmp/wt/linked' info.head # => 'f3e2c1ffb860086504eeb27b77a1d0028b68fd8f' info.branch # => 'refs/heads/linked' info.locked? # => true info.lock_reason # => 'on purpose' info.detached? # => false info.to_s # => '/tmp/wt/linked'
@example Pass an entry back to a worktree operation
info = repo.worktree_list.find { |w| w.branch == 'refs/heads/linked' } repo.worktree_remove(info)
@see
Git::Repository::WorktreeOperations#worktree_listfor the repositorymethod that returns these
@api public
@!attribute [r] path
@return [String] the worktree directory as git reports it
@!attribute [r] head
@return [String, nil] the full object ID of the checked-out HEAD commit (the all-zero object ID when the branch has no commits yet), or nil for a bare main worktree
@!attribute [r] branch
@return [String, nil] the full refname of the checked-out branch (e.g., 'refs/heads/main'), or nil when the worktree is bare or detached
@!attribute [r] bare
@return [Boolean] true if this is the main worktree of a bare repository
@!attribute [r] detached
@return [Boolean] true if HEAD is detached in this worktree
@!attribute [r] locked
@return [Boolean] true if the worktree is locked
@!attribute [r] lock_reason
@return [String, nil] the reason given when the worktree was locked, or nil when it is not locked or was locked without a reason
@!attribute [r] prunable
@return [Boolean] true if `git worktree prune` would remove this entry
@!attribute [r] prune_reason
@return [String, nil] git's explanation of why the entry is prunable, or nil when it is not prunable