git 4.4.1 → 5.0.0.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/copilot-instructions.md +67 -2705
- data/.github/pull_request_template.md +3 -1
- data/.github/skills/breaking-change-analysis/SKILL.md +102 -0
- data/.github/skills/ci-cd-troubleshooting/SKILL.md +264 -0
- data/.github/skills/command-implementation/REFERENCE.md +993 -0
- data/.github/skills/command-implementation/SKILL.md +229 -0
- data/.github/skills/command-test-conventions/SKILL.md +660 -0
- data/.github/skills/command-yard-documentation/SKILL.md +426 -0
- data/.github/skills/dependency-management/SKILL.md +72 -0
- data/.github/skills/development-workflow/SKILL.md +506 -0
- data/.github/skills/extract-command-from-lib/SKILL.md +487 -0
- data/.github/skills/extract-facade-from-base-lib/SKILL.md +586 -0
- data/.github/skills/facade-implementation/REFERENCE.md +840 -0
- data/.github/skills/facade-implementation/SKILL.md +260 -0
- data/.github/skills/facade-test-conventions/SKILL.md +380 -0
- data/.github/skills/facade-yard-documentation/SKILL.md +429 -0
- data/.github/skills/make-skill-template/SKILL.md +176 -0
- data/.github/skills/pr-readiness-review/SKILL.md +185 -0
- data/.github/skills/project-context/SKILL.md +313 -0
- data/.github/skills/pull-request-review/SKILL.md +168 -0
- data/.github/skills/refactor-command-to-commandlineresult/SKILL.md +131 -0
- data/.github/skills/release-management/SKILL.md +125 -0
- data/.github/skills/review-arguments-dsl/CHECKLIST.md +788 -0
- data/.github/skills/review-arguments-dsl/SKILL.md +214 -0
- data/.github/skills/review-backward-compatibility/SKILL.md +275 -0
- data/.github/skills/review-cross-command-consistency/SKILL.md +139 -0
- data/.github/skills/reviewing-skills/SKILL.md +189 -0
- data/.github/skills/rspec-unit-testing-standards/SKILL.md +639 -0
- data/.github/skills/tdd-refactor-step/SKILL.md +236 -0
- data/.github/skills/test-debugging/SKILL.md +160 -0
- data/.github/skills/yard-documentation/SKILL.md +793 -0
- data/.github/workflows/continuous_integration.yml +3 -67
- data/.github/workflows/enforce_conventional_commits.yml +1 -1
- data/.github/workflows/experimental_continuous_integration.yml +2 -2
- data/.github/workflows/release.yml +3 -4
- data/.gitignore +8 -0
- data/.husky/pre-commit +13 -0
- data/.release-please-manifest.json +1 -1
- data/.rspec +3 -0
- data/.rubocop.yml +7 -3
- data/.rubocop_todo.yml +23 -5
- data/.yardopts +1 -0
- data/CHANGELOG.md +0 -66
- data/CONTRIBUTING.md +694 -53
- data/README.md +17 -17
- data/Rakefile +61 -9
- data/commitlint.test +4 -0
- data/git.gemspec +14 -8
- data/lib/git/args_builder.rb +0 -8
- data/lib/git/base.rb +488 -412
- data/lib/git/branch.rb +117 -59
- data/lib/git/branch_delete_failure.rb +31 -0
- data/lib/git/branch_delete_result.rb +63 -0
- data/lib/git/branch_info.rb +178 -0
- data/lib/git/branches.rb +130 -24
- data/lib/git/command_line/base.rb +245 -0
- data/lib/git/command_line/capturing.rb +249 -0
- data/lib/git/command_line/result.rb +96 -0
- data/lib/git/command_line/streaming.rb +194 -0
- data/lib/git/command_line.rb +43 -322
- data/lib/git/command_line_result.rb +4 -88
- data/lib/git/commands/add.rb +131 -0
- data/lib/git/commands/am/abort.rb +43 -0
- data/lib/git/commands/am/apply.rb +252 -0
- data/lib/git/commands/am/continue.rb +43 -0
- data/lib/git/commands/am/quit.rb +43 -0
- data/lib/git/commands/am/retry.rb +47 -0
- data/lib/git/commands/am/show_current_patch.rb +64 -0
- data/lib/git/commands/am/skip.rb +42 -0
- data/lib/git/commands/am.rb +33 -0
- data/lib/git/commands/apply.rb +237 -0
- data/lib/git/commands/archive/list_formats.rb +46 -0
- data/lib/git/commands/archive.rb +140 -0
- data/lib/git/commands/arguments.rb +3510 -0
- data/lib/git/commands/base.rb +403 -0
- data/lib/git/commands/branch/copy.rb +94 -0
- data/lib/git/commands/branch/create.rb +173 -0
- data/lib/git/commands/branch/delete.rb +80 -0
- data/lib/git/commands/branch/list.rb +162 -0
- data/lib/git/commands/branch/move.rb +94 -0
- data/lib/git/commands/branch/set_upstream.rb +86 -0
- data/lib/git/commands/branch/show_current.rb +49 -0
- data/lib/git/commands/branch/unset_upstream.rb +57 -0
- data/lib/git/commands/branch.rb +34 -0
- data/lib/git/commands/cat_file/batch.rb +364 -0
- data/lib/git/commands/cat_file/filtered.rb +105 -0
- data/lib/git/commands/cat_file/raw.rb +210 -0
- data/lib/git/commands/cat_file.rb +49 -0
- data/lib/git/commands/checkout/branch.rb +151 -0
- data/lib/git/commands/checkout/files.rb +115 -0
- data/lib/git/commands/checkout.rb +38 -0
- data/lib/git/commands/checkout_index.rb +105 -0
- data/lib/git/commands/clean.rb +100 -0
- data/lib/git/commands/clone.rb +240 -0
- data/lib/git/commands/commit.rb +272 -0
- data/lib/git/commands/commit_tree.rb +100 -0
- data/lib/git/commands/config_option_syntax/add.rb +83 -0
- data/lib/git/commands/config_option_syntax/get.rb +117 -0
- data/lib/git/commands/config_option_syntax/get_all.rb +115 -0
- data/lib/git/commands/config_option_syntax/get_color.rb +91 -0
- data/lib/git/commands/config_option_syntax/get_color_bool.rb +93 -0
- data/lib/git/commands/config_option_syntax/get_regexp.rb +115 -0
- data/lib/git/commands/config_option_syntax/get_urlmatch.rb +102 -0
- data/lib/git/commands/config_option_syntax/list.rb +107 -0
- data/lib/git/commands/config_option_syntax/remove_section.rb +74 -0
- data/lib/git/commands/config_option_syntax/rename_section.rb +78 -0
- data/lib/git/commands/config_option_syntax/replace_all.rb +104 -0
- data/lib/git/commands/config_option_syntax/set.rb +114 -0
- data/lib/git/commands/config_option_syntax/unset.rb +89 -0
- data/lib/git/commands/config_option_syntax/unset_all.rb +89 -0
- data/lib/git/commands/config_option_syntax.rb +56 -0
- data/lib/git/commands/describe.rb +155 -0
- data/lib/git/commands/diff.rb +656 -0
- data/lib/git/commands/diff_files.rb +518 -0
- data/lib/git/commands/diff_index.rb +496 -0
- data/lib/git/commands/fetch.rb +352 -0
- data/lib/git/commands/fsck.rb +136 -0
- data/lib/git/commands/gc.rb +132 -0
- data/lib/git/commands/grep.rb +338 -0
- data/lib/git/commands/init.rb +99 -0
- data/lib/git/commands/log.rb +632 -0
- data/lib/git/commands/ls_files.rb +191 -0
- data/lib/git/commands/ls_remote.rb +155 -0
- data/lib/git/commands/ls_tree.rb +131 -0
- data/lib/git/commands/maintenance/register.rb +75 -0
- data/lib/git/commands/maintenance/run.rb +104 -0
- data/lib/git/commands/maintenance/start.rb +66 -0
- data/lib/git/commands/maintenance/stop.rb +55 -0
- data/lib/git/commands/maintenance/unregister.rb +79 -0
- data/lib/git/commands/maintenance.rb +31 -0
- data/lib/git/commands/merge/abort.rb +44 -0
- data/lib/git/commands/merge/continue.rb +44 -0
- data/lib/git/commands/merge/quit.rb +46 -0
- data/lib/git/commands/merge/start.rb +245 -0
- data/lib/git/commands/merge.rb +28 -0
- data/lib/git/commands/merge_base.rb +86 -0
- data/lib/git/commands/mv.rb +77 -0
- data/lib/git/commands/name_rev.rb +114 -0
- data/lib/git/commands/pull.rb +377 -0
- data/lib/git/commands/push.rb +246 -0
- data/lib/git/commands/read_tree.rb +149 -0
- data/lib/git/commands/remote/add.rb +91 -0
- data/lib/git/commands/remote/get_url.rb +66 -0
- data/lib/git/commands/remote/list.rb +54 -0
- data/lib/git/commands/remote/prune.rb +61 -0
- data/lib/git/commands/remote/remove.rb +52 -0
- data/lib/git/commands/remote/rename.rb +69 -0
- data/lib/git/commands/remote/set_branches.rb +63 -0
- data/lib/git/commands/remote/set_head.rb +82 -0
- data/lib/git/commands/remote/set_url.rb +71 -0
- data/lib/git/commands/remote/set_url_add.rb +61 -0
- data/lib/git/commands/remote/set_url_delete.rb +64 -0
- data/lib/git/commands/remote/show.rb +71 -0
- data/lib/git/commands/remote/update.rb +72 -0
- data/lib/git/commands/remote.rb +42 -0
- data/lib/git/commands/repack.rb +277 -0
- data/lib/git/commands/reset.rb +147 -0
- data/lib/git/commands/rev_parse.rb +297 -0
- data/lib/git/commands/revert/abort.rb +45 -0
- data/lib/git/commands/revert/continue.rb +57 -0
- data/lib/git/commands/revert/quit.rb +47 -0
- data/lib/git/commands/revert/skip.rb +44 -0
- data/lib/git/commands/revert/start.rb +153 -0
- data/lib/git/commands/revert.rb +29 -0
- data/lib/git/commands/rm.rb +114 -0
- data/lib/git/commands/show.rb +632 -0
- data/lib/git/commands/show_ref/exclude_existing.rb +120 -0
- data/lib/git/commands/show_ref/exists.rb +78 -0
- data/lib/git/commands/show_ref/list.rb +145 -0
- data/lib/git/commands/show_ref/verify.rb +120 -0
- data/lib/git/commands/show_ref.rb +42 -0
- data/lib/git/commands/stash/apply.rb +75 -0
- data/lib/git/commands/stash/branch.rb +65 -0
- data/lib/git/commands/stash/clear.rb +41 -0
- data/lib/git/commands/stash/create.rb +58 -0
- data/lib/git/commands/stash/drop.rb +67 -0
- data/lib/git/commands/stash/list.rb +39 -0
- data/lib/git/commands/stash/pop.rb +78 -0
- data/lib/git/commands/stash/push.rb +103 -0
- data/lib/git/commands/stash/show.rb +149 -0
- data/lib/git/commands/stash/store.rb +63 -0
- data/lib/git/commands/stash.rb +38 -0
- data/lib/git/commands/status.rb +169 -0
- data/lib/git/commands/symbolic_ref/delete.rb +68 -0
- data/lib/git/commands/symbolic_ref/read.rb +95 -0
- data/lib/git/commands/symbolic_ref/update.rb +76 -0
- data/lib/git/commands/symbolic_ref.rb +38 -0
- data/lib/git/commands/tag/create.rb +139 -0
- data/lib/git/commands/tag/delete.rb +55 -0
- data/lib/git/commands/tag/list.rb +143 -0
- data/lib/git/commands/tag/verify.rb +71 -0
- data/lib/git/commands/tag.rb +26 -0
- data/lib/git/commands/update_ref/batch.rb +140 -0
- data/lib/git/commands/update_ref/delete.rb +92 -0
- data/lib/git/commands/update_ref/update.rb +106 -0
- data/lib/git/commands/update_ref.rb +42 -0
- data/lib/git/commands/version.rb +52 -0
- data/lib/git/commands/worktree/add.rb +140 -0
- data/lib/git/commands/worktree/list.rb +64 -0
- data/lib/git/commands/worktree/lock.rb +58 -0
- data/lib/git/commands/worktree/management_base.rb +51 -0
- data/lib/git/commands/worktree/move.rb +66 -0
- data/lib/git/commands/worktree/prune.rb +67 -0
- data/lib/git/commands/worktree/remove.rb +63 -0
- data/lib/git/commands/worktree/repair.rb +76 -0
- data/lib/git/commands/worktree/unlock.rb +47 -0
- data/lib/git/commands/worktree.rb +43 -0
- data/lib/git/commands/write_tree.rb +68 -0
- data/lib/git/commands.rb +89 -0
- data/lib/git/detached_head_info.rb +54 -0
- data/lib/git/diff.rb +297 -7
- data/lib/git/diff_file_numstat_info.rb +29 -0
- data/lib/git/diff_file_patch_info.rb +134 -0
- data/lib/git/diff_file_raw_info.rb +127 -0
- data/lib/git/diff_info.rb +169 -0
- data/lib/git/diff_path_status.rb +78 -19
- data/lib/git/diff_result.rb +32 -0
- data/lib/git/diff_stats.rb +59 -14
- data/lib/git/dirstat_info.rb +86 -0
- data/lib/git/errors.rb +65 -2
- data/lib/git/execution_context/global.rb +56 -0
- data/lib/git/execution_context/repository.rb +147 -0
- data/lib/git/execution_context.rb +482 -0
- data/lib/git/file_ref.rb +74 -0
- data/lib/git/fsck_object.rb +9 -9
- data/lib/git/fsck_result.rb +1 -1
- data/lib/git/lib.rb +1606 -1085
- data/lib/git/log.rb +15 -2
- data/lib/git/object.rb +92 -22
- data/lib/git/parsers/branch.rb +224 -0
- data/lib/git/parsers/cat_file.rb +111 -0
- data/lib/git/parsers/diff.rb +585 -0
- data/lib/git/parsers/fsck.rb +133 -0
- data/lib/git/parsers/grep.rb +42 -0
- data/lib/git/parsers/ls_tree.rb +58 -0
- data/lib/git/parsers/stash.rb +208 -0
- data/lib/git/parsers/tag.rb +257 -0
- data/lib/git/remote.rb +133 -9
- data/lib/git/repository/branching.rb +572 -0
- data/lib/git/repository/committing.rb +191 -0
- data/lib/git/repository/configuring.rb +156 -0
- data/lib/git/repository/diffing.rb +775 -0
- data/lib/git/repository/inspecting.rb +153 -0
- data/lib/git/repository/logging.rb +247 -0
- data/lib/git/repository/merging.rb +295 -0
- data/lib/git/repository/object_operations.rb +1101 -0
- data/lib/git/repository/path_resolver.rb +207 -0
- data/lib/git/repository/remote_operations.rb +753 -0
- data/lib/git/repository/shared_private.rb +51 -0
- data/lib/git/repository/staging.rb +390 -0
- data/lib/git/repository/stashing.rb +107 -0
- data/lib/git/repository/status_operations.rb +180 -0
- data/lib/git/repository/worktree_operations.rb +159 -0
- data/lib/git/repository.rb +264 -1
- data/lib/git/stash.rb +85 -4
- data/lib/git/stash_info.rb +104 -0
- data/lib/git/stashes.rb +130 -13
- data/lib/git/status.rb +226 -18
- data/lib/git/tag_delete_failure.rb +31 -0
- data/lib/git/tag_delete_result.rb +63 -0
- data/lib/git/tag_info.rb +105 -0
- data/lib/git/version.rb +109 -2
- data/lib/git/version_constraint.rb +81 -0
- data/lib/git/worktree.rb +120 -5
- data/lib/git/worktrees.rb +107 -7
- data/lib/git.rb +117 -56
- data/redesign/1_architecture_existing.md +54 -18
- data/redesign/2_architecture_redesign.md +365 -46
- data/redesign/3_architecture_implementation.md +1451 -54
- data/tasks/gem_tasks.rake +4 -0
- data/tasks/npm_tasks.rake +7 -0
- data/tasks/rspec.rake +48 -0
- data/tasks/test.rake +13 -1
- data/tasks/yard.rake +34 -7
- metadata +349 -20
- data/lib/git/index.rb +0 -6
- data/lib/git/path.rb +0 -38
- data/lib/git/working_directory.rb +0 -6
- /data/{release-please-config.json → .release-please-config.json} +0 -0
data/lib/git/branch.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'git/
|
|
3
|
+
require 'git/base'
|
|
4
|
+
require_relative 'branch_info'
|
|
4
5
|
|
|
5
6
|
module Git
|
|
6
7
|
# Represents a Git branch
|
|
@@ -28,7 +29,7 @@ module Git
|
|
|
28
29
|
# by {Git::Remote#branch} use the `<remote>/<branch>` form (e.g.
|
|
29
30
|
# `'origin/main'`) which does **not** populate {#remote}.
|
|
30
31
|
#
|
|
31
|
-
# @example
|
|
32
|
+
# @example Local and remote-tracking branch full refnames
|
|
32
33
|
# git.branch('main').full #=> 'main'
|
|
33
34
|
# git.branch('remotes/origin/main').full #=> 'remotes/origin/main'
|
|
34
35
|
#
|
|
@@ -43,7 +44,7 @@ module Git
|
|
|
43
44
|
# branches and for remote-tracking branches in `<remote>/<branch>` form
|
|
44
45
|
# (such as those returned by {Git::Remote#branch}).
|
|
45
46
|
#
|
|
46
|
-
# @example
|
|
47
|
+
# @example Local and remote-tracking branches
|
|
47
48
|
# git.branch('main').remote #=> nil
|
|
48
49
|
# git.branch('remotes/origin/main').remote #=> #<Git::Remote 'origin'>
|
|
49
50
|
# git.remote('origin').branch('main').remote #=> nil # uses 'origin/main' form
|
|
@@ -54,37 +55,39 @@ module Git
|
|
|
54
55
|
|
|
55
56
|
# The short branch name without the remote prefix
|
|
56
57
|
#
|
|
57
|
-
# For
|
|
58
|
-
#
|
|
59
|
-
# rather than `'remotes/origin/main'`). For branches in the
|
|
60
|
-
# `<remote>/<branch>` form (such as those created by {Git::Remote#branch}),
|
|
61
|
-
# no stripping occurs and `name` returns the full form (e.g. `'origin/main'`).
|
|
58
|
+
# For both local and remote-tracking branches this is the bare branch
|
|
59
|
+
# name (e.g. `'main'` rather than `'remotes/origin/main'`).
|
|
62
60
|
#
|
|
63
|
-
# @example
|
|
64
|
-
# git.branch('main').name
|
|
65
|
-
# git.branch('remotes/origin/main').name
|
|
66
|
-
# git.remote('origin').branch('main').name #=> 'origin/main'
|
|
61
|
+
# @example Local and remote-tracking branch short names
|
|
62
|
+
# git.branch('main').name #=> 'main'
|
|
63
|
+
# git.branch('remotes/origin/main').name #=> 'main'
|
|
67
64
|
#
|
|
68
|
-
# @return [String] the branch name
|
|
65
|
+
# @return [String] the short branch name
|
|
69
66
|
#
|
|
70
67
|
attr_accessor :name
|
|
71
68
|
|
|
72
69
|
# Initialize a new Branch object
|
|
73
70
|
#
|
|
74
|
-
# @
|
|
71
|
+
# @param base [Git::Base, Git::Repository] the git repository
|
|
75
72
|
#
|
|
76
|
-
#
|
|
73
|
+
# Accepts either a {Git::Base} (legacy) or a {Git::Repository} (new form).
|
|
74
|
+
# The `is_a?(Git::Base)` guard will be removed when {Git::Base} is deleted
|
|
75
|
+
# in Phase 4.
|
|
77
76
|
#
|
|
78
|
-
# @param
|
|
77
|
+
# @param branch_info_or_name [Git::BranchInfo, String] branch info object or name string
|
|
79
78
|
#
|
|
80
|
-
#
|
|
79
|
+
# Passing a BranchInfo is preferred; String support is for backward compatibility.
|
|
81
80
|
#
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
# @note Use {Git::Base#branch} or {Git::Base#branches} instead of constructing directly
|
|
82
|
+
#
|
|
83
|
+
# @api private
|
|
84
|
+
#
|
|
85
|
+
def initialize(base, branch_info_or_name)
|
|
84
86
|
@base = base
|
|
85
87
|
@gcommit = nil
|
|
86
88
|
@stashes = nil
|
|
87
|
-
|
|
89
|
+
|
|
90
|
+
initialize_from_argument(branch_info_or_name)
|
|
88
91
|
end
|
|
89
92
|
|
|
90
93
|
# Returns the commit at the tip of this branch
|
|
@@ -97,7 +100,7 @@ module Git
|
|
|
97
100
|
# @return [Git::Object] the commit at the tip of this branch
|
|
98
101
|
#
|
|
99
102
|
def gcommit
|
|
100
|
-
@gcommit ||=
|
|
103
|
+
@gcommit ||= branch_repository.gcommit(@full)
|
|
101
104
|
@gcommit
|
|
102
105
|
end
|
|
103
106
|
|
|
@@ -111,7 +114,7 @@ module Git
|
|
|
111
114
|
# @return [Git::Stashes] the stash list
|
|
112
115
|
#
|
|
113
116
|
def stashes
|
|
114
|
-
@stashes ||= Git::Stashes.new(
|
|
117
|
+
@stashes ||= Git::Stashes.new(branch_repository)
|
|
115
118
|
end
|
|
116
119
|
|
|
117
120
|
# Checks out this branch, attempting to create it first if it does not already exist
|
|
@@ -120,8 +123,10 @@ module Git
|
|
|
120
123
|
# step is silently ignored and the checkout proceeds regardless.
|
|
121
124
|
#
|
|
122
125
|
# **Note:** for remote-tracking branches (where {#remote} is not `nil`),
|
|
123
|
-
#
|
|
124
|
-
#
|
|
126
|
+
# `check_if_create` will attempt to create a *local* branch named {#name}
|
|
127
|
+
# as a side-effect before checking out {#full} (which typically results in
|
|
128
|
+
# a detached HEAD). This is a known limitation; see
|
|
129
|
+
# [ruby-git#1280](https://github.com/ruby-git/ruby-git/issues/1280).
|
|
125
130
|
#
|
|
126
131
|
# @example Check out a branch
|
|
127
132
|
# git = Git.open('.')
|
|
@@ -133,7 +138,7 @@ module Git
|
|
|
133
138
|
#
|
|
134
139
|
def checkout
|
|
135
140
|
check_if_create
|
|
136
|
-
|
|
141
|
+
branch_repository.checkout(@full)
|
|
137
142
|
end
|
|
138
143
|
|
|
139
144
|
# Archives this branch and writes the result to a file
|
|
@@ -153,7 +158,7 @@ module Git
|
|
|
153
158
|
# @raise [Git::FailedError] if `git archive` fails
|
|
154
159
|
#
|
|
155
160
|
def archive(file, opts = {})
|
|
156
|
-
|
|
161
|
+
branch_repository.archive(@full, file, opts)
|
|
157
162
|
end
|
|
158
163
|
|
|
159
164
|
# Checks out this branch for the duration of a block, then restores the original branch
|
|
@@ -184,14 +189,14 @@ module Git
|
|
|
184
189
|
# @raise [Git::FailedError] if any of the underlying git operations (checkout, commit, reset) fail
|
|
185
190
|
#
|
|
186
191
|
def in_branch(message = 'in branch work')
|
|
187
|
-
old_current =
|
|
192
|
+
old_current = branch_repository.current_branch
|
|
188
193
|
checkout
|
|
189
194
|
if yield
|
|
190
|
-
|
|
195
|
+
branch_repository.commit_all(message)
|
|
191
196
|
else
|
|
192
|
-
|
|
197
|
+
branch_repository.reset(nil, hard: true)
|
|
193
198
|
end
|
|
194
|
-
|
|
199
|
+
branch_repository.checkout(old_current)
|
|
195
200
|
end
|
|
196
201
|
|
|
197
202
|
# Creates this branch if it does not already exist
|
|
@@ -202,8 +207,7 @@ module Git
|
|
|
202
207
|
# @example Create a new branch
|
|
203
208
|
# git.branch('feature').create
|
|
204
209
|
#
|
|
205
|
-
# @return [
|
|
206
|
-
# or `nil` if an error was rescued
|
|
210
|
+
# @return [nil]
|
|
207
211
|
#
|
|
208
212
|
def create
|
|
209
213
|
check_if_create
|
|
@@ -211,22 +215,22 @@ module Git
|
|
|
211
215
|
|
|
212
216
|
# Deletes this branch
|
|
213
217
|
#
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
# delete a *local* branch with the same short name rather than the
|
|
217
|
-
# remote-tracking ref, which is almost certainly not what you want.
|
|
218
|
-
# See [ruby-git#1280](https://github.com/ruby-git/ruby-git/issues/1280) for
|
|
219
|
-
# the planned fix.
|
|
218
|
+
# Remote-tracking branches (one where {#remote} is not `nil`) delete the
|
|
219
|
+
# local remote-tracking ref; they do not push a deletion to the remote.
|
|
220
220
|
#
|
|
221
221
|
# @example Delete a local branch
|
|
222
222
|
# git.branch('old-feature').delete
|
|
223
223
|
#
|
|
224
224
|
# @return [String] git's deletion output
|
|
225
225
|
#
|
|
226
|
-
# @raise [Git::
|
|
226
|
+
# @raise [Git::Error] if the branch cannot be deleted
|
|
227
227
|
#
|
|
228
228
|
def delete
|
|
229
|
-
@
|
|
229
|
+
if @remote
|
|
230
|
+
branch_repository.branch_delete("#{@remote.name}/#{@name}", remotes: true)
|
|
231
|
+
else
|
|
232
|
+
branch_repository.branch_delete(@name)
|
|
233
|
+
end
|
|
230
234
|
end
|
|
231
235
|
|
|
232
236
|
# Returns true if this is the currently checked-out branch
|
|
@@ -241,11 +245,11 @@ module Git
|
|
|
241
245
|
# git.branch('main').current #=> true
|
|
242
246
|
#
|
|
243
247
|
# @return [Boolean] whether this branch is currently checked out
|
|
244
|
-
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
245
248
|
#
|
|
249
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
246
250
|
#
|
|
247
251
|
def current # rubocop:disable Naming/PredicateMethod
|
|
248
|
-
|
|
252
|
+
branch_repository.current_branch == @name
|
|
249
253
|
end
|
|
250
254
|
|
|
251
255
|
# Returns true if this branch contains the given commit
|
|
@@ -261,11 +265,11 @@ module Git
|
|
|
261
265
|
# @param commit [String] the commit SHA or ref to check
|
|
262
266
|
#
|
|
263
267
|
# @return [Boolean] whether this branch contains the given commit
|
|
264
|
-
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
265
268
|
#
|
|
269
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
266
270
|
#
|
|
267
271
|
def contains?(commit)
|
|
268
|
-
|
|
272
|
+
!branch_repository.branch_contains(commit, name).empty?
|
|
269
273
|
end
|
|
270
274
|
|
|
271
275
|
# Merges a branch into this branch, or merges this branch into the current branch
|
|
@@ -297,26 +301,25 @@ module Git
|
|
|
297
301
|
#
|
|
298
302
|
# @return [String] git's stdout from the merge command
|
|
299
303
|
#
|
|
300
|
-
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
301
|
-
# the merge, checkout, commit, or reset operations
|
|
304
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
302
305
|
#
|
|
303
306
|
def merge(branch = nil, message = nil)
|
|
304
307
|
if branch
|
|
305
308
|
in_branch do
|
|
306
|
-
|
|
309
|
+
branch_repository.merge(branch, message)
|
|
307
310
|
false
|
|
308
311
|
end
|
|
309
312
|
# merge a branch into this one
|
|
310
313
|
else
|
|
311
314
|
# merge this branch into the current one
|
|
312
|
-
|
|
315
|
+
branch_repository.merge(@name)
|
|
313
316
|
end
|
|
314
317
|
end
|
|
315
318
|
|
|
316
319
|
# Updates the git ref for this branch to point to the given commit
|
|
317
320
|
#
|
|
318
321
|
# The target ref depends on whether {#remote} is set:
|
|
319
|
-
# - When {#remote} is not `nil` (i.e. the branch was
|
|
322
|
+
# - When {#remote} is not `nil` (i.e. the branch was initialized with a
|
|
320
323
|
# `remotes/<remote>/` or `refs/remotes/<remote>/` prefix), updates
|
|
321
324
|
# `refs/remotes/<remote>/<name>`.
|
|
322
325
|
# - Otherwise updates `refs/heads/<name>`. Note that branches in the
|
|
@@ -329,15 +332,15 @@ module Git
|
|
|
329
332
|
#
|
|
330
333
|
# @param commit [String] the commit SHA to point this branch at
|
|
331
334
|
#
|
|
332
|
-
# @return [
|
|
335
|
+
# @return [Git::CommandLineResult] the result of calling `git update-ref`
|
|
333
336
|
#
|
|
334
337
|
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
335
338
|
#
|
|
336
339
|
def update_ref(commit)
|
|
337
340
|
if @remote
|
|
338
|
-
|
|
341
|
+
branch_repository.update_ref("remotes/#{@remote.name}/#{@name}", commit)
|
|
339
342
|
else
|
|
340
|
-
|
|
343
|
+
branch_repository.update_ref(@name, commit)
|
|
341
344
|
end
|
|
342
345
|
end
|
|
343
346
|
|
|
@@ -383,11 +386,51 @@ module Git
|
|
|
383
386
|
|
|
384
387
|
private
|
|
385
388
|
|
|
389
|
+
# Dispatches initialization to the appropriate strategy
|
|
390
|
+
#
|
|
391
|
+
# @param branch_info_or_name [Git::BranchInfo, String] branch info or name string
|
|
392
|
+
#
|
|
393
|
+
# @return [nil]
|
|
394
|
+
#
|
|
395
|
+
# @api private
|
|
396
|
+
#
|
|
397
|
+
def initialize_from_argument(branch_info_or_name)
|
|
398
|
+
if branch_info_or_name.is_a?(Git::BranchInfo)
|
|
399
|
+
initialize_from_branch_info(branch_info_or_name)
|
|
400
|
+
else
|
|
401
|
+
initialize_from_name(branch_info_or_name)
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
# Initialize from a BranchInfo object (preferred path)
|
|
406
|
+
#
|
|
407
|
+
# @param branch_info [Git::BranchInfo] the branch info
|
|
408
|
+
#
|
|
409
|
+
# @return [nil]
|
|
410
|
+
#
|
|
411
|
+
def initialize_from_branch_info(branch_info)
|
|
412
|
+
@full = branch_info.refname
|
|
413
|
+
@name = branch_info.short_name
|
|
414
|
+
@remote = branch_info.remote_name ? Git::Remote.new(@base, branch_info.remote_name) : nil
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
# Initialize from a string name (legacy path for backward compatibility)
|
|
418
|
+
#
|
|
419
|
+
# @param name [String] the branch name
|
|
420
|
+
#
|
|
421
|
+
# @return [nil]
|
|
422
|
+
#
|
|
423
|
+
def initialize_from_name(name)
|
|
424
|
+
@full = name
|
|
425
|
+
@remote, @name = parse_name(name)
|
|
426
|
+
end
|
|
427
|
+
|
|
386
428
|
# Parses a full branch name into remote and short branch name components
|
|
387
429
|
#
|
|
388
|
-
# Strips an optional `remotes/` or `refs/remotes/` prefix. Only inputs that
|
|
389
|
-
# with one of those prefixes yield a remote object; all other inputs
|
|
390
|
-
# `'origin/master'`) are treated as local branch names with a
|
|
430
|
+
# Strips an optional `remotes/` or `refs/remotes/` prefix. Only inputs that
|
|
431
|
+
# begin with one of those prefixes yield a remote object; all other inputs
|
|
432
|
+
# (including `'origin/master'`) are treated as local branch names with a
|
|
433
|
+
# `nil` remote.
|
|
391
434
|
#
|
|
392
435
|
# @example Local branches
|
|
393
436
|
# parse_name('master') #=> [nil, 'master']
|
|
@@ -399,8 +442,9 @@ module Git
|
|
|
399
442
|
#
|
|
400
443
|
# @param name [String] the full branch name to parse
|
|
401
444
|
#
|
|
402
|
-
# @return [Array(Git::Remote, String)] a two-element array
|
|
403
|
-
#
|
|
445
|
+
# @return [Array(Git::Remote, String)] a two-element array; the first element is
|
|
446
|
+
# a {Git::Remote} for remote-tracking branches or `nil` for local branches,
|
|
447
|
+
# and the second element is the short branch name
|
|
404
448
|
#
|
|
405
449
|
def parse_name(name)
|
|
406
450
|
# Expect this will always match
|
|
@@ -412,12 +456,26 @@ module Git
|
|
|
412
456
|
|
|
413
457
|
# Creates the branch if it does not already exist, ignoring errors
|
|
414
458
|
#
|
|
415
|
-
# @return [
|
|
459
|
+
# @return [nil]
|
|
416
460
|
#
|
|
417
461
|
def check_if_create
|
|
418
|
-
|
|
462
|
+
branch_repository.branch_new(@name)
|
|
419
463
|
rescue StandardError
|
|
420
464
|
nil
|
|
421
465
|
end
|
|
466
|
+
|
|
467
|
+
# Resolves the {Git::Repository} for this branch
|
|
468
|
+
#
|
|
469
|
+
# Accepts either a {Git::Repository} (new form) or a {Git::Base} (legacy).
|
|
470
|
+
# The `is_a?(Git::Base)` guard will be removed when {Git::Base} is deleted
|
|
471
|
+
# in Phase 4.
|
|
472
|
+
#
|
|
473
|
+
# @return [Git::Repository]
|
|
474
|
+
#
|
|
475
|
+
# @api private
|
|
476
|
+
#
|
|
477
|
+
def branch_repository
|
|
478
|
+
@base.is_a?(Git::Base) ? @base.facade_repository : @base
|
|
479
|
+
end
|
|
422
480
|
end
|
|
423
481
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
# Represents a branch that failed to be deleted
|
|
5
|
+
#
|
|
6
|
+
# This is an immutable data object returned as part of {Git::BranchDeleteResult}
|
|
7
|
+
# when one or more branches could not be deleted.
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# failure = Git::BranchDeleteFailure.new(
|
|
11
|
+
# name: 'nonexistent',
|
|
12
|
+
# error_message: "branch 'nonexistent' not found."
|
|
13
|
+
# )
|
|
14
|
+
# failure.name #=> 'nonexistent'
|
|
15
|
+
# failure.error_message #=> "branch 'nonexistent' not found."
|
|
16
|
+
#
|
|
17
|
+
# @see Git::BranchDeleteResult
|
|
18
|
+
# @see Git::Commands::Branch::Delete
|
|
19
|
+
#
|
|
20
|
+
# @api public
|
|
21
|
+
#
|
|
22
|
+
# @!attribute [r] name
|
|
23
|
+
# The name of the branch that failed to be deleted
|
|
24
|
+
# @return [String]
|
|
25
|
+
#
|
|
26
|
+
# @!attribute [r] error_message
|
|
27
|
+
# The error message from git explaining why the branch could not be deleted
|
|
28
|
+
# @return [String]
|
|
29
|
+
#
|
|
30
|
+
BranchDeleteFailure = Data.define(:name, :error_message)
|
|
31
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'git/branch_info'
|
|
4
|
+
require 'git/branch_delete_failure'
|
|
5
|
+
|
|
6
|
+
module Git
|
|
7
|
+
# Represents the result of a branch delete operation
|
|
8
|
+
#
|
|
9
|
+
# This is an immutable data object returned by {Git::Commands::Branch::Delete#call}.
|
|
10
|
+
# It contains information about which branches were successfully deleted and which
|
|
11
|
+
# failed to be deleted, along with the reason for each failure.
|
|
12
|
+
#
|
|
13
|
+
# Git's `git branch -d` command uses "best effort" semantics - it deletes as many
|
|
14
|
+
# branches as possible and reports errors for those that couldn't be deleted. This
|
|
15
|
+
# result object reflects that behavior, allowing callers to inspect both
|
|
16
|
+
# successes and failures.
|
|
17
|
+
#
|
|
18
|
+
# @example Successful deletion of all branches
|
|
19
|
+
# result = branch_delete.call('feature-1', 'feature-2')
|
|
20
|
+
# result.success? #=> true
|
|
21
|
+
# result.deleted.map(&:name) #=> ['feature-1', 'feature-2']
|
|
22
|
+
# result.not_deleted #=> []
|
|
23
|
+
#
|
|
24
|
+
# @example Partial failure (some branches deleted, some not found)
|
|
25
|
+
# result = branch_delete.call('feature-1', 'nonexistent', 'feature-2')
|
|
26
|
+
# result.success? #=> false
|
|
27
|
+
# result.deleted.map(&:name) #=> ['feature-1', 'feature-2']
|
|
28
|
+
# result.not_deleted.first.name #=> 'nonexistent'
|
|
29
|
+
# result.not_deleted.first.error_message #=> "branch 'nonexistent' not found."
|
|
30
|
+
#
|
|
31
|
+
# @see Git::BranchInfo
|
|
32
|
+
# @see Git::BranchDeleteFailure
|
|
33
|
+
# @see Git::Commands::Branch::Delete
|
|
34
|
+
#
|
|
35
|
+
# @api public
|
|
36
|
+
#
|
|
37
|
+
# @!attribute [r] deleted
|
|
38
|
+
# Branches that were successfully deleted
|
|
39
|
+
# @return [Array<Git::BranchInfo>]
|
|
40
|
+
#
|
|
41
|
+
# @!attribute [r] not_deleted
|
|
42
|
+
# Branches that could not be deleted, with the reason for each failure
|
|
43
|
+
# @return [Array<Git::BranchDeleteFailure>]
|
|
44
|
+
#
|
|
45
|
+
BranchDeleteResult = Data.define(:deleted, :not_deleted) do
|
|
46
|
+
# Returns true if all requested branches were successfully deleted
|
|
47
|
+
#
|
|
48
|
+
# @return [Boolean] true if no branches failed to delete, false otherwise
|
|
49
|
+
#
|
|
50
|
+
# @example
|
|
51
|
+
# result = branch_delete.call('feature-branch')
|
|
52
|
+
# if result.success?
|
|
53
|
+
# puts "All branches deleted successfully"
|
|
54
|
+
# else
|
|
55
|
+
# puts "Some branches could not be deleted:"
|
|
56
|
+
# result.not_deleted.each { |f| puts " #{f.name}: #{f.error_message}" }
|
|
57
|
+
# end
|
|
58
|
+
#
|
|
59
|
+
def success?
|
|
60
|
+
not_deleted.empty?
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
# Regular expression for parsing branch refnames
|
|
5
|
+
#
|
|
6
|
+
# Captures:
|
|
7
|
+
# - remote_name: the remote name (e.g., 'origin') for remote branches, nil for local
|
|
8
|
+
# - branch_name: the branch name without the remote prefix
|
|
9
|
+
#
|
|
10
|
+
# @note This regex is similar to Git::Branch::BRANCH_NAME_REGEXP but uses \A/\z anchors
|
|
11
|
+
# instead of ^/$ for stricter matching. As part of the architectural redesign,
|
|
12
|
+
# Git::Branch will eventually be refactored to use BranchInfo internally, at which
|
|
13
|
+
# point this will become the single source of truth for branch name parsing.
|
|
14
|
+
#
|
|
15
|
+
# @note This regex assumes remote names do not contain '/'. If a remote name
|
|
16
|
+
# contains '/', parsing will be incorrect. For example, 'remotes/team/upstream/main'
|
|
17
|
+
# would parse as remote_name='team' instead of 'team/upstream'. This is an inherent
|
|
18
|
+
# ambiguity in git refnames that can only be resolved with knowledge of configured
|
|
19
|
+
# remotes. See: https://github.com/ruby-git/ruby-git/issues/919
|
|
20
|
+
#
|
|
21
|
+
# @example
|
|
22
|
+
# 'main' => { remote_name: nil, branch_name: 'main' }
|
|
23
|
+
# 'remotes/origin/main' => { remote_name: 'origin', branch_name: 'main' }
|
|
24
|
+
# 'feature/foo' => { remote_name: nil, branch_name: 'feature/foo' }
|
|
25
|
+
# 'remotes/origin/feature/bar' => { remote_name: 'origin', branch_name: 'feature/bar' }
|
|
26
|
+
#
|
|
27
|
+
# @api private
|
|
28
|
+
BRANCH_REFNAME_REGEXP = %r{
|
|
29
|
+
\A # start of string
|
|
30
|
+
(?:(?:refs/)?remotes/(?<remote_name>[^/]+)/)? # optional 'refs?/remotes/<remote_name>/'
|
|
31
|
+
(?<branch_name>.+) # branch name (everything else)
|
|
32
|
+
\z # end of string
|
|
33
|
+
}x
|
|
34
|
+
|
|
35
|
+
# Value object representing branch metadata from git branch output
|
|
36
|
+
#
|
|
37
|
+
# This is a lightweight, immutable data structure returned by branch listing
|
|
38
|
+
# commands. It contains only the data parsed from git output without any
|
|
39
|
+
# repository context or operations.
|
|
40
|
+
#
|
|
41
|
+
# @example Creating from git branch output
|
|
42
|
+
# info = Git::BranchInfo.new(
|
|
43
|
+
# refname: 'main',
|
|
44
|
+
# target_oid: 'abc123def456789012345678901234567890abcd',
|
|
45
|
+
# current: true,
|
|
46
|
+
# worktree: false,
|
|
47
|
+
# symref: nil,
|
|
48
|
+
# upstream: nil
|
|
49
|
+
# )
|
|
50
|
+
# info.current? #=> true
|
|
51
|
+
# info.remote? #=> false
|
|
52
|
+
# info.short_name #=> 'main'
|
|
53
|
+
#
|
|
54
|
+
# @example Remote branch
|
|
55
|
+
# info = Git::BranchInfo.new(
|
|
56
|
+
# refname: 'remotes/origin/main',
|
|
57
|
+
# target_oid: 'abc123def456789012345678901234567890abcd',
|
|
58
|
+
# current: false,
|
|
59
|
+
# worktree: false,
|
|
60
|
+
# symref: nil,
|
|
61
|
+
# upstream: nil
|
|
62
|
+
# )
|
|
63
|
+
# info.remote? #=> true
|
|
64
|
+
# info.remote_name #=> 'origin'
|
|
65
|
+
# info.short_name #=> 'main'
|
|
66
|
+
#
|
|
67
|
+
# @example Local branch with upstream tracking
|
|
68
|
+
# upstream_info = Git::BranchInfo.new(
|
|
69
|
+
# refname: 'remotes/origin/main',
|
|
70
|
+
# target_oid: 'abc123def456789012345678901234567890abcd',
|
|
71
|
+
# current: false,
|
|
72
|
+
# worktree: false,
|
|
73
|
+
# symref: nil,
|
|
74
|
+
# upstream: nil
|
|
75
|
+
# )
|
|
76
|
+
# info = Git::BranchInfo.new(
|
|
77
|
+
# refname: 'main',
|
|
78
|
+
# target_oid: 'abc123def456789012345678901234567890abcd',
|
|
79
|
+
# current: true,
|
|
80
|
+
# worktree: false,
|
|
81
|
+
# symref: nil,
|
|
82
|
+
# upstream: upstream_info
|
|
83
|
+
# )
|
|
84
|
+
# info.upstream.remote_name #=> 'origin'
|
|
85
|
+
#
|
|
86
|
+
# @see Git::Branch for the full-featured branch object with operations
|
|
87
|
+
#
|
|
88
|
+
# @see Git::Commands::Branch::List for the command that produces these
|
|
89
|
+
#
|
|
90
|
+
# @api public
|
|
91
|
+
#
|
|
92
|
+
# @!attribute [r] refname
|
|
93
|
+
#
|
|
94
|
+
# The full reference name of the branch
|
|
95
|
+
#
|
|
96
|
+
# @return [String] the branch refname (e.g., 'main', 'remotes/origin/main')
|
|
97
|
+
#
|
|
98
|
+
# @!attribute [r] target_oid
|
|
99
|
+
#
|
|
100
|
+
# The commit object ID (SHA) that this branch points to
|
|
101
|
+
#
|
|
102
|
+
# @return [String, nil] the full 40-character object ID, or nil if unavailable
|
|
103
|
+
#
|
|
104
|
+
# @!attribute [r] current
|
|
105
|
+
#
|
|
106
|
+
# Whether this branch is currently checked out in the current worktree
|
|
107
|
+
#
|
|
108
|
+
# @return [Boolean] true if this is the current branch
|
|
109
|
+
#
|
|
110
|
+
# @!attribute [r] worktree
|
|
111
|
+
#
|
|
112
|
+
# Whether this branch is checked out in another linked worktree
|
|
113
|
+
#
|
|
114
|
+
# @return [Boolean] true if checked out in a different worktree
|
|
115
|
+
#
|
|
116
|
+
# @!attribute [r] symref
|
|
117
|
+
#
|
|
118
|
+
# The target reference if this is a symbolic reference
|
|
119
|
+
#
|
|
120
|
+
# @return [String, nil] the target ref (e.g., 'refs/heads/main'), or nil if not a symref
|
|
121
|
+
#
|
|
122
|
+
# @!attribute [r] upstream
|
|
123
|
+
#
|
|
124
|
+
# The configured upstream/tracking branch
|
|
125
|
+
#
|
|
126
|
+
# @return [Git::BranchInfo, nil] the upstream branch info, or nil if no upstream is configured
|
|
127
|
+
#
|
|
128
|
+
# @note Remote-tracking branches (e.g., 'origin/main') have upstream: nil
|
|
129
|
+
#
|
|
130
|
+
# @note When upstream exists but the remote-tracking branch hasn't been fetched,
|
|
131
|
+
# the upstream's target_oid may be nil
|
|
132
|
+
#
|
|
133
|
+
BranchInfo = Data.define(:refname, :target_oid, :current, :worktree, :symref, :upstream) do
|
|
134
|
+
# @return [Boolean] always false for BranchInfo (see DetachedHeadInfo for detached state)
|
|
135
|
+
def detached? = false
|
|
136
|
+
|
|
137
|
+
# @return [Boolean] true if this is an unborn branch (no commits yet)
|
|
138
|
+
def unborn? = target_oid.nil?
|
|
139
|
+
|
|
140
|
+
# @return [Boolean] true if this is the currently checked out branch
|
|
141
|
+
def current? = current
|
|
142
|
+
|
|
143
|
+
# @return [Boolean] true if this branch is checked out in another worktree
|
|
144
|
+
def worktree? = worktree
|
|
145
|
+
|
|
146
|
+
# @return [Boolean] true if this is a symbolic reference
|
|
147
|
+
def symref? = !symref.nil?
|
|
148
|
+
|
|
149
|
+
# @return [Boolean] true if this is a remote-tracking branch
|
|
150
|
+
def remote? = !remote_name.nil?
|
|
151
|
+
|
|
152
|
+
# @return [String, nil] the name of the remote (e.g., 'origin'), or nil for local branches
|
|
153
|
+
def remote_name
|
|
154
|
+
parse_refname[:remote_name]
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# @return [String] the branch name without remote prefix (e.g., 'main' or 'feature/foo')
|
|
158
|
+
def short_name
|
|
159
|
+
parse_refname[:branch_name]
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# @return [String] string representation (the full refname)
|
|
163
|
+
def to_s = refname
|
|
164
|
+
|
|
165
|
+
private
|
|
166
|
+
|
|
167
|
+
# Parse the refname and return match data
|
|
168
|
+
#
|
|
169
|
+
# The regex is guaranteed to match any non-empty string due to the `.+` pattern,
|
|
170
|
+
# so we don't need nil checking. If refname is empty/nil, this would fail at
|
|
171
|
+
# object creation time since refname is a required attribute.
|
|
172
|
+
#
|
|
173
|
+
# @return [MatchData] the match result
|
|
174
|
+
def parse_refname
|
|
175
|
+
refname.match(Git::BRANCH_REFNAME_REGEXP)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|