git 1.19.1 → 5.5.0
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/.yardopts +5 -1
- data/AI_POLICY.md +24 -0
- data/CHANGELOG.md +689 -0
- data/CODE_OF_CONDUCT.md +25 -0
- data/CONTRIBUTING.md +1175 -97
- data/GOVERNANCE.md +106 -0
- data/LICENSE +1 -1
- data/MAINTAINERS.md +17 -4
- data/README.md +476 -320
- data/UPGRADING.md +1138 -0
- data/git.gemspec +124 -36
- data/lib/git/author.rb +39 -7
- data/lib/git/author_info.rb +66 -0
- data/lib/git/branch.rb +615 -65
- data/lib/git/branch_delete_failure.rb +34 -0
- data/lib/git/branch_delete_result.rb +66 -0
- data/lib/git/branch_info.rb +237 -0
- data/lib/git/branches.rb +167 -44
- data/lib/git/command_line/base.rb +247 -0
- data/lib/git/command_line/capturing.rb +308 -0
- data/lib/git/command_line/result.rb +88 -0
- data/lib/git/command_line/streaming.rb +236 -0
- data/lib/git/command_line.rb +52 -0
- data/lib/git/commands/add.rb +139 -0
- data/lib/git/commands/am/abort.rb +43 -0
- data/lib/git/commands/am/apply.rb +263 -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 +49 -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 +242 -0
- data/lib/git/commands/archive/list_formats.rb +46 -0
- data/lib/git/commands/archive.rb +145 -0
- data/lib/git/commands/arguments.rb +4521 -0
- data/lib/git/commands/base.rb +502 -0
- data/lib/git/commands/branch/copy.rb +102 -0
- data/lib/git/commands/branch/create.rb +177 -0
- data/lib/git/commands/branch/delete.rb +88 -0
- data/lib/git/commands/branch/list.rb +178 -0
- data/lib/git/commands/branch/move.rb +102 -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 +53 -0
- data/lib/git/commands/branch.rb +34 -0
- data/lib/git/commands/cat_file/batch.rb +385 -0
- data/lib/git/commands/cat_file/filtered.rb +105 -0
- data/lib/git/commands/cat_file/raw.rb +271 -0
- data/lib/git/commands/cat_file.rb +49 -0
- data/lib/git/commands/checkout/branch.rb +153 -0
- data/lib/git/commands/checkout/files.rb +116 -0
- data/lib/git/commands/checkout.rb +38 -0
- data/lib/git/commands/checkout_index.rb +106 -0
- data/lib/git/commands/clean.rb +102 -0
- data/lib/git/commands/clone.rb +241 -0
- data/lib/git/commands/commit.rb +273 -0
- data/lib/git/commands/commit_tree.rb +101 -0
- data/lib/git/commands/config_option_syntax/add.rb +86 -0
- data/lib/git/commands/config_option_syntax/get.rb +121 -0
- data/lib/git/commands/config_option_syntax/get_all.rb +118 -0
- data/lib/git/commands/config_option_syntax/get_color.rb +95 -0
- data/lib/git/commands/config_option_syntax/get_color_bool.rb +96 -0
- data/lib/git/commands/config_option_syntax/get_regexp.rb +119 -0
- data/lib/git/commands/config_option_syntax/get_urlmatch.rb +111 -0
- data/lib/git/commands/config_option_syntax/list.rb +111 -0
- data/lib/git/commands/config_option_syntax/remove_section.rb +79 -0
- data/lib/git/commands/config_option_syntax/rename_section.rb +83 -0
- data/lib/git/commands/config_option_syntax/replace_all.rb +109 -0
- data/lib/git/commands/config_option_syntax/set.rb +119 -0
- data/lib/git/commands/config_option_syntax/unset.rb +92 -0
- data/lib/git/commands/config_option_syntax/unset_all.rb +94 -0
- data/lib/git/commands/config_option_syntax.rb +56 -0
- data/lib/git/commands/describe.rb +156 -0
- data/lib/git/commands/diff.rb +657 -0
- data/lib/git/commands/diff_files.rb +519 -0
- data/lib/git/commands/diff_index.rb +499 -0
- data/lib/git/commands/fetch.rb +354 -0
- data/lib/git/commands/fsck.rb +138 -0
- data/lib/git/commands/gc.rb +134 -0
- data/lib/git/commands/grep.rb +339 -0
- data/lib/git/commands/init.rb +101 -0
- data/lib/git/commands/log.rb +634 -0
- data/lib/git/commands/ls_files.rb +195 -0
- data/lib/git/commands/ls_remote.rb +161 -0
- data/lib/git/commands/ls_tree.rb +135 -0
- data/lib/git/commands/maintenance/register.rb +77 -0
- data/lib/git/commands/maintenance/run.rb +109 -0
- data/lib/git/commands/maintenance/start.rb +71 -0
- data/lib/git/commands/maintenance/stop.rb +60 -0
- data/lib/git/commands/maintenance/unregister.rb +84 -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 +250 -0
- data/lib/git/commands/merge.rb +28 -0
- data/lib/git/commands/merge_base.rb +91 -0
- data/lib/git/commands/mv.rb +82 -0
- data/lib/git/commands/name_rev.rb +119 -0
- data/lib/git/commands/pull.rb +382 -0
- data/lib/git/commands/push.rb +251 -0
- data/lib/git/commands/read_tree.rb +154 -0
- data/lib/git/commands/remote/add.rb +96 -0
- data/lib/git/commands/remote/get_url.rb +68 -0
- data/lib/git/commands/remote/list.rb +56 -0
- data/lib/git/commands/remote/prune.rb +63 -0
- data/lib/git/commands/remote/remove.rb +52 -0
- data/lib/git/commands/remote/rename.rb +76 -0
- data/lib/git/commands/remote/set_branches.rb +70 -0
- data/lib/git/commands/remote/set_head.rb +89 -0
- data/lib/git/commands/remote/set_url.rb +78 -0
- data/lib/git/commands/remote/set_url_add.rb +70 -0
- data/lib/git/commands/remote/set_url_delete.rb +71 -0
- data/lib/git/commands/remote/show.rb +77 -0
- data/lib/git/commands/remote/update.rb +79 -0
- data/lib/git/commands/remote.rb +42 -0
- data/lib/git/commands/repack.rb +281 -0
- data/lib/git/commands/reset.rb +154 -0
- data/lib/git/commands/rev_parse.rb +304 -0
- data/lib/git/commands/revert/abort.rb +45 -0
- data/lib/git/commands/revert/continue.rb +62 -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 +158 -0
- data/lib/git/commands/revert.rb +29 -0
- data/lib/git/commands/rm.rb +113 -0
- data/lib/git/commands/show.rb +632 -0
- data/lib/git/commands/show_ref/exclude_existing.rb +119 -0
- data/lib/git/commands/show_ref/exists.rb +80 -0
- data/lib/git/commands/show_ref/list.rb +149 -0
- data/lib/git/commands/show_ref/verify.rb +122 -0
- data/lib/git/commands/show_ref.rb +42 -0
- data/lib/git/commands/stash/apply.rb +81 -0
- data/lib/git/commands/stash/branch.rb +67 -0
- data/lib/git/commands/stash/clear.rb +43 -0
- data/lib/git/commands/stash/create.rb +60 -0
- data/lib/git/commands/stash/drop.rb +73 -0
- data/lib/git/commands/stash/list.rb +43 -0
- data/lib/git/commands/stash/pop.rb +87 -0
- data/lib/git/commands/stash/push.rb +112 -0
- data/lib/git/commands/stash/show.rb +158 -0
- data/lib/git/commands/stash/store.rb +72 -0
- data/lib/git/commands/stash.rb +38 -0
- data/lib/git/commands/status.rb +174 -0
- data/lib/git/commands/symbolic_ref/delete.rb +72 -0
- data/lib/git/commands/symbolic_ref/read.rb +99 -0
- data/lib/git/commands/symbolic_ref/update.rb +79 -0
- data/lib/git/commands/symbolic_ref.rb +38 -0
- data/lib/git/commands/tag/create.rb +142 -0
- data/lib/git/commands/tag/delete.rb +57 -0
- data/lib/git/commands/tag/list.rb +146 -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 +145 -0
- data/lib/git/commands/update_ref/delete.rb +90 -0
- data/lib/git/commands/update_ref/update.rb +103 -0
- data/lib/git/commands/update_ref.rb +42 -0
- data/lib/git/commands/version.rb +60 -0
- data/lib/git/commands/worktree/add.rb +139 -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 +88 -0
- data/lib/git/config.rb +72 -5
- data/lib/git/config_entry_info.rb +106 -0
- data/lib/git/configuring.rb +795 -0
- data/lib/git/detached_head_info.rb +57 -0
- data/lib/git/diff.rb +437 -86
- data/lib/git/diff_file_numstat_info.rb +31 -0
- data/lib/git/diff_file_patch_info.rb +136 -0
- data/lib/git/diff_file_raw_info.rb +129 -0
- data/lib/git/diff_info.rb +162 -0
- data/lib/git/diff_path_status.rb +107 -0
- data/lib/git/diff_result.rb +34 -0
- data/lib/git/diff_stats.rb +111 -0
- data/lib/git/dirstat_info.rb +102 -0
- data/lib/git/encoding_utils.rb +32 -1
- data/lib/git/errors.rb +285 -0
- data/lib/git/escaped_path.rb +57 -5
- data/lib/git/execution_context/global.rb +31 -0
- data/lib/git/execution_context/repository.rb +151 -0
- data/lib/git/execution_context.rb +559 -0
- data/lib/git/factories.rb +813 -0
- data/lib/git/file_ref.rb +77 -0
- data/lib/git/fsck_object.rb +56 -0
- data/lib/git/fsck_result.rb +132 -0
- data/lib/git/log.rb +306 -90
- data/lib/git/object.rb +563 -141
- data/lib/git/parsers/branch.rb +240 -0
- data/lib/git/parsers/cat_file.rb +111 -0
- data/lib/git/parsers/config_entry.rb +110 -0
- data/lib/git/parsers/diff.rb +792 -0
- data/lib/git/parsers/fsck.rb +144 -0
- data/lib/git/parsers/grep.rb +42 -0
- data/lib/git/parsers/ls_remote.rb +79 -0
- data/lib/git/parsers/ls_tree.rb +58 -0
- data/lib/git/parsers/remote.rb +162 -0
- data/lib/git/parsers/stash.rb +292 -0
- data/lib/git/parsers/status.rb +251 -0
- data/lib/git/parsers/tag.rb +341 -0
- data/lib/git/parsers/worktree.rb +185 -0
- data/lib/git/path_resolver.rb +206 -0
- data/lib/git/remote.rb +165 -12
- data/lib/git/remote_info.rb +203 -0
- data/lib/git/repository/branching.rb +964 -0
- data/lib/git/repository/committing.rb +246 -0
- data/lib/git/repository/context_helpers.rb +293 -0
- data/lib/git/repository/diffing.rb +785 -0
- data/lib/git/repository/inspecting.rb +252 -0
- data/lib/git/repository/logging.rb +410 -0
- data/lib/git/repository/maintenance.rb +65 -0
- data/lib/git/repository/merging.rb +451 -0
- data/lib/git/repository/object_operations.rb +1551 -0
- data/lib/git/repository/remote_operations.rb +984 -0
- data/lib/git/repository/shared_private.rb +120 -0
- data/lib/git/repository/staging.rb +587 -0
- data/lib/git/repository/stashing.rb +623 -0
- data/lib/git/repository/status_operations.rb +249 -0
- data/lib/git/repository/worktree_operations.rb +339 -0
- data/lib/git/repository.rb +484 -2
- data/lib/git/stash.rb +109 -12
- data/lib/git/stash_info.rb +102 -0
- data/lib/git/stashes.rb +169 -26
- data/lib/git/status.rb +308 -122
- data/lib/git/status_file_info.rb +258 -0
- data/lib/git/status_info.rb +189 -0
- data/lib/git/tag_delete_failure.rb +34 -0
- data/lib/git/tag_delete_result.rb +66 -0
- data/lib/git/tag_info.rb +99 -0
- data/lib/git/url.rb +15 -8
- data/lib/git/version.rb +113 -2
- data/lib/git/version_constraint.rb +85 -0
- data/lib/git/worktree.rb +150 -8
- data/lib/git/worktree_info.rb +128 -0
- data/lib/git/worktrees.rb +118 -13
- data/lib/git.rb +632 -234
- metadata +369 -54
- data/.github/stale.yml +0 -25
- data/.github/workflows/continuous_integration.yml +0 -49
- data/.gitignore +0 -10
- data/Dockerfile.changelog-rs +0 -12
- data/Gemfile +0 -5
- data/ISSUE_TEMPLATE.md +0 -15
- data/PULL_REQUEST_TEMPLATE.md +0 -9
- data/RELEASING.md +0 -70
- data/Rakefile +0 -60
- data/lib/git/base/factory.rb +0 -99
- data/lib/git/base.rb +0 -711
- data/lib/git/command_line_result.rb +0 -86
- data/lib/git/failed_error.rb +0 -53
- data/lib/git/git_execute_error.rb +0 -7
- data/lib/git/index.rb +0 -5
- data/lib/git/lib.rb +0 -1328
- data/lib/git/path.rb +0 -31
- data/lib/git/signaled_error.rb +0 -50
- data/lib/git/working_directory.rb +0 -4
data/lib/git/branch.rb
CHANGED
|
@@ -1,109 +1,558 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'branch_info'
|
|
2
4
|
|
|
3
5
|
module Git
|
|
4
|
-
|
|
5
|
-
|
|
6
|
+
# Represents a Git branch
|
|
7
|
+
#
|
|
8
|
+
# Branch objects provide access to branch metadata and operations like checkout,
|
|
9
|
+
# delete, and merge. They should be obtained via {Git::Repository#branch} or
|
|
10
|
+
# {Git::Repository#branches}, not constructed directly.
|
|
11
|
+
#
|
|
12
|
+
# @example Getting a branch
|
|
13
|
+
# git = Git.open('.')
|
|
14
|
+
# branch = git.branch('main')
|
|
15
|
+
# branch.checkout
|
|
16
|
+
#
|
|
17
|
+
# @example Listing branches
|
|
18
|
+
# git.branches.each { |b| puts b.name }
|
|
19
|
+
#
|
|
20
|
+
# @deprecated Use {Git::Repository::Branching#branch_list} and the
|
|
21
|
+
# name-based branch operations on {Git::Repository} instead
|
|
22
|
+
#
|
|
23
|
+
# {Git::Repository::Branching#branch_list} returns immutable
|
|
24
|
+
# {Git::BranchInfo} value objects. Operations that lived on this class are
|
|
25
|
+
# called on the repository with the branch name instead (for example
|
|
26
|
+
# {Git::Repository::Branching#checkout} and
|
|
27
|
+
# {Git::Repository::Branching#branch_delete}). Every operation on a
|
|
28
|
+
# `Git::Branch` emits a deprecation warning; the `full`, `name`, `remote`,
|
|
29
|
+
# `to_s`, and `to_a` readers do not.
|
|
30
|
+
#
|
|
31
|
+
# @api public
|
|
32
|
+
#
|
|
33
|
+
class Branch
|
|
34
|
+
# The full refname of this branch
|
|
35
|
+
#
|
|
36
|
+
# For local branches this is the short name (e.g. `'main'`). For
|
|
37
|
+
# remote-tracking branches obtained via {Git::Repository#branches} this includes
|
|
38
|
+
# the `remotes/` prefix (e.g. `'remotes/origin/main'`). Branches constructed
|
|
39
|
+
# by {Git::Remote#branch} use the `<remote>/<branch>` form (e.g.
|
|
40
|
+
# `'origin/main'`) which does **not** populate {#remote}.
|
|
41
|
+
#
|
|
42
|
+
# @example Local and remote-tracking branch full refnames
|
|
43
|
+
# git.branch('main').full #=> 'main'
|
|
44
|
+
# git.branch('remotes/origin/main').full #=> 'remotes/origin/main'
|
|
45
|
+
#
|
|
46
|
+
# @return [String] the full refname
|
|
47
|
+
#
|
|
48
|
+
attr_accessor :full
|
|
6
49
|
|
|
7
|
-
|
|
8
|
-
|
|
50
|
+
# The remote for this branch, or `nil` for local or bare-name remote-tracking branches
|
|
51
|
+
#
|
|
52
|
+
# Set to a {Git::Remote} object only when this branch was initialized with a
|
|
53
|
+
# `remotes/<remote>/` or `refs/remotes/<remote>/` prefix. `nil` for local
|
|
54
|
+
# branches and for remote-tracking branches in `<remote>/<branch>` form
|
|
55
|
+
# (such as those returned by {Git::Remote#branch}).
|
|
56
|
+
#
|
|
57
|
+
# @example Local and remote-tracking branches
|
|
58
|
+
# git.branch('main').remote #=> nil
|
|
59
|
+
# git.branch('remotes/origin/main').remote #=> #<Git::Remote 'origin'>
|
|
60
|
+
# git.remote('origin').branch('main').remote #=> nil # uses 'origin/main' form
|
|
61
|
+
#
|
|
62
|
+
# @return [Git::Remote, nil] the remote object, or `nil`
|
|
63
|
+
#
|
|
64
|
+
attr_accessor :remote
|
|
65
|
+
|
|
66
|
+
# The short branch name without the remote prefix
|
|
67
|
+
#
|
|
68
|
+
# For both local and remote-tracking branches this is the bare branch
|
|
69
|
+
# name (e.g. `'main'` rather than `'remotes/origin/main'`).
|
|
70
|
+
#
|
|
71
|
+
# @example Local and remote-tracking branch short names
|
|
72
|
+
# git.branch('main').name #=> 'main'
|
|
73
|
+
# git.branch('remotes/origin/main').name #=> 'main'
|
|
74
|
+
#
|
|
75
|
+
# @return [String] the short branch name
|
|
76
|
+
#
|
|
77
|
+
attr_accessor :name
|
|
78
|
+
|
|
79
|
+
# Initialize a new Branch object
|
|
80
|
+
#
|
|
81
|
+
# @param base [Git::Repository] the git repository
|
|
82
|
+
#
|
|
83
|
+
# @param branch_info_or_name [Git::BranchInfo, String] branch info object or name string
|
|
84
|
+
#
|
|
85
|
+
# Passing a BranchInfo is preferred; String support is for backward compatibility.
|
|
86
|
+
#
|
|
87
|
+
# @note Use {Git::Repository#branch} or {Git::Repository#branches} instead of constructing directly
|
|
88
|
+
#
|
|
89
|
+
# @api private
|
|
90
|
+
#
|
|
91
|
+
def initialize(base, branch_info_or_name)
|
|
9
92
|
@base = base
|
|
10
93
|
@gcommit = nil
|
|
11
94
|
@stashes = nil
|
|
12
|
-
|
|
95
|
+
|
|
96
|
+
initialize_from_argument(branch_info_or_name)
|
|
13
97
|
end
|
|
14
98
|
|
|
99
|
+
# Returns the commit at the tip of this branch
|
|
100
|
+
#
|
|
101
|
+
# The result is memoized after the first call.
|
|
102
|
+
#
|
|
103
|
+
# @example Get the tip commit
|
|
104
|
+
# git.branch('main').gcommit #=> #<Git::Object ...>
|
|
105
|
+
#
|
|
106
|
+
# @return [Git::Object] the commit at the tip of this branch
|
|
107
|
+
#
|
|
108
|
+
# @deprecated Use {Git::Repository::ObjectOperations#gcommit} with the branch name instead
|
|
109
|
+
#
|
|
110
|
+
# Pass the branch name for a local branch, or `"remotes/#{remote}/#{name}"`
|
|
111
|
+
# (the value of {#full}) for a remote-tracking branch; the shorter
|
|
112
|
+
# `"#{remote}/#{name}"` can resolve a local branch of that name.
|
|
113
|
+
#
|
|
114
|
+
# @see Git::Repository::ObjectOperations#gcommit
|
|
115
|
+
#
|
|
15
116
|
def gcommit
|
|
16
|
-
|
|
117
|
+
Git::Deprecation.warn(
|
|
118
|
+
'Git::Branch#gcommit is deprecated and will be removed in v6.0.0. ' \
|
|
119
|
+
'Use Git::Repository#gcommit(name) or, for a remote-tracking branch, ' \
|
|
120
|
+
'Git::Repository#gcommit("remotes/remote/name") instead.'
|
|
121
|
+
)
|
|
122
|
+
@gcommit ||= branch_repository.gcommit(@full)
|
|
17
123
|
@gcommit
|
|
18
124
|
end
|
|
19
125
|
|
|
126
|
+
# Returns the stash list for this repository
|
|
127
|
+
#
|
|
128
|
+
# This method ignores the branch receiver and returns every stash in the
|
|
129
|
+
# repository, so `git.branch('feature').stashes` and
|
|
130
|
+
# `git.branch('main').stashes` return the same entries. It is deprecated and
|
|
131
|
+
# will be removed in v6.0.0.
|
|
132
|
+
#
|
|
133
|
+
# The result is memoized after the first call.
|
|
134
|
+
#
|
|
135
|
+
# @example Iterate over stash entries (deprecated)
|
|
136
|
+
# git.branch('main').stashes.each { |s| puts s }
|
|
137
|
+
#
|
|
138
|
+
# @example The replacement
|
|
139
|
+
# repo.stash_infos.each { |info| puts info.message }
|
|
140
|
+
#
|
|
141
|
+
# @return [Git::Stashes] the stash list
|
|
142
|
+
#
|
|
143
|
+
# @deprecated Use {Git::Repository#stash_infos} instead
|
|
144
|
+
#
|
|
145
|
+
# @see Git::Repository#stash_infos
|
|
146
|
+
#
|
|
20
147
|
def stashes
|
|
21
|
-
|
|
148
|
+
Git::Deprecation.warn(
|
|
149
|
+
'Git::Branch#stashes is deprecated and will be removed in v6.0.0. ' \
|
|
150
|
+
'It ignores the branch and returns all repository stashes. ' \
|
|
151
|
+
'Use Git::Repository#stash_infos instead.'
|
|
152
|
+
)
|
|
153
|
+
# Git::Stashes is deprecated too; silence it so one stashes call emits one warning
|
|
154
|
+
@stashes ||= Git::Deprecation.silence { Git::Stashes.new(branch_repository) }
|
|
22
155
|
end
|
|
23
156
|
|
|
157
|
+
# Checks out this branch, attempting to create it first if it does not already exist
|
|
158
|
+
#
|
|
159
|
+
# Branch creation is attempted via {#check_if_create}; any error from that
|
|
160
|
+
# step is silently ignored and the checkout proceeds regardless.
|
|
161
|
+
#
|
|
162
|
+
# **Note:** for remote-tracking branches (where {#remote} is not `nil`),
|
|
163
|
+
# `check_if_create` will attempt to create a *local* branch named {#name}
|
|
164
|
+
# as a side-effect before checking out {#full} (which typically results in
|
|
165
|
+
# a detached HEAD). This is a known limitation; see
|
|
166
|
+
# [ruby-git#1280](https://github.com/ruby-git/ruby-git/issues/1280).
|
|
167
|
+
#
|
|
168
|
+
# @example Check out a branch
|
|
169
|
+
# git = Git.open('.')
|
|
170
|
+
# git.branch('main').checkout
|
|
171
|
+
#
|
|
172
|
+
# @return [String] git's stdout from the checkout
|
|
173
|
+
#
|
|
174
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
175
|
+
#
|
|
176
|
+
# @deprecated Use {Git::Repository::Branching#checkout} with the branch name instead
|
|
177
|
+
#
|
|
178
|
+
# {Git::Repository::Branching#checkout} does not create a missing local
|
|
179
|
+
# branch, apart from the guess git makes on its own: with no `:no_guess`
|
|
180
|
+
# option, git creates a tracking branch when exactly one remote has a
|
|
181
|
+
# branch of that name. To reproduce the create-or-checkout behavior of
|
|
182
|
+
# this method, call {Git::Repository::Branching#branch_new} when
|
|
183
|
+
# {Git::Repository::Branching#local_branch?} is false, then
|
|
184
|
+
# {Git::Repository::Branching#checkout}. Pass `"remotes/#{remote}/#{name}"`
|
|
185
|
+
# (the value of {#full}) for a remote-tracking branch; the shorter
|
|
186
|
+
# `"#{remote}/#{name}"` can resolve a local branch of that name.
|
|
187
|
+
#
|
|
188
|
+
# @see Git::Repository::Branching#checkout
|
|
189
|
+
#
|
|
190
|
+
# @see Git::Repository::Branching#branch_new
|
|
191
|
+
#
|
|
24
192
|
def checkout
|
|
193
|
+
Git::Deprecation.warn(
|
|
194
|
+
'Git::Branch#checkout is deprecated and will be removed in v6.0.0. ' \
|
|
195
|
+
'Use Git::Repository#checkout(name) or, for a remote-tracking branch, ' \
|
|
196
|
+
'Git::Repository#checkout("remotes/remote/name") instead. Git::Repository#checkout does not ' \
|
|
197
|
+
'create a missing local branch (beyond the guess git makes from a unique remote-tracking ' \
|
|
198
|
+
'branch); call Git::Repository#branch_new first unless Git::Repository#local_branch? is true.'
|
|
199
|
+
)
|
|
25
200
|
check_if_create
|
|
26
|
-
|
|
201
|
+
branch_repository.checkout(@full)
|
|
27
202
|
end
|
|
28
203
|
|
|
204
|
+
# Archives this branch and writes the result to a file
|
|
205
|
+
#
|
|
206
|
+
# @example Archive to a tar file
|
|
207
|
+
# git.branch('main').archive('/tmp/main.tar', format: 'tar')
|
|
208
|
+
#
|
|
209
|
+
# @example Archive to a zip file
|
|
210
|
+
# git.branch('main').archive('/tmp/main.zip', format: 'zip')
|
|
211
|
+
#
|
|
212
|
+
# @example Archive a remote branch to a tgz file
|
|
213
|
+
# git.remote('origin').branch('main').archive('/tmp/main.tgz', format: 'tgz')
|
|
214
|
+
#
|
|
215
|
+
# @param file [String] path to the destination archive file
|
|
216
|
+
#
|
|
217
|
+
# @param opts [Hash] archive options (see {Git::Repository#archive})
|
|
218
|
+
#
|
|
219
|
+
# @option opts [String] :format ('zip') archive format for this wrapper:
|
|
220
|
+
# `'tar'`, `'zip'`, or `'tgz'`
|
|
221
|
+
#
|
|
222
|
+
# @option opts [String] :prefix (nil) prefix prepended to every filename
|
|
223
|
+
# in the archive
|
|
224
|
+
#
|
|
225
|
+
# @option opts [String] :path (nil) path within the tree to include in the
|
|
226
|
+
# archive
|
|
227
|
+
#
|
|
228
|
+
# @option opts [String] :remote (nil) retrieve the archive from a remote
|
|
229
|
+
# repository
|
|
230
|
+
#
|
|
231
|
+
# @option opts [Boolean, nil] :add_gzip (nil) apply gzip compression after
|
|
232
|
+
# writing the archive; set automatically when `format: 'tgz'` is given
|
|
233
|
+
#
|
|
234
|
+
# @return [String] the path to the written archive file
|
|
235
|
+
#
|
|
236
|
+
# @raise [ArgumentError] when archive options or destination path are invalid
|
|
237
|
+
#
|
|
238
|
+
# @raise [Git::FailedError] if `git archive` fails
|
|
239
|
+
#
|
|
240
|
+
# @deprecated Use {Git::Repository::ObjectOperations#archive} with the branch name instead
|
|
241
|
+
#
|
|
242
|
+
# Pass the branch name for a local branch, or `"remotes/#{remote}/#{name}"`
|
|
243
|
+
# (the value of {#full}) for a remote-tracking branch; the shorter
|
|
244
|
+
# `"#{remote}/#{name}"` can resolve a local branch of that name.
|
|
245
|
+
#
|
|
246
|
+
# @see Git::Repository::ObjectOperations#archive
|
|
247
|
+
#
|
|
29
248
|
def archive(file, opts = {})
|
|
30
|
-
|
|
249
|
+
Git::Deprecation.warn(
|
|
250
|
+
'Git::Branch#archive is deprecated and will be removed in v6.0.0. ' \
|
|
251
|
+
'Use Git::Repository#archive(name, file, opts) or, for a remote-tracking branch, ' \
|
|
252
|
+
'Git::Repository#archive("remotes/remote/name", file, opts) instead.'
|
|
253
|
+
)
|
|
254
|
+
branch_repository.archive(@full, file, opts)
|
|
31
255
|
end
|
|
32
256
|
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
257
|
+
# Checks out this branch for the duration of a block, then restores the original branch
|
|
258
|
+
#
|
|
259
|
+
# If the block returns a truthy value, all pending changes are committed with the
|
|
260
|
+
# given message before switching back to the original branch. If the block returns
|
|
261
|
+
# a falsy value, a hard reset is performed before switching back.
|
|
262
|
+
#
|
|
263
|
+
# **Note:** the restore checkout is not wrapped in `ensure`. If the block,
|
|
264
|
+
# the commit, or the reset raises an exception, the repository will be left
|
|
265
|
+
# checked out on this branch rather than restored to the original.
|
|
266
|
+
#
|
|
267
|
+
# @example Commit a new file on a feature branch
|
|
268
|
+
# git.branch('feature').in_branch('Add README') do
|
|
269
|
+
# File.write('README.md', '# Hello')
|
|
270
|
+
# git.add('README.md')
|
|
271
|
+
# true # commit and return to original branch
|
|
272
|
+
# end
|
|
273
|
+
#
|
|
274
|
+
# @param message [String] commit message used when the block returns truthy
|
|
275
|
+
#
|
|
276
|
+
# @return [String] git's stdout from the final checkout back to the original branch
|
|
277
|
+
#
|
|
278
|
+
# @raise [Git::FailedError] if any of the underlying git operations (checkout, commit, reset) fail
|
|
279
|
+
#
|
|
280
|
+
# @yield Executes the block with this branch checked out
|
|
281
|
+
#
|
|
282
|
+
# @yieldreturn [Object] return a truthy value to commit all changes, a falsy value to hard-reset
|
|
283
|
+
#
|
|
284
|
+
# @deprecated Use {Git::Repository::Branching#in_branch} with the branch name instead
|
|
285
|
+
#
|
|
286
|
+
# {Git::Repository::Branching#in_branch} does not create the branch and
|
|
287
|
+
# restores a detached HEAD to its original commit.
|
|
288
|
+
# It takes an existing local branch, so a remote-tracking `Git::Branch` has
|
|
289
|
+
# no direct replacement: this method checked out the remote-tracking ref,
|
|
290
|
+
# detaching HEAD. Create a local branch from that ref with
|
|
291
|
+
# {Git::Repository::Branching#branch_new} first.
|
|
292
|
+
#
|
|
293
|
+
# @see Git::Repository::Branching#in_branch
|
|
294
|
+
#
|
|
38
295
|
def in_branch(message = 'in branch work')
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
296
|
+
Git::Deprecation.warn(
|
|
297
|
+
'Git::Branch#in_branch is deprecated and will be removed in v6.0.0. ' \
|
|
298
|
+
'Use Git::Repository#in_branch(name, message) instead. It takes an existing local ' \
|
|
299
|
+
'branch; for a remote-tracking branch, create a local branch from it first.'
|
|
300
|
+
)
|
|
301
|
+
old_current = branch_repository.current_branch
|
|
302
|
+
# checkout is deprecated too; silence it so one in_branch call emits one warning
|
|
303
|
+
Git::Deprecation.silence { checkout }
|
|
304
|
+
yield ? branch_repository.commit_all(message) : branch_repository.reset(nil, hard: true)
|
|
305
|
+
branch_repository.checkout(old_current)
|
|
47
306
|
end
|
|
48
307
|
|
|
308
|
+
# Creates this branch if it does not already exist
|
|
309
|
+
#
|
|
310
|
+
# Silently ignores any error raised during branch creation (including the case
|
|
311
|
+
# where the branch already exists).
|
|
312
|
+
#
|
|
313
|
+
# @example Create a new branch
|
|
314
|
+
# git.branch('feature').create
|
|
315
|
+
#
|
|
316
|
+
# @return [nil]
|
|
317
|
+
#
|
|
318
|
+
# @deprecated Use {Git::Repository::Branching#branch_new} instead
|
|
319
|
+
#
|
|
320
|
+
# {Git::Repository::Branching#branch_new} raises {Git::FailedError} when
|
|
321
|
+
# the branch already exists rather than ignoring the error.
|
|
322
|
+
#
|
|
323
|
+
# @see Git::Repository::Branching#branch_new
|
|
324
|
+
#
|
|
49
325
|
def create
|
|
326
|
+
Git::Deprecation.warn(
|
|
327
|
+
'Git::Branch#create is deprecated and will be removed in v6.0.0. ' \
|
|
328
|
+
'Use Git::Repository#branch_new instead.'
|
|
329
|
+
)
|
|
50
330
|
check_if_create
|
|
51
331
|
end
|
|
52
332
|
|
|
333
|
+
# Deletes this branch
|
|
334
|
+
#
|
|
335
|
+
# Remote-tracking branches (one where {#remote} is not `nil`) delete the
|
|
336
|
+
# local remote-tracking ref; they do not push a deletion to the remote.
|
|
337
|
+
#
|
|
338
|
+
# @example Delete a local branch
|
|
339
|
+
# git.branch('old-feature').delete
|
|
340
|
+
#
|
|
341
|
+
# @return [String] git's deletion output
|
|
342
|
+
#
|
|
343
|
+
# @raise [Git::Error] if the branch cannot be deleted
|
|
344
|
+
#
|
|
345
|
+
# @deprecated Use {Git::Repository::Branching#branch_delete} instead
|
|
346
|
+
#
|
|
347
|
+
# Pass the branch name for a local branch, or `"#{remote}/#{name}"` with
|
|
348
|
+
# `remotes: true` for a remote-tracking branch.
|
|
349
|
+
#
|
|
350
|
+
# @see Git::Repository::Branching#branch_delete
|
|
351
|
+
#
|
|
53
352
|
def delete
|
|
54
|
-
|
|
353
|
+
Git::Deprecation.warn(
|
|
354
|
+
'Git::Branch#delete is deprecated and will be removed in v6.0.0. ' \
|
|
355
|
+
'Use Git::Repository#branch_delete(name) or, for a remote-tracking branch, ' \
|
|
356
|
+
'Git::Repository#branch_delete("remote/name", remotes: true) instead.'
|
|
357
|
+
)
|
|
358
|
+
if @remote
|
|
359
|
+
branch_repository.branch_delete("#{@remote.name}/#{@name}", remotes: true)
|
|
360
|
+
else
|
|
361
|
+
branch_repository.branch_delete(@name)
|
|
362
|
+
end
|
|
55
363
|
end
|
|
56
364
|
|
|
57
|
-
|
|
58
|
-
|
|
365
|
+
# Returns true if this is the currently checked-out branch
|
|
366
|
+
#
|
|
367
|
+
# **Note:** this compares the current branch's short name against {#name}.
|
|
368
|
+
# For a remote-tracking branch (where {#remote} is not `nil`), {#name} is
|
|
369
|
+
# still the bare short name (e.g. `'main'`), so this will return `true`
|
|
370
|
+
# whenever the *local* branch with that name is checked out — not the
|
|
371
|
+
# remote-tracking ref itself.
|
|
372
|
+
#
|
|
373
|
+
# @example Check whether currently on main
|
|
374
|
+
# git.branch('main').current #=> true
|
|
375
|
+
#
|
|
376
|
+
# @return [Boolean] whether this branch is currently checked out
|
|
377
|
+
#
|
|
378
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
379
|
+
#
|
|
380
|
+
# @deprecated Compare {Git::Repository::Branching#current_branch} with the
|
|
381
|
+
# branch name instead
|
|
382
|
+
#
|
|
383
|
+
# @see Git::Repository::Branching#current_branch
|
|
384
|
+
#
|
|
385
|
+
def current # rubocop:disable Naming/PredicateMethod
|
|
386
|
+
Git::Deprecation.warn(
|
|
387
|
+
'Git::Branch#current is deprecated and will be removed in v6.0.0. ' \
|
|
388
|
+
'Use Git::Repository#current_branch == name instead.'
|
|
389
|
+
)
|
|
390
|
+
branch_repository.current_branch == @name
|
|
59
391
|
end
|
|
60
392
|
|
|
393
|
+
# Returns true if this branch contains the given commit
|
|
394
|
+
#
|
|
395
|
+
# **Note:** this queries local branches by short name. For a remote-tracking
|
|
396
|
+
# branch (where {#remote} is not `nil`), it checks the *local* branch with
|
|
397
|
+
# the same {#name} rather than the remote-tracking ref, which may give an
|
|
398
|
+
# inaccurate result.
|
|
399
|
+
#
|
|
400
|
+
# @example Check if a commit is reachable from this branch
|
|
401
|
+
# git.branch('main').contains?('abc1234') #=> true
|
|
402
|
+
#
|
|
403
|
+
# @param commit [String] the commit SHA or ref to check
|
|
404
|
+
#
|
|
405
|
+
# @return [Boolean] whether this branch contains the given commit
|
|
406
|
+
#
|
|
407
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
408
|
+
#
|
|
409
|
+
# @deprecated Use {Git::Repository::Branching#branch_contains} with the
|
|
410
|
+
# commit and branch name instead
|
|
411
|
+
#
|
|
412
|
+
# {Git::Repository::Branching#branch_contains} returns the matching
|
|
413
|
+
# branch names as a String; test it with `empty?`.
|
|
414
|
+
#
|
|
415
|
+
# @see Git::Repository::Branching#branch_contains
|
|
416
|
+
#
|
|
61
417
|
def contains?(commit)
|
|
62
|
-
|
|
418
|
+
Git::Deprecation.warn(
|
|
419
|
+
'Git::Branch#contains? is deprecated and will be removed in v6.0.0. ' \
|
|
420
|
+
'Use !Git::Repository#branch_contains(commit, name).empty? instead.'
|
|
421
|
+
)
|
|
422
|
+
!branch_repository.branch_contains(commit, name).empty?
|
|
63
423
|
end
|
|
64
424
|
|
|
425
|
+
# Merges a branch into this branch, or merges this branch into the current branch
|
|
426
|
+
#
|
|
427
|
+
# @overload merge(branch, message = nil)
|
|
428
|
+
#
|
|
429
|
+
# Temporarily checks out this branch, merges the given branch into it,
|
|
430
|
+
# then restores the original branch.
|
|
431
|
+
#
|
|
432
|
+
# **Note:** if `self` is a remote-tracking branch (where {#remote} is not
|
|
433
|
+
# `nil`), this delegates to {#checkout} which has the detached-HEAD
|
|
434
|
+
# side-effect described there. The remote-tracking ref will not be updated.
|
|
435
|
+
#
|
|
436
|
+
# @example Merge a feature branch into main
|
|
437
|
+
# git.branch('main').merge('feature')
|
|
438
|
+
#
|
|
439
|
+
# @param branch [String] the name of the branch to merge into this one
|
|
440
|
+
#
|
|
441
|
+
# @param message [String, nil] commit message for the merge commit
|
|
442
|
+
#
|
|
443
|
+
# @return [String] git's stdout from the final checkout back to the original branch
|
|
444
|
+
#
|
|
445
|
+
# @overload merge()
|
|
446
|
+
#
|
|
447
|
+
# Merges this branch into the currently checked-out branch.
|
|
448
|
+
#
|
|
449
|
+
# @example Merge main into the current branch
|
|
450
|
+
# git.branch('main').merge
|
|
451
|
+
#
|
|
452
|
+
# @return [String] git's stdout from the merge command
|
|
453
|
+
#
|
|
454
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
455
|
+
#
|
|
456
|
+
# @deprecated Use {Git::Repository::Merging#merge_into} in place of
|
|
457
|
+
# `merge(branch)` and {Git::Repository::Merging#merge} with the branch
|
|
458
|
+
# name in place of `merge()`
|
|
459
|
+
#
|
|
460
|
+
# {Git::Repository::Merging#merge_into} returns the merge's stdout, does
|
|
461
|
+
# not hard-reset after the merge, and restores a detached HEAD to its
|
|
462
|
+
# original commit.
|
|
463
|
+
# It takes an existing local branch, so a remote-tracking `Git::Branch` has
|
|
464
|
+
# no direct replacement: `merge(branch)` checked out the remote-tracking ref,
|
|
465
|
+
# detaching HEAD. Create a local branch from that ref with
|
|
466
|
+
# {Git::Repository::Branching#branch_new} first.
|
|
467
|
+
#
|
|
468
|
+
# @see Git::Repository::Merging#merge_into
|
|
469
|
+
#
|
|
470
|
+
# @see Git::Repository::Merging#merge
|
|
471
|
+
#
|
|
65
472
|
def merge(branch = nil, message = nil)
|
|
66
473
|
if branch
|
|
67
|
-
|
|
68
|
-
@base.merge(branch, message)
|
|
69
|
-
false
|
|
70
|
-
end
|
|
71
|
-
# merge a branch into this one
|
|
474
|
+
merge_into_this_branch(branch, message)
|
|
72
475
|
else
|
|
73
|
-
|
|
74
|
-
@base.merge(@name)
|
|
476
|
+
merge_into_current_branch
|
|
75
477
|
end
|
|
76
478
|
end
|
|
77
479
|
|
|
480
|
+
# Updates the git ref for this branch to point to the given commit
|
|
481
|
+
#
|
|
482
|
+
# The target ref depends on whether {#remote} is set:
|
|
483
|
+
# - When {#remote} is not `nil` (i.e. the branch was initialized with a
|
|
484
|
+
# `remotes/<remote>/` or `refs/remotes/<remote>/` prefix), updates
|
|
485
|
+
# `refs/remotes/<remote>/<name>`.
|
|
486
|
+
# - Otherwise updates `refs/heads/<name>`. Note that branches in the
|
|
487
|
+
# `<remote>/<branch>` form (e.g. those returned by {Git::Remote#branch})
|
|
488
|
+
# have `remote == nil` and therefore update `refs/heads/<remote>/<name>`,
|
|
489
|
+
# **not** `refs/remotes/...`.
|
|
490
|
+
#
|
|
491
|
+
# @example Advance a local branch to a new commit
|
|
492
|
+
# git.branch('feature').update_ref('abc1234def5678')
|
|
493
|
+
#
|
|
494
|
+
# @param commit [String] the commit SHA to point this branch at
|
|
495
|
+
#
|
|
496
|
+
# @return [Git::CommandLine::Result] the result of calling `git update-ref`
|
|
497
|
+
#
|
|
498
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
499
|
+
#
|
|
500
|
+
# @deprecated Use {Git::Repository::Branching#update_ref} instead
|
|
501
|
+
#
|
|
502
|
+
# Pass the branch name for a local branch, or
|
|
503
|
+
# `"remotes/#{remote}/#{name}"` for a remote-tracking branch.
|
|
504
|
+
#
|
|
505
|
+
# @see Git::Repository::Branching#update_ref
|
|
506
|
+
#
|
|
78
507
|
def update_ref(commit)
|
|
508
|
+
Git::Deprecation.warn(
|
|
509
|
+
'Git::Branch#update_ref is deprecated and will be removed in v6.0.0. ' \
|
|
510
|
+
'Use Git::Repository#update_ref(name, commit) or, for a remote-tracking branch, ' \
|
|
511
|
+
'Git::Repository#update_ref("remotes/remote/name", commit) instead.'
|
|
512
|
+
)
|
|
79
513
|
if @remote
|
|
80
|
-
|
|
514
|
+
branch_repository.update_ref("remotes/#{@remote.name}/#{@name}", commit)
|
|
81
515
|
else
|
|
82
|
-
|
|
516
|
+
branch_repository.update_ref(@name, commit)
|
|
83
517
|
end
|
|
84
518
|
end
|
|
85
519
|
|
|
520
|
+
# Returns this branch as a single-element array containing its full refname
|
|
521
|
+
#
|
|
522
|
+
# @example Get branch as array
|
|
523
|
+
# git.branch('main').to_a #=> ['main']
|
|
524
|
+
#
|
|
525
|
+
# @return [Array<String>] a single-element array containing the full refname
|
|
526
|
+
#
|
|
86
527
|
def to_a
|
|
87
528
|
[@full]
|
|
88
529
|
end
|
|
89
530
|
|
|
531
|
+
# Returns the full refname of this branch as a string
|
|
532
|
+
#
|
|
533
|
+
# @example Get branch as string
|
|
534
|
+
# git.branch('main').to_s #=> 'main'
|
|
535
|
+
#
|
|
536
|
+
# @return [String] the full refname
|
|
537
|
+
#
|
|
90
538
|
def to_s
|
|
91
539
|
@full
|
|
92
540
|
end
|
|
93
541
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
542
|
+
# Regular expression for parsing branch refnames
|
|
543
|
+
#
|
|
544
|
+
# Matches full and short refnames, capturing an optional remote name and the
|
|
545
|
+
# branch name. Used internally to identify remote-tracking branches.
|
|
546
|
+
#
|
|
547
|
+
# @note This legacy string-constructor path does not resolve remote names
|
|
548
|
+
# containing `/`. Use {Git::Repository#branch_list} to build branch objects
|
|
549
|
+
# from remote-aware {Git::BranchInfo} values.
|
|
550
|
+
#
|
|
551
|
+
# @api private
|
|
552
|
+
#
|
|
104
553
|
BRANCH_NAME_REGEXP = %r{
|
|
105
554
|
^
|
|
106
|
-
# Optional 'refs/remotes/' at the
|
|
555
|
+
# Optional 'remotes/' or 'refs/remotes/' at the beginning to specify a remote tracking branch
|
|
107
556
|
# with a <remote_name>. <remote_name> is nil if not present.
|
|
108
557
|
(?:
|
|
109
558
|
(?:(?:refs/)?remotes/)(?<remote_name>[^/]+)/
|
|
@@ -112,32 +561,133 @@ module Git
|
|
|
112
561
|
$
|
|
113
562
|
}x
|
|
114
563
|
|
|
115
|
-
|
|
564
|
+
private
|
|
565
|
+
|
|
566
|
+
# Dispatches initialization to the appropriate strategy
|
|
567
|
+
#
|
|
568
|
+
# @param branch_info_or_name [Git::BranchInfo, String] branch info or name string
|
|
569
|
+
#
|
|
570
|
+
# @return [nil]
|
|
571
|
+
#
|
|
572
|
+
# @api private
|
|
573
|
+
#
|
|
574
|
+
def initialize_from_argument(branch_info_or_name)
|
|
575
|
+
if branch_info_or_name.is_a?(Git::BranchInfo)
|
|
576
|
+
initialize_from_branch_info(branch_info_or_name)
|
|
577
|
+
else
|
|
578
|
+
initialize_from_name(branch_info_or_name)
|
|
579
|
+
end
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
# Initialize from a BranchInfo object (preferred path)
|
|
583
|
+
#
|
|
584
|
+
# @param branch_info [Git::BranchInfo] the branch info
|
|
585
|
+
#
|
|
586
|
+
# @return [nil]
|
|
587
|
+
#
|
|
588
|
+
def initialize_from_branch_info(branch_info)
|
|
589
|
+
@name = branch_info.short_name
|
|
590
|
+
remote_name = branch_info.remote_name
|
|
591
|
+
# Git::Remote is deprecated too; silence it so one Git::Branch call emits one warning
|
|
592
|
+
@remote = remote_name ? Git::Deprecation.silence { Git::Remote.new(@base, remote_name) } : nil
|
|
593
|
+
@full = @remote ? "remotes/#{@remote.name}/#{@name}" : @name
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
# Initialize from a string name (legacy path for backward compatibility)
|
|
597
|
+
#
|
|
598
|
+
# @param name [String] the branch name
|
|
599
|
+
#
|
|
600
|
+
# @return [nil]
|
|
601
|
+
#
|
|
602
|
+
def initialize_from_name(name)
|
|
603
|
+
@full = name
|
|
604
|
+
@remote, @name = parse_name(name)
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
# Parses a full branch name into remote and short branch name components
|
|
608
|
+
#
|
|
609
|
+
# Strips an optional `remotes/` or `refs/remotes/` prefix. Only inputs that
|
|
610
|
+
# begin with one of those prefixes yield a remote object; all other inputs
|
|
611
|
+
# (including `'origin/master'`) are treated as local branch names with a
|
|
612
|
+
# `nil` remote.
|
|
116
613
|
#
|
|
117
|
-
#
|
|
118
|
-
#
|
|
119
|
-
#
|
|
614
|
+
# @example Local branches
|
|
615
|
+
# parse_name('master') #=> [nil, 'master']
|
|
616
|
+
# parse_name('origin/master') #=> [nil, 'origin/master']
|
|
120
617
|
#
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
# parse_name('master') #=> [
|
|
124
|
-
# parse_name('origin/master') #=> [nil, 'origin/master']
|
|
125
|
-
# parse_name('origin/master/v2') #=> [nil, 'origin/master']
|
|
618
|
+
# @example Remote-tracking branches
|
|
619
|
+
# parse_name('remotes/origin/master') #=> [#<Git::Remote 'origin'>, 'master']
|
|
620
|
+
# parse_name('refs/remotes/origin/master') #=> [#<Git::Remote 'origin'>, 'master']
|
|
126
621
|
#
|
|
127
|
-
#
|
|
128
|
-
#
|
|
129
|
-
#
|
|
130
|
-
#
|
|
131
|
-
#
|
|
622
|
+
# @param name [String] the full branch name to parse
|
|
623
|
+
#
|
|
624
|
+
# @return [Array(Git::Remote, String)] a two-element array; the first element is
|
|
625
|
+
# a {Git::Remote} for remote-tracking branches or `nil` for local branches,
|
|
626
|
+
# and the second element is the short branch name
|
|
132
627
|
#
|
|
133
|
-
# param [String] name branch full name.
|
|
134
|
-
# return [<Git::Remote,NilClass,String>] an Array containing the remote and branch names.
|
|
135
628
|
def parse_name(name)
|
|
136
629
|
# Expect this will always match
|
|
137
630
|
match = name.match(BRANCH_NAME_REGEXP)
|
|
138
|
-
|
|
631
|
+
remote_name = match[:remote_name]
|
|
632
|
+
# Git::Remote is deprecated too; silence it so one Git::Branch call emits one warning
|
|
633
|
+
remote = remote_name ? Git::Deprecation.silence { Git::Remote.new(@base, remote_name) } : nil
|
|
139
634
|
branch_name = match[:branch_name]
|
|
140
|
-
[
|
|
635
|
+
[remote, branch_name]
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
# Merges the given branch into this branch, then restores the original branch
|
|
639
|
+
#
|
|
640
|
+
# @param branch [String] the name of the branch to merge into this one
|
|
641
|
+
#
|
|
642
|
+
# @param message [String, nil] commit message for the merge commit
|
|
643
|
+
#
|
|
644
|
+
# @return [String] git's stdout from the final checkout back to the original branch
|
|
645
|
+
#
|
|
646
|
+
# @api private
|
|
647
|
+
#
|
|
648
|
+
def merge_into_this_branch(branch, message)
|
|
649
|
+
Git::Deprecation.warn(
|
|
650
|
+
'Git::Branch#merge(branch) is deprecated and will be removed in v6.0.0. ' \
|
|
651
|
+
'Use Git::Repository#merge_into(name, branch, message) instead. It takes an existing ' \
|
|
652
|
+
'local branch; for a remote-tracking branch, create a local branch from it first.'
|
|
653
|
+
)
|
|
654
|
+
# in_branch is deprecated too; silence it so one merge call emits one warning.
|
|
655
|
+
# The falsy block value makes in_branch hard-reset instead of committing.
|
|
656
|
+
Git::Deprecation.silence do
|
|
657
|
+
in_branch { branch_repository.merge(branch, message) && false }
|
|
658
|
+
end
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
# Merges this branch into the currently checked-out branch
|
|
662
|
+
#
|
|
663
|
+
# @return [String] git's stdout from the merge command
|
|
664
|
+
#
|
|
665
|
+
# @api private
|
|
666
|
+
#
|
|
667
|
+
def merge_into_current_branch
|
|
668
|
+
Git::Deprecation.warn(
|
|
669
|
+
'Git::Branch#merge with no arguments is deprecated and will be removed in v6.0.0. ' \
|
|
670
|
+
'Use Git::Repository#merge(name) instead.'
|
|
671
|
+
)
|
|
672
|
+
branch_repository.merge(@name)
|
|
673
|
+
end
|
|
674
|
+
|
|
675
|
+
# Creates the branch if it does not already exist, ignoring errors
|
|
676
|
+
#
|
|
677
|
+
# @return [nil]
|
|
678
|
+
#
|
|
679
|
+
def check_if_create
|
|
680
|
+
branch_repository.branch_new(@name)
|
|
681
|
+
rescue StandardError
|
|
682
|
+
nil
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
# @return [Git::Repository]
|
|
686
|
+
#
|
|
687
|
+
# @api private
|
|
688
|
+
#
|
|
689
|
+
def branch_repository
|
|
690
|
+
@base
|
|
141
691
|
end
|
|
142
692
|
end
|
|
143
693
|
end
|