gitbroker 0.6.4 → 0.6.6
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/lib/gitbroker/branch_publisher.rb +9 -8
- data/lib/gitbroker/cli.rb +1 -0
- data/lib/gitbroker/git_context.rb +10 -0
- data/lib/gitbroker/neutralizer.rb +2 -2
- data/lib/gitbroker/task_runner.rb +4 -3
- data/lib/gitbroker/version.rb +1 -1
- data/lib/gitbroker/worktree.rb +6 -5
- data/plugin/.claude-plugin/plugin.json +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6ef35d4ad926d8851302c8ed0c6c5be6e0dd70f5207fac41d6fc4f77b02e46b0
|
|
4
|
+
data.tar.gz: 1c6afa6a9db5082116ecaab590dff94ce6d3ca1527d0459fc9ddf468d77c7abb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a784b73eceee92147c09a4a28de801bc40b3b6f93f2d2323c12dcad7c2e7da04901372fd6319464f3a494f4e82c3a12adfc653dcae329e22af3b130be6b54916
|
|
7
|
+
data.tar.gz: c9aace186cb3e2a3309182e791e53ad3c1553ee167e50951cdab83b35aad0eb19c2f0f1f1bc82d847e1936e11278708d27c6cda0017d7e9854b76630e19b7344
|
|
@@ -14,16 +14,17 @@ module Gitbroker
|
|
|
14
14
|
|
|
15
15
|
REF = %r{\A\w[\w./-]{0,200}\z}
|
|
16
16
|
|
|
17
|
-
def initialize(dir:, head_ref:, expected_sha:, base_ref:, runner: Runner.new)
|
|
17
|
+
def initialize(dir:, head_ref:, expected_sha:, base_ref:, remote: "origin", runner: Runner.new)
|
|
18
18
|
@dir = dir
|
|
19
19
|
@head_ref = head_ref.to_s
|
|
20
20
|
@expected = expected_sha.to_s
|
|
21
21
|
@base_ref = base_ref.to_s
|
|
22
|
+
@remote = remote.to_s
|
|
22
23
|
@runner = runner
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def publish!
|
|
26
|
-
return failed("No branch name to push.") unless valid_ref?(@head_ref) && valid_ref?(@base_ref)
|
|
27
|
+
return failed("No branch name to push.") unless valid_ref?(@head_ref) && valid_ref?(@base_ref) && valid_ref?(@remote)
|
|
27
28
|
return failed("No starting head to protect.") unless @expected.match?(/\A[0-9a-f]{7,40}\z/)
|
|
28
29
|
return failed("A rebase or merge is still in progress in the worktree: finish it first.") if in_progress?
|
|
29
30
|
return failed("The worktree has uncommitted changes.") unless git("status", "--porcelain").strip.empty?
|
|
@@ -31,16 +32,16 @@ module Gitbroker
|
|
|
31
32
|
head = git("rev-parse", "HEAD").strip
|
|
32
33
|
return Result.new(:nothing, "Nothing to push: the branch did not change.") if head.start_with?(@expected) || @expected.start_with?(head)
|
|
33
34
|
|
|
34
|
-
git("fetch", "--quiet",
|
|
35
|
-
unless @runner.git_success?(@dir, "merge-base", "--is-ancestor", "
|
|
36
|
-
return failed("The branch is not on top of
|
|
35
|
+
git("fetch", "--quiet", @remote, @base_ref)
|
|
36
|
+
unless @runner.git_success?(@dir, "merge-base", "--is-ancestor", "#{@remote}/#{@base_ref}", "HEAD")
|
|
37
|
+
return failed("The branch is not on top of #{@remote}/#{@base_ref}: nothing pushed.")
|
|
37
38
|
end
|
|
38
|
-
unless git("rev-list", "--merges", "#{@
|
|
39
|
+
unless git("rev-list", "--merges", "#{@remote}/#{@base_ref}..HEAD").strip.empty?
|
|
39
40
|
return failed("The branch contains merge commits; it must be a clean rebase: nothing pushed.")
|
|
40
41
|
end
|
|
41
42
|
|
|
42
|
-
git("push", lease_option,
|
|
43
|
-
Result.new(:pushed, "Pushed #{@head_ref} rebased onto
|
|
43
|
+
git("push", lease_option, @remote, "HEAD:refs/heads/#{@head_ref}")
|
|
44
|
+
Result.new(:pushed, "Pushed #{@head_ref} rebased onto #{@remote}/#{@base_ref}.")
|
|
44
45
|
rescue Error => e
|
|
45
46
|
failed("Push failed: #{e.message.lines.first.to_s.strip}")
|
|
46
47
|
end
|
data/lib/gitbroker/cli.rb
CHANGED
|
@@ -319,6 +319,7 @@ module Gitbroker
|
|
|
319
319
|
parser.on("--head-ref REF") { options[:head_ref] = _1 }
|
|
320
320
|
parser.on("--expected SHA") { options[:expected_sha] = _1 }
|
|
321
321
|
parser.on("--base REF") { options[:base_ref] = _1 }
|
|
322
|
+
parser.on("--remote NAME") { options[:remote] = _1 }
|
|
322
323
|
end.parse!(@argv)
|
|
323
324
|
result = BranchPublisher.new(**options).publish!
|
|
324
325
|
@out.puts result.message
|
|
@@ -61,6 +61,16 @@ module Gitbroker
|
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
+
# The remote that is `full_name` on GitHub (origin first when several are): a checkout found through its `github` remote
|
|
65
|
+
# has an origin that is something else, so fetching and pushing must name the remote, never assume origin.
|
|
66
|
+
def remote_for(dir, full_name)
|
|
67
|
+
wanted = full_name.to_s.downcase
|
|
68
|
+
matches = remote_urls(dir).select { |_name, url| RepoScanner.full_name_from(url).to_s.downcase == wanted }.map(&:first)
|
|
69
|
+
(matches.include?("origin") ? "origin" : matches.find { _1.match?(REMOTE_NAME) }) || "origin"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
REMOTE_NAME = /\A\w[\w.-]{0,60}\z/
|
|
73
|
+
|
|
64
74
|
def repository_from(remotes)
|
|
65
75
|
remotes.sort_by { |name, _url| name == "origin" ? 0 : 1 }.lazy.filter_map { |_name, url| RepoScanner.full_name_from(url) }.first
|
|
66
76
|
end
|
|
@@ -17,13 +17,13 @@ module Gitbroker
|
|
|
17
17
|
@runner = runner
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def neutralize!(dir, repo_path:, number:, base_ref:)
|
|
20
|
+
def neutralize!(dir, repo_path:, number:, base_ref:, remote: "origin")
|
|
21
21
|
raise Error, "Invalid base branch #{base_ref.inspect}" unless Worktree.valid_ref?(base_ref)
|
|
22
22
|
raise Error, "Invalid PR number #{number.inspect}" unless number.to_s.match?(/\A[1-9]\d{0,9}\z/)
|
|
23
23
|
|
|
24
24
|
@dir = File.realpath(dir)
|
|
25
25
|
base = "refs/gitbroker/base-#{number}"
|
|
26
|
-
@runner.git(repo_path, "fetch", "--quiet",
|
|
26
|
+
@runner.git(repo_path, "fetch", "--quiet", remote, "+refs/heads/#{base_ref}:#{base}")
|
|
27
27
|
|
|
28
28
|
removed = paths(@runner.git(@dir, "ls-files", "-z", "--", *REMOVE))
|
|
29
29
|
removed.each { delete(_1) }
|
|
@@ -58,7 +58,7 @@ module Gitbroker
|
|
|
58
58
|
cross_repository: task["cross_repository"] == true)
|
|
59
59
|
# Agents report real paths (macOS: /private/var, not /var); progress paths are matched against this form.
|
|
60
60
|
dir = File.realpath(dir)
|
|
61
|
-
restored = task["untrusted"] ? @neutralizer.neutralize!(dir, repo_path:, number: task["pr_number"], base_ref: base_ref(task)) : []
|
|
61
|
+
restored = task["untrusted"] ? @neutralizer.neutralize!(dir, repo_path:, number: task["pr_number"], base_ref: base_ref(task), remote: GitContext.remote_for(repo_path, task["repo"])) : []
|
|
62
62
|
task = task.merge("prompt" => prompt_for(task))
|
|
63
63
|
agent = Agents.for(@config, worktree: dir)
|
|
64
64
|
say(id, "#{task["kind"]} on #{task["repo"]}##{task["pr_number"]}: starting (#{agent.name}, #{task["mode"] == "terminal" ? "terminal" : "autonomous"})")
|
|
@@ -143,7 +143,8 @@ module Gitbroker
|
|
|
143
143
|
def publish_branch(task, outcome, dir)
|
|
144
144
|
return outcome unless publishes_branch?(task)
|
|
145
145
|
|
|
146
|
-
result = BranchPublisher.new(dir:, head_ref: task["head_ref"], expected_sha: task["head_sha"], base_ref: base_ref(task)
|
|
146
|
+
result = BranchPublisher.new(dir:, head_ref: task["head_ref"], expected_sha: task["head_sha"], base_ref: base_ref(task),
|
|
147
|
+
remote: GitContext.remote_for(dir, task["repo"])).publish!
|
|
147
148
|
say(task["task_id"], result.message)
|
|
148
149
|
return outcome unless result.failed?
|
|
149
150
|
|
|
@@ -155,7 +156,7 @@ module Gitbroker
|
|
|
155
156
|
return unless publishes_branch?(task)
|
|
156
157
|
|
|
157
158
|
[ RbConfig.ruby, ServiceInstaller.launcher, "publish-branch", "--dir", dir, "--head-ref", task["head_ref"].to_s,
|
|
158
|
-
"--expected", task["head_sha"].to_s, "--base", base_ref(task) ]
|
|
159
|
+
"--expected", task["head_sha"].to_s, "--base", base_ref(task), "--remote", GitContext.remote_for(dir, task["repo"]) ]
|
|
159
160
|
end
|
|
160
161
|
|
|
161
162
|
def publishes_branch?(task) = task["kind"] == "update_branch" && task["cross_repository"] != true && !task["read_only"]
|
data/lib/gitbroker/version.rb
CHANGED
data/lib/gitbroker/worktree.rb
CHANGED
|
@@ -24,7 +24,8 @@ module Gitbroker
|
|
|
24
24
|
validate!(full_name:, number:, head_sha:, kind:)
|
|
25
25
|
dir = File.join(@root, full_name.downcase.tr("/", "-"), "pr-#{number}-#{kind}")
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
remote = GitContext.remote_for(repo_path, full_name)
|
|
28
|
+
@runner.git(repo_path, "fetch", "--quiet", remote, "+refs/pull/#{number}/head:refs/gitbroker/pr-#{number}")
|
|
28
29
|
unless @runner.git_success?(repo_path, "cat-file", "-e", "#{head_sha}^{commit}")
|
|
29
30
|
raise Error, "Head #{head_sha[0, 7]} is not in the fetched PR; the PR may have moved. Start the task again from the card."
|
|
30
31
|
end
|
|
@@ -41,7 +42,7 @@ module Gitbroker
|
|
|
41
42
|
@runner.git(repo_path, "worktree", "add", "--quiet", *target, dir, head_sha)
|
|
42
43
|
end
|
|
43
44
|
if branch
|
|
44
|
-
cross_repository ? drop_upstream(repo_path, local) : track_upstream(repo_path, local, head_ref)
|
|
45
|
+
cross_repository ? drop_upstream(repo_path, local) : track_upstream(repo_path, local, head_ref, remote)
|
|
45
46
|
end
|
|
46
47
|
dir
|
|
47
48
|
end
|
|
@@ -93,11 +94,11 @@ module Gitbroker
|
|
|
93
94
|
raise Error, "Branch #{local} has commits that are not on the PR head; push or delete it, then start the task again."
|
|
94
95
|
end
|
|
95
96
|
|
|
96
|
-
def track_upstream(repo_path, local, head_ref)
|
|
97
|
+
def track_upstream(repo_path, local, head_ref, remote)
|
|
97
98
|
return unless self.class.valid_ref?(head_ref)
|
|
98
|
-
return unless @runner.git_success?(repo_path, "fetch", "--quiet",
|
|
99
|
+
return unless @runner.git_success?(repo_path, "fetch", "--quiet", remote, "+refs/heads/#{head_ref}:refs/remotes/#{remote}/#{head_ref}")
|
|
99
100
|
|
|
100
|
-
@runner.git(repo_path, "branch", "--quiet", "--set-upstream-to
|
|
101
|
+
@runner.git(repo_path, "branch", "--quiet", "--set-upstream-to=#{remote}/#{head_ref}", local)
|
|
101
102
|
end
|
|
102
103
|
|
|
103
104
|
def drop_upstream(repo_path, local)
|