braid 1.1.8 → 1.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/braid/command.rb +39 -15
- data/lib/braid/commands/add.rb +22 -12
- data/lib/braid/commands/diff.rb +27 -10
- data/lib/braid/commands/push.rb +33 -18
- data/lib/braid/commands/remove.rb +17 -4
- data/lib/braid/commands/setup.rb +12 -3
- data/lib/braid/commands/status.rb +17 -8
- data/lib/braid/commands/update.rb +47 -23
- data/lib/braid/commands/upgrade_config.rb +18 -4
- data/lib/braid/config.rb +28 -18
- data/lib/braid/main.rb +47 -33
- data/lib/braid/mirror.rb +70 -44
- data/lib/braid/operations.rb +235 -79
- data/lib/braid/operations_lite.rb +1 -1
- data/lib/braid/sorbet/fake_runtime.rb +22 -0
- data/lib/braid/version.rb +1 -1
- data/lib/braid.rb +2 -10
- metadata +46 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f38ff51ac35694b840f6dbc049ae5bf630fc3b6cf0e6e781431c5f9190f12df1
|
4
|
+
data.tar.gz: de2a9463583afbbb4d0a380ffbef2d68defb9b505f7aa27a684e5bc53c5e4579
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7cf1ec0a11f3f02788d41cb710e49263e3ea429d9e0db7ee856453a3616fc7d8350498e96401efed19f45afa90fe4ef61bdfa484568b5520c78cbd67988120d4
|
7
|
+
data.tar.gz: f7dd2378a8fcb3704db070f20a814c7c4f90956e34684ad22d68335ac3f0ed37ce268bd43ebcab92427ad017c74fa5ed4f5225bfda6cf7623c01643d2561ef23
|
data/lib/braid/command.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
module Braid
|
3
3
|
class Command
|
4
4
|
extend T::Sig
|
@@ -9,15 +9,13 @@ module Braid
|
|
9
9
|
extend Operations::VersionControl
|
10
10
|
include Operations::VersionControl
|
11
11
|
|
12
|
-
|
12
|
+
sig {void}
|
13
|
+
def run
|
13
14
|
verify_git_version!
|
14
15
|
check_working_dir!
|
15
|
-
|
16
|
-
klass = Commands.const_get(command.to_s)
|
17
|
-
klass.new.run(*args)
|
18
|
-
|
16
|
+
run_internal
|
19
17
|
rescue BraidError => error
|
20
|
-
handle_error(error)
|
18
|
+
Command.handle_error(error)
|
21
19
|
end
|
22
20
|
|
23
21
|
sig {params(error: BraidError).returns(T.noreturn)}
|
@@ -36,13 +34,19 @@ module Braid
|
|
36
34
|
puts "Braid: #{str}"
|
37
35
|
end
|
38
36
|
|
37
|
+
sig {void}
|
38
|
+
def initialize
|
39
|
+
@config = T.let(nil, T.nilable(Config))
|
40
|
+
end
|
41
|
+
|
39
42
|
sig {params(str: String).void}
|
40
43
|
def msg(str)
|
41
44
|
self.class.msg(str)
|
42
45
|
end
|
43
46
|
|
47
|
+
sig {returns(Config)}
|
44
48
|
def config
|
45
|
-
@config ||= Config.new(
|
49
|
+
@config ||= Config.new(mode: config_mode)
|
46
50
|
end
|
47
51
|
|
48
52
|
sig {returns(T::Boolean)}
|
@@ -57,23 +61,32 @@ module Braid
|
|
57
61
|
|
58
62
|
private
|
59
63
|
|
64
|
+
# TODO (typing): We could make this method abstract if our fake Sorbet
|
65
|
+
# runtime supported abstract methods.
|
66
|
+
sig {void}
|
67
|
+
def run_internal
|
68
|
+
raise InternalError, 'Command.run_internal not overridden'
|
69
|
+
end
|
70
|
+
|
60
71
|
sig {returns(Config::ConfigMode)}
|
61
72
|
def config_mode
|
62
73
|
Config::MODE_MAY_WRITE
|
63
74
|
end
|
64
75
|
|
76
|
+
sig {params(mirror: Mirror).void}
|
65
77
|
def setup_remote(mirror)
|
66
78
|
existing_force = Braid.force
|
67
79
|
begin
|
68
80
|
Braid.force = true
|
69
|
-
|
81
|
+
Commands::Setup.new(mirror.path).run
|
70
82
|
ensure
|
71
83
|
Braid.force = existing_force
|
72
84
|
end
|
73
85
|
end
|
74
86
|
|
75
|
-
|
76
|
-
|
87
|
+
sig {params(mirror: Mirror).void}
|
88
|
+
def clear_remote(mirror)
|
89
|
+
git.remote_rm(mirror.remote)
|
77
90
|
end
|
78
91
|
|
79
92
|
sig {returns(T::Boolean)}
|
@@ -82,12 +95,12 @@ module Braid
|
|
82
95
|
end
|
83
96
|
|
84
97
|
sig {void}
|
85
|
-
def
|
98
|
+
def verify_git_version!
|
86
99
|
git.require_version!(REQUIRED_GIT_VERSION)
|
87
100
|
end
|
88
101
|
|
89
102
|
sig {void}
|
90
|
-
def
|
103
|
+
def check_working_dir!
|
91
104
|
# If we aren't in a git repository at all, git.is_inside_worktree will
|
92
105
|
# propagate a "fatal: Not a git repository" ShellException.
|
93
106
|
unless git.is_inside_worktree
|
@@ -103,7 +116,12 @@ module Braid
|
|
103
116
|
git.ensure_clean!
|
104
117
|
end
|
105
118
|
|
106
|
-
|
119
|
+
sig {
|
120
|
+
type_parameters(:R).params(
|
121
|
+
blk: T.proc.returns(T.type_parameter(:R))
|
122
|
+
).returns(T.type_parameter(:R))
|
123
|
+
}
|
124
|
+
def with_reset_on_error(&blk)
|
107
125
|
bail_on_local_changes!
|
108
126
|
|
109
127
|
work_head = git.head
|
@@ -123,11 +141,16 @@ module Braid
|
|
123
141
|
git.add(CONFIG_FILE)
|
124
142
|
end
|
125
143
|
|
144
|
+
sig {params(mirror: Mirror, revision: T.nilable(String)).returns(String)}
|
126
145
|
def display_revision(mirror, revision = nil)
|
127
|
-
|
146
|
+
# This shouldn't be called while `mirror.revision` is nil in the middle of
|
147
|
+
# `braid add`. TODO (typing): Remove `T.must` if we restructure the code
|
148
|
+
# so `mirror.revision` is annotated as non-nil.
|
149
|
+
revision ||= T.must(mirror.revision)
|
128
150
|
"'#{revision[0, 7]}'"
|
129
151
|
end
|
130
152
|
|
153
|
+
sig {params(mirror: Mirror).returns(Operations::Git::ObjectID)}
|
131
154
|
def determine_repository_revision(mirror)
|
132
155
|
if mirror.tag
|
133
156
|
if use_local_cache?
|
@@ -147,6 +170,7 @@ module Braid
|
|
147
170
|
end
|
148
171
|
end
|
149
172
|
|
173
|
+
sig {params(mirror: Mirror, revision: T.nilable(Operations::Git::ObjectExpr)).returns(Operations::Git::ObjectID)}
|
150
174
|
def validate_new_revision(mirror, revision)
|
151
175
|
if revision.nil?
|
152
176
|
determine_repository_revision(mirror)
|
data/lib/braid/commands/add.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
module Braid
|
3
3
|
module Commands
|
4
4
|
class Add < Command
|
@@ -13,6 +13,7 @@ module Braid
|
|
13
13
|
# the mirror to the remote HEAD revision, but that's probably not what the
|
14
14
|
# user wants. It's much more likely that something is wrong and Braid
|
15
15
|
# should report an error.
|
16
|
+
sig {params(url: String).returns(T.nilable(String))}
|
16
17
|
def get_default_branch_name(url)
|
17
18
|
head_targets = []
|
18
19
|
# The `HEAD` parameter here doesn't appear to do an exact match (it
|
@@ -20,7 +21,7 @@ module Braid
|
|
20
21
|
# as `refs/remotes/origin/HEAD` in the unusual case where the repository
|
21
22
|
# contains its own remote-tracking branches), but it reduces the data we
|
22
23
|
# have to scan a bit.
|
23
|
-
git.ls_remote('--symref', url, 'HEAD').split("\n").each do |line|
|
24
|
+
git.ls_remote(['--symref', url, 'HEAD']).split("\n").each do |line|
|
24
25
|
m = /^ref: (.*)\tHEAD$/.match(line)
|
25
26
|
head_targets.push(m[1]) if m
|
26
27
|
end
|
@@ -30,28 +31,37 @@ module Braid
|
|
30
31
|
m[1]
|
31
32
|
end
|
32
33
|
|
33
|
-
|
34
|
+
sig {params(url: String, options: Mirror::Options).void}
|
35
|
+
def initialize(url, options)
|
36
|
+
@url = url
|
37
|
+
@options = options
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
sig {void}
|
43
|
+
def run_internal
|
34
44
|
with_reset_on_error do
|
35
|
-
if options
|
36
|
-
default_branch = get_default_branch_name(url)
|
45
|
+
if @options.branch.nil? && @options.tag.nil? && @options.revision.nil?
|
46
|
+
default_branch = get_default_branch_name(@url)
|
37
47
|
if default_branch.nil?
|
38
48
|
raise BraidError, <<-MSG
|
39
49
|
Failed to detect the default branch of the remote repository. Please specify
|
40
50
|
the branch you want to use via the --branch option.
|
41
51
|
MSG
|
42
52
|
end
|
43
|
-
options
|
53
|
+
@options.branch = default_branch
|
44
54
|
end
|
45
55
|
|
46
|
-
mirror = config.add_from_options(url, options)
|
56
|
+
mirror = config.add_from_options(@url, @options)
|
47
57
|
add_config_file
|
48
58
|
|
49
|
-
mirror.branch = nil if options
|
50
|
-
raise BraidError, 'Can not add mirror specifying both a revision and a tag' if options
|
59
|
+
mirror.branch = nil if @options.revision
|
60
|
+
raise BraidError, 'Can not add mirror specifying both a revision and a tag' if @options.revision && mirror.tag
|
51
61
|
|
52
62
|
branch_message = mirror.branch.nil? ? '' : " branch '#{mirror.branch}'"
|
53
63
|
tag_message = mirror.tag.nil? ? '' : " tag '#{mirror.tag}'"
|
54
|
-
revision_message = options
|
64
|
+
revision_message = @options.revision ? " at #{display_revision(mirror, @options.revision)}" : ''
|
55
65
|
msg "Adding mirror of '#{mirror.url}'#{branch_message}#{tag_message}#{revision_message}."
|
56
66
|
|
57
67
|
# these commands are explained in the subtree merge guide
|
@@ -61,7 +71,7 @@ MSG
|
|
61
71
|
setup_remote(mirror)
|
62
72
|
mirror.fetch
|
63
73
|
|
64
|
-
new_revision = validate_new_revision(mirror, options
|
74
|
+
new_revision = validate_new_revision(mirror, @options.revision)
|
65
75
|
target_item = mirror.upstream_item_for_revision(new_revision)
|
66
76
|
|
67
77
|
git.add_item_to_index(target_item, mirror.path, true)
|
@@ -73,7 +83,7 @@ MSG
|
|
73
83
|
git.commit("Add mirror '#{mirror.path}' at #{display_revision(mirror)}")
|
74
84
|
msg "Added mirror at #{display_revision(mirror)}."
|
75
85
|
|
76
|
-
clear_remote(mirror
|
86
|
+
clear_remote(mirror)
|
77
87
|
end
|
78
88
|
end
|
79
89
|
end
|
data/lib/braid/commands/diff.rb
CHANGED
@@ -1,14 +1,27 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
module Braid
|
3
3
|
module Commands
|
4
4
|
class Diff < Command
|
5
|
-
|
6
|
-
|
5
|
+
class Options < T::Struct
|
6
|
+
prop :git_diff_args, T::Array[String]
|
7
|
+
prop :keep, T::Boolean
|
8
|
+
end
|
9
|
+
|
10
|
+
sig {params(path: T.nilable(String), options: Options).void}
|
11
|
+
def initialize(path, options)
|
12
|
+
@path = path
|
13
|
+
@options = options
|
7
14
|
end
|
8
15
|
|
9
16
|
private
|
10
17
|
|
11
|
-
|
18
|
+
sig {void}
|
19
|
+
def run_internal
|
20
|
+
@path ? diff_one(@path) : diff_all
|
21
|
+
end
|
22
|
+
|
23
|
+
sig {void}
|
24
|
+
def diff_all
|
12
25
|
# We don't want "git diff" to invoke the pager once for each mirror.
|
13
26
|
# TODO: Invoke the default pager once for the entire output.
|
14
27
|
Operations::with_modified_environment({ 'GIT_PAGER' => ''}) do
|
@@ -16,31 +29,35 @@ module Braid
|
|
16
29
|
separator
|
17
30
|
msg "Diffing #{path}\n"
|
18
31
|
separator
|
19
|
-
show_diff(path
|
32
|
+
show_diff(path)
|
20
33
|
end
|
21
34
|
end
|
22
35
|
end
|
23
36
|
|
24
|
-
|
25
|
-
|
37
|
+
sig {params(path: String).void}
|
38
|
+
def diff_one(path)
|
39
|
+
show_diff(path)
|
26
40
|
end
|
27
41
|
|
42
|
+
sig {void}
|
28
43
|
def separator
|
29
44
|
puts "=======================================================\n"
|
30
45
|
end
|
31
46
|
|
32
|
-
|
47
|
+
sig {params(path: String).void}
|
48
|
+
def show_diff(path)
|
33
49
|
mirror = config.get!(path)
|
34
50
|
setup_remote(mirror)
|
35
51
|
mirror.fetch_base_revision_if_missing
|
36
52
|
|
37
53
|
# XXX: Warn if the user specifies file paths that are outside the
|
38
54
|
# mirror? Currently, they just won't match anything.
|
39
|
-
git.diff_to_stdout(
|
55
|
+
git.diff_to_stdout(mirror.diff_args(@options.git_diff_args))
|
40
56
|
|
41
|
-
clear_remote(mirror
|
57
|
+
clear_remote(mirror) unless @options.keep
|
42
58
|
end
|
43
59
|
|
60
|
+
sig {returns(Config::ConfigMode)}
|
44
61
|
def config_mode
|
45
62
|
Config::MODE_READ_ONLY
|
46
63
|
end
|
data/lib/braid/commands/push.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
require 'fileutils'
|
3
3
|
require 'tmpdir'
|
4
4
|
|
5
5
|
module Braid
|
6
6
|
class NoPushToTag < BraidError
|
7
|
+
sig {returns(String)}
|
7
8
|
def message
|
8
9
|
"mirror is based off a tag. Can not push to a tag: #{super}"
|
9
10
|
end
|
@@ -11,12 +12,26 @@ module Braid
|
|
11
12
|
|
12
13
|
module Commands
|
13
14
|
class Push < Command
|
14
|
-
|
15
|
-
|
15
|
+
class Options < T::Struct
|
16
|
+
prop :keep, T::Boolean
|
17
|
+
prop :branch, T.nilable(String)
|
18
|
+
end
|
19
|
+
|
20
|
+
sig {params(path: String, options: Options).void}
|
21
|
+
def initialize(path, options)
|
22
|
+
@path = path
|
23
|
+
@options = options
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
16
27
|
|
17
|
-
|
28
|
+
sig {void}
|
29
|
+
def run_internal
|
30
|
+
mirror = config.get!(@path)
|
18
31
|
|
19
|
-
|
32
|
+
branch = @options.branch || mirror.branch
|
33
|
+
|
34
|
+
raise NoPushToTag, @path unless branch
|
20
35
|
|
21
36
|
setup_remote(mirror)
|
22
37
|
mirror.fetch
|
@@ -24,14 +39,14 @@ module Braid
|
|
24
39
|
base_revision = determine_repository_revision(mirror)
|
25
40
|
unless mirror.merged?(base_revision)
|
26
41
|
msg 'Mirror is not up to date. Stopping.'
|
27
|
-
clear_remote(mirror
|
42
|
+
clear_remote(mirror) unless @options.keep
|
28
43
|
return
|
29
44
|
end
|
30
45
|
|
31
46
|
diff = mirror.diff
|
32
47
|
if diff.empty?
|
33
48
|
msg 'No local changes found. Stopping.'
|
34
|
-
clear_remote(mirror
|
49
|
+
clear_remote(mirror) unless @options.keep
|
35
50
|
return
|
36
51
|
end
|
37
52
|
local_mirror_item = git.get_tree_item('HEAD', mirror.path)
|
@@ -44,7 +59,8 @@ module Braid
|
|
44
59
|
end
|
45
60
|
clone_dir = Dir.tmpdir + "/braid_push.#{$$}"
|
46
61
|
Dir.mkdir(clone_dir)
|
47
|
-
|
62
|
+
# TODO (typing): Remove this `T.must` somehow?
|
63
|
+
remote_url = T.must(git.remote_url(mirror.remote))
|
48
64
|
if remote_url == mirror.cached_url
|
49
65
|
remote_url = mirror.url
|
50
66
|
elsif File.directory?(remote_url)
|
@@ -68,7 +84,7 @@ module Braid
|
|
68
84
|
File.open('.git/objects/info/alternates', 'wb') { |f|
|
69
85
|
f.puts(odb_paths)
|
70
86
|
}
|
71
|
-
git.fetch(remote_url, mirror.remote_ref)
|
87
|
+
git.fetch(remote_url, [mirror.remote_ref])
|
72
88
|
new_tree = git.make_tree_with_item(base_revision,
|
73
89
|
mirror.remote_path || '', local_mirror_item)
|
74
90
|
if git.require_version('2.27')
|
@@ -106,22 +122,21 @@ module Braid
|
|
106
122
|
# Update HEAD the same way git.checkout(base_revision) would, but
|
107
123
|
# don't populate the index or working tree (to save us the trouble of
|
108
124
|
# emptying them again before the git.read_tree).
|
109
|
-
git.update_ref('--no-deref', 'HEAD', base_revision)
|
110
|
-
git.
|
125
|
+
git.update_ref(['--no-deref', 'HEAD', base_revision])
|
126
|
+
git.read_tree_um(new_tree)
|
111
127
|
system('git commit -v')
|
112
128
|
msg "Pushing changes to remote branch #{branch}."
|
113
|
-
git.push(remote_url, "HEAD:refs/heads/#{branch}")
|
129
|
+
git.push([remote_url, "HEAD:refs/heads/#{branch}"])
|
114
130
|
end
|
115
131
|
FileUtils.rm_r(clone_dir)
|
116
132
|
|
117
|
-
clear_remote(mirror
|
133
|
+
clear_remote(mirror) unless @options.keep
|
118
134
|
end
|
119
|
-
end
|
120
135
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
136
|
+
sig {returns(Config::ConfigMode)}
|
137
|
+
def config_mode
|
138
|
+
Config::MODE_READ_ONLY # Surprisingly enough.
|
139
|
+
end
|
125
140
|
end
|
126
141
|
end
|
127
142
|
end
|
@@ -1,9 +1,22 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
module Braid
|
3
3
|
module Commands
|
4
4
|
class Remove < Command
|
5
|
-
|
6
|
-
|
5
|
+
class Options < T::Struct
|
6
|
+
prop :keep, T::Boolean
|
7
|
+
end
|
8
|
+
|
9
|
+
sig {params(path: String, options: Options).void}
|
10
|
+
def initialize(path, options)
|
11
|
+
@path = path
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
sig {void}
|
18
|
+
def run_internal
|
19
|
+
mirror = config.get!(@path)
|
7
20
|
|
8
21
|
with_reset_on_error do
|
9
22
|
msg "Removing mirror from '#{mirror.path}'."
|
@@ -13,7 +26,7 @@ module Braid
|
|
13
26
|
config.remove(mirror)
|
14
27
|
add_config_file
|
15
28
|
|
16
|
-
if options
|
29
|
+
if @options.keep
|
17
30
|
msg "Not removing remote '#{mirror.remote}'" if verbose?
|
18
31
|
elsif git.remote_url(mirror.remote)
|
19
32
|
msg "Removed remote '#{mirror.path}'" if verbose?
|
data/lib/braid/commands/setup.rb
CHANGED
@@ -1,13 +1,20 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
module Braid
|
3
3
|
module Commands
|
4
4
|
class Setup < Command
|
5
|
-
|
6
|
-
|
5
|
+
sig {params(path: T.nilable(String)).void}
|
6
|
+
def initialize(path = nil)
|
7
|
+
@path = path
|
7
8
|
end
|
8
9
|
|
9
10
|
private
|
10
11
|
|
12
|
+
sig {void}
|
13
|
+
def run_internal
|
14
|
+
@path ? setup_one(@path) : setup_all
|
15
|
+
end
|
16
|
+
|
17
|
+
sig {void}
|
11
18
|
def setup_all
|
12
19
|
msg 'Setting up all mirrors.'
|
13
20
|
config.mirrors.each do |path|
|
@@ -15,6 +22,7 @@ module Braid
|
|
15
22
|
end
|
16
23
|
end
|
17
24
|
|
25
|
+
sig {params(path: String).void}
|
18
26
|
def setup_one(path)
|
19
27
|
mirror = config.get!(path)
|
20
28
|
|
@@ -33,6 +41,7 @@ module Braid
|
|
33
41
|
git.remote_add(mirror.remote, url)
|
34
42
|
end
|
35
43
|
|
44
|
+
sig {returns(Config::ConfigMode)}
|
36
45
|
def config_mode
|
37
46
|
Config::MODE_READ_ONLY
|
38
47
|
end
|
@@ -1,23 +1,31 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
module Braid
|
3
3
|
module Commands
|
4
4
|
class Status < Command
|
5
|
-
|
6
|
-
|
5
|
+
sig {params(path: T.nilable(String)).void}
|
6
|
+
def initialize(path)
|
7
|
+
@path = path
|
7
8
|
end
|
8
9
|
|
9
10
|
private
|
10
11
|
|
11
|
-
|
12
|
+
sig {void}
|
13
|
+
def run_internal
|
14
|
+
@path ? status_one(@path) : status_all
|
15
|
+
end
|
16
|
+
|
17
|
+
sig {void}
|
18
|
+
def status_all
|
12
19
|
print "\n"
|
13
20
|
msg "Listing all mirrors.\n=======================================================\n"
|
14
21
|
config.mirrors.each do |path|
|
15
|
-
status_one(path
|
22
|
+
status_one(path)
|
16
23
|
end
|
17
24
|
print "\n"
|
18
25
|
end
|
19
26
|
|
20
|
-
|
27
|
+
sig {params(path: String).void}
|
28
|
+
def status_one(path)
|
21
29
|
mirror = config.get!(path)
|
22
30
|
setup_remote(mirror)
|
23
31
|
mirror.fetch
|
@@ -31,7 +39,7 @@ module Braid
|
|
31
39
|
print " [BRANCH=#{mirror.branch}]"
|
32
40
|
end
|
33
41
|
msg "Fetching new commits for '#{mirror.path}'." if verbose?
|
34
|
-
new_revision = validate_new_revision(mirror,
|
42
|
+
new_revision = validate_new_revision(mirror, nil)
|
35
43
|
print ' (Remote Modified)' if new_revision.to_s != mirror.base_revision.to_s
|
36
44
|
local_file_count = git.read_ls_files(mirror.path).split.size
|
37
45
|
if 0 == local_file_count
|
@@ -40,9 +48,10 @@ module Braid
|
|
40
48
|
print ' (Locally Modified)'
|
41
49
|
end
|
42
50
|
print "\n"
|
43
|
-
clear_remote(mirror
|
51
|
+
clear_remote(mirror)
|
44
52
|
end
|
45
53
|
|
54
|
+
sig {returns(Config::ConfigMode)}
|
46
55
|
def config_mode
|
47
56
|
Config::MODE_READ_ONLY
|
48
57
|
end
|
@@ -1,26 +1,47 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
module Braid
|
3
3
|
module Commands
|
4
4
|
class Update < Command
|
5
|
-
|
6
|
-
|
5
|
+
class Options < T::Struct
|
6
|
+
prop :branch, T.nilable(String)
|
7
|
+
prop :tag, T.nilable(String)
|
8
|
+
prop :revision, T.nilable(Operations::Git::ObjectExpr)
|
9
|
+
prop :head, T::Boolean
|
10
|
+
prop :keep, T::Boolean
|
7
11
|
end
|
8
12
|
|
9
|
-
|
13
|
+
sig {params(path: T.nilable(String), options: Options).void}
|
14
|
+
def initialize(path, options)
|
15
|
+
@path = path
|
16
|
+
@options = options
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
sig {void}
|
22
|
+
def run_internal
|
23
|
+
@path ? update_one(@path) : update_all
|
24
|
+
end
|
25
|
+
|
26
|
+
sig {void}
|
27
|
+
def update_all
|
28
|
+
# Maintain previous behavior of ignoring these options when updating all
|
29
|
+
# mirrors. TODO: Should we make it an error if the options were passed?
|
30
|
+
@options.revision = nil
|
31
|
+
@options.head = false
|
10
32
|
|
11
|
-
def update_all(options = {})
|
12
|
-
options.reject! { |k, v| %w(revision head).include?(k) }
|
13
33
|
msg 'Updating all mirrors.'
|
14
34
|
config.mirrors.each do |path|
|
15
35
|
bail_on_local_changes!
|
16
|
-
update_one(path
|
36
|
+
update_one(path)
|
17
37
|
end
|
18
38
|
end
|
19
39
|
|
20
|
-
|
40
|
+
sig {params(path: String).void}
|
41
|
+
def update_one(path)
|
21
42
|
bail_on_local_changes!
|
22
43
|
|
23
|
-
raise BraidError, "Do not specify --head option anymore. Please use '--branch MyBranch' to track a branch or '--tag MyTag' to track a branch" if options
|
44
|
+
raise BraidError, "Do not specify --head option anymore. Please use '--branch MyBranch' to track a branch or '--tag MyTag' to track a branch" if @options.head
|
24
45
|
|
25
46
|
mirror = config.get!(path)
|
26
47
|
|
@@ -31,16 +52,16 @@ module Braid
|
|
31
52
|
original_branch = mirror.branch
|
32
53
|
original_tag = mirror.tag
|
33
54
|
|
34
|
-
raise BraidError, 'Can not update mirror specifying both a revision and a tag' if options
|
35
|
-
raise BraidError, 'Can not update mirror specifying both a branch and a tag' if options
|
55
|
+
raise BraidError, 'Can not update mirror specifying both a revision and a tag' if @options.revision && @options.tag
|
56
|
+
raise BraidError, 'Can not update mirror specifying both a branch and a tag' if @options.branch && @options.tag
|
36
57
|
|
37
|
-
if options
|
38
|
-
mirror.tag = options
|
58
|
+
if @options.tag
|
59
|
+
mirror.tag = @options.tag
|
39
60
|
mirror.branch = nil
|
40
|
-
elsif options
|
61
|
+
elsif @options.branch
|
41
62
|
mirror.tag = nil
|
42
|
-
mirror.branch = options
|
43
|
-
elsif options
|
63
|
+
mirror.branch = @options.branch
|
64
|
+
elsif @options.revision
|
44
65
|
mirror.tag = nil
|
45
66
|
mirror.branch = nil
|
46
67
|
end
|
@@ -51,11 +72,14 @@ module Braid
|
|
51
72
|
msg "Fetching new commits for '#{mirror.path}'." if verbose?
|
52
73
|
mirror.fetch
|
53
74
|
|
54
|
-
new_revision = options
|
75
|
+
new_revision = @options.revision
|
55
76
|
begin
|
56
77
|
new_revision = validate_new_revision(mirror, new_revision)
|
57
78
|
rescue InvalidRevision
|
58
79
|
# Ignored as it means the revision matches expected
|
80
|
+
# This can only happen if new_revision was non-nil.
|
81
|
+
# TODO (typing): Untangle the logic and remote this `T.must`.
|
82
|
+
new_revision = T.must(new_revision)
|
59
83
|
end
|
60
84
|
|
61
85
|
from_desc =
|
@@ -68,19 +92,19 @@ module Braid
|
|
68
92
|
msg "Switching mirror '#{mirror.path}' to branch '#{mirror.branch}' from #{from_desc}."
|
69
93
|
elsif mirror.tag && original_tag != mirror.tag
|
70
94
|
msg "Switching mirror '#{mirror.path}' to tag '#{mirror.tag}' from #{from_desc}."
|
71
|
-
elsif options
|
72
|
-
msg "Switching mirror '#{mirror.path}' to revision '#{options
|
95
|
+
elsif @options.revision && original_revision != @options.revision
|
96
|
+
msg "Switching mirror '#{mirror.path}' to revision '#{@options.revision}' from #{from_desc}."
|
73
97
|
else
|
74
98
|
switching = false
|
75
99
|
end
|
76
100
|
|
77
101
|
if !switching &&
|
78
102
|
(
|
79
|
-
(options
|
80
|
-
(options
|
103
|
+
(@options.revision && was_locked && new_revision == mirror.base_revision) ||
|
104
|
+
(@options.revision.nil? && !was_locked && mirror.merged?(git.rev_parse(new_revision)))
|
81
105
|
)
|
82
106
|
msg "Mirror '#{mirror.path}' is already up to date."
|
83
|
-
clear_remote(mirror
|
107
|
+
clear_remote(mirror) unless @options.keep
|
84
108
|
return
|
85
109
|
end
|
86
110
|
|
@@ -120,7 +144,7 @@ module Braid
|
|
120
144
|
|
121
145
|
git.commit(commit_message)
|
122
146
|
msg "Updated mirror to #{display_revision(mirror)}."
|
123
|
-
clear_remote(mirror
|
147
|
+
clear_remote(mirror) unless @options.keep
|
124
148
|
end
|
125
149
|
end
|
126
150
|
end
|