dreamcat4-braid 0.50 → 0.52
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.
- data/bin/braid +10 -2
- data/braid.gemspec +2 -2
- data/lib/braid/commands/add.rb +17 -11
- data/lib/braid/commands/diff.rb +10 -3
- data/lib/braid/commands/remove.rb +17 -10
- data/lib/braid/commands/setup.rb +4 -0
- data/lib/braid/commands/update.rb +56 -51
- data/lib/braid/mirror.rb +11 -4
- data/lib/braid/operations.rb +66 -0
- metadata +1 -1
data/bin/braid
CHANGED
|
@@ -51,11 +51,11 @@ Main {
|
|
|
51
51
|
. braid add svn://remote/path --branch notmaster
|
|
52
52
|
TXT
|
|
53
53
|
|
|
54
|
-
mixin :argument_url, :option_type, :optional_path, :option_branch, :option_rails_plugin, :option_revision, :option_full, :option_verbose
|
|
54
|
+
mixin :argument_url, :option_type, :optional_path, :option_branch, :option_rails_plugin, :option_rails_gem, :option_revision, :option_full, :option_verbose
|
|
55
55
|
|
|
56
56
|
run {
|
|
57
57
|
Braid.verbose = verbose
|
|
58
|
-
Braid::Command.run(:add, url, { "type" => type, "path" => path, "branch" => branch, "rails_plugin" => rails_plugin, "revision" => revision, "full" => full })
|
|
58
|
+
Braid::Command.run(:add, url, { "type" => type, "path" => path, "branch" => branch, "rails_plugin" => rails_plugin, "rails_gem" => rails_gem, "revision" => revision, "full" => full })
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -196,6 +196,14 @@ Main {
|
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
mixin(:option_rails_gem) {
|
|
200
|
+
option(:rails_gem, :p) {
|
|
201
|
+
optional
|
|
202
|
+
desc 'added mirror is a Rails gem'
|
|
203
|
+
attr
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
199
207
|
mixin(:option_revision) {
|
|
200
208
|
option(:revision, :r) {
|
|
201
209
|
optional
|
data/braid.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = %q{braid}
|
|
3
|
-
s.version = "0.
|
|
3
|
+
s.version = "0.52"
|
|
4
4
|
|
|
5
5
|
s.specification_version = 2 if s.respond_to? :specification_version=
|
|
6
6
|
|
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
|
17
17
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "braid", "--main"]
|
|
18
18
|
s.require_paths = ["lib"]
|
|
19
19
|
s.rubyforge_project = %q{braid}
|
|
20
|
-
s.rubygems_version = %q{1.1
|
|
20
|
+
s.rubygems_version = %q{1.3.1}
|
|
21
21
|
s.summary = %q{A simple tool for tracking vendor branches in git.}
|
|
22
22
|
|
|
23
23
|
s.add_dependency(%q<main>, [">= 2.8.0"])
|
data/lib/braid/commands/add.rb
CHANGED
|
@@ -15,18 +15,24 @@ module Braid
|
|
|
15
15
|
# http://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html
|
|
16
16
|
|
|
17
17
|
setup_remote(mirror)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
|
|
19
|
+
if mirror.type == "git-clone"
|
|
20
|
+
gitclone.add_gitignore(mirror.path)
|
|
21
|
+
mirror.rspec_git.update
|
|
22
|
+
else
|
|
23
|
+
mirror.fetch
|
|
24
|
+
|
|
25
|
+
new_revision = validate_new_revision(mirror, options["revision"])
|
|
26
|
+
target_revision = determine_target_revision(mirror, new_revision)
|
|
27
|
+
|
|
28
|
+
unless mirror.squashed?
|
|
29
|
+
git.merge_ours(target_revision)
|
|
30
|
+
end
|
|
31
|
+
git.read_tree_prefix(target_revision, mirror.path)
|
|
32
|
+
|
|
33
|
+
mirror.revision = new_revision
|
|
34
|
+
mirror.lock = new_revision if options["revision"]
|
|
25
35
|
end
|
|
26
|
-
git.read_tree_prefix(target_revision, mirror.path)
|
|
27
|
-
|
|
28
|
-
mirror.revision = new_revision
|
|
29
|
-
mirror.lock = new_revision if options["revision"]
|
|
30
36
|
config.update(mirror)
|
|
31
37
|
add_config_file
|
|
32
38
|
|
data/lib/braid/commands/diff.rb
CHANGED
|
@@ -3,10 +3,17 @@ module Braid
|
|
|
3
3
|
class Diff < Command
|
|
4
4
|
def run(path)
|
|
5
5
|
mirror = config.get!(path)
|
|
6
|
-
|
|
6
|
+
if mirror.type == "git-clone"
|
|
7
|
+
unless system("cd #{mirror.path} && git diff")
|
|
8
|
+
msg "Error diffing \"#{path}\" in \"#{mirror.path}\""
|
|
9
|
+
exit 1
|
|
10
|
+
end
|
|
11
|
+
else
|
|
12
|
+
setup_remote(mirror)
|
|
7
13
|
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
diff = mirror.diff
|
|
15
|
+
puts diff unless diff.empty?
|
|
16
|
+
end
|
|
10
17
|
end
|
|
11
18
|
end
|
|
12
19
|
end
|
|
@@ -9,18 +9,25 @@ module Braid
|
|
|
9
9
|
with_reset_on_error do
|
|
10
10
|
msg "Removing mirror from '#{mirror.path}'."
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
if mirror.type == "git-clone"
|
|
13
|
+
gitclone.remove_gitignore(mirror.path)
|
|
14
|
+
FileUtils.rm_rf(mirror.path)
|
|
15
|
+
config.remove(mirror)
|
|
16
|
+
add_config_file
|
|
17
|
+
else
|
|
18
|
+
git.rm_r(mirror.path)
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
config.remove(mirror)
|
|
21
|
+
add_config_file
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
if options[:keep]
|
|
24
|
+
msg "Not removing remote '#{mirror.remote}'" if verbose?
|
|
25
|
+
elsif git.remote_url(mirror.remote)
|
|
26
|
+
msg "Removed remote '#{mirror.path}'" if verbose?
|
|
27
|
+
git.remote_rm mirror.remote
|
|
28
|
+
else
|
|
29
|
+
msg "Remote '#{mirror.remote}' not found, nothing to cleanup" if verbose?
|
|
30
|
+
end
|
|
24
31
|
end
|
|
25
32
|
|
|
26
33
|
commit_message = "Removed mirror '#{mirror.path}'"
|
data/lib/braid/commands/setup.rb
CHANGED
|
@@ -20,73 +20,78 @@ module Braid
|
|
|
20
20
|
|
|
21
21
|
def update_one(path, options = {})
|
|
22
22
|
mirror = config.get!(path)
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
revision_message = options["revision"] ? " to #{display_revision(mirror, options["revision"])}" : ""
|
|
25
25
|
msg "Updating mirror '#{mirror.path}'#{revision_message}."
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
if mirror.type == "git-clone"
|
|
28
|
+
mirror.rspec_git.update options["revision"]
|
|
29
|
+
else
|
|
30
|
+
|
|
31
|
+
# check options for lock modification
|
|
32
|
+
if mirror.locked?
|
|
33
|
+
if options["head"]
|
|
34
|
+
msg "Unlocking mirror '#{mirror.path}'." if verbose?
|
|
35
|
+
mirror.lock = nil
|
|
36
|
+
elsif !options["revision"]
|
|
37
|
+
msg "Mirror '#{mirror.path}' is locked to #{display_revision(mirror, mirror.lock)}. Use --head to force."
|
|
38
|
+
return
|
|
39
|
+
end
|
|
35
40
|
end
|
|
36
|
-
end
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
setup_remote(mirror)
|
|
43
|
+
msg "Fetching new commits for '#{mirror.path}'." if verbose?
|
|
44
|
+
mirror.fetch
|
|
41
45
|
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
new_revision = validate_new_revision(mirror, options["revision"])
|
|
47
|
+
target_revision = determine_target_revision(mirror, new_revision)
|
|
44
48
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if mirror.squashed?
|
|
51
|
-
diff = mirror.diff
|
|
52
|
-
base_revision = mirror.base_revision
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
mirror.revision = new_revision
|
|
56
|
-
mirror.lock = new_revision if options["revision"]
|
|
49
|
+
if mirror.merged?(target_revision)
|
|
50
|
+
msg "Mirror '#{mirror.path}' is already up to date."
|
|
51
|
+
return
|
|
52
|
+
end
|
|
57
53
|
|
|
58
|
-
msg "Merging in mirror '#{mirror.path}'." if verbose?
|
|
59
|
-
begin
|
|
60
54
|
if mirror.squashed?
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
55
|
+
diff = mirror.diff
|
|
56
|
+
base_revision = mirror.base_revision
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
mirror.revision = new_revision
|
|
60
|
+
mirror.lock = new_revision if options["revision"]
|
|
61
|
+
|
|
62
|
+
msg "Merging in mirror '#{mirror.path}'." if verbose?
|
|
63
|
+
begin
|
|
64
|
+
if mirror.squashed?
|
|
65
|
+
local_hash = git.rev_parse("HEAD")
|
|
66
|
+
if diff
|
|
67
|
+
base_hash = generate_tree_hash(mirror, base_revision)
|
|
68
|
+
else
|
|
69
|
+
base_hash = local_hash
|
|
70
|
+
end
|
|
71
|
+
remote_hash = generate_tree_hash(mirror, target_revision)
|
|
72
|
+
ENV["GITHEAD_#{local_hash}"] = "HEAD"
|
|
73
|
+
ENV["GITHEAD_#{remote_hash}"] = target_revision
|
|
74
|
+
git.merge_recursive(base_hash, local_hash, remote_hash)
|
|
64
75
|
else
|
|
65
|
-
|
|
76
|
+
git.merge_subtree(target_revision)
|
|
66
77
|
end
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
ENV["GITHEAD_#{remote_hash}"] = target_revision
|
|
70
|
-
git.merge_recursive(base_hash, local_hash, remote_hash)
|
|
71
|
-
else
|
|
72
|
-
git.merge_subtree(target_revision)
|
|
78
|
+
rescue Operations::MergeError => error
|
|
79
|
+
msg "Caught merge error. Breaking."
|
|
73
80
|
end
|
|
74
|
-
rescue Operations::MergeError => error
|
|
75
|
-
msg "Caught merge error. Breaking."
|
|
76
|
-
end
|
|
77
81
|
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
config.update(mirror)
|
|
83
|
+
add_config_file
|
|
80
84
|
|
|
81
|
-
|
|
85
|
+
commit_message = "Updated mirror '#{mirror.path}' to #{display_revision(mirror)}"
|
|
82
86
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
if error
|
|
88
|
+
File.open(".git/MERGE_MSG", 'w') { |f| f.puts(commit_message) }
|
|
89
|
+
return
|
|
90
|
+
end
|
|
87
91
|
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
git.commit(commit_message)
|
|
93
|
+
msg commit_message
|
|
94
|
+
end
|
|
90
95
|
end
|
|
91
96
|
|
|
92
97
|
def generate_tree_hash(mirror, revision)
|
data/lib/braid/mirror.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
require 'rspec_git.rb'
|
|
2
|
+
|
|
1
3
|
module Braid
|
|
2
4
|
class Mirror
|
|
3
|
-
TYPES = %w(git svn)
|
|
5
|
+
TYPES = %w(git svn git-clone)
|
|
4
6
|
ATTRIBUTES = %w(url remote type branch squashed revision lock)
|
|
5
7
|
|
|
6
8
|
class UnknownType < BraidError
|
|
@@ -21,11 +23,12 @@ module Braid
|
|
|
21
23
|
|
|
22
24
|
include Operations::VersionControl
|
|
23
25
|
|
|
24
|
-
attr_reader :path, :attributes
|
|
26
|
+
attr_reader :path, :attributes, :rspec_git
|
|
25
27
|
|
|
26
28
|
def initialize(path, attributes = {})
|
|
27
29
|
@path = path.sub(/\/$/, '')
|
|
28
30
|
@attributes = attributes
|
|
31
|
+
@rspec_git = RSpec::Git.new File.basename(@path) @path attributes["url"]
|
|
29
32
|
end
|
|
30
33
|
|
|
31
34
|
def self.new_from_options(url, options = {})
|
|
@@ -43,10 +46,14 @@ module Braid
|
|
|
43
46
|
raise PathRequired
|
|
44
47
|
end
|
|
45
48
|
|
|
46
|
-
if options["rails_plugin"]
|
|
49
|
+
if options["rails_plugin"] && ! path =~ /vendor\/plugins.*/
|
|
47
50
|
path = "vendor/plugins/#{path}"
|
|
48
51
|
end
|
|
49
52
|
|
|
53
|
+
if options["rails_gem"] && ! path =~ /vendor\/gems.*/
|
|
54
|
+
path = "vendor/gems/#{path}"
|
|
55
|
+
end
|
|
56
|
+
|
|
50
57
|
remote = "braid/#{path}".gsub("_", '-') # stupid git svn changes all _ to ., weird
|
|
51
58
|
squashed = !options["full"]
|
|
52
59
|
branch = nil if type == "svn"
|
|
@@ -152,7 +159,7 @@ module Braid
|
|
|
152
159
|
return url_scheme if TYPES.include?(url_scheme)
|
|
153
160
|
|
|
154
161
|
return "svn" if url[-6..-1] == "/trunk"
|
|
155
|
-
return "git" if url[-4..-1] == ".git"
|
|
162
|
+
return "git-clone" if url[-4..-1] == ".git"
|
|
156
163
|
end
|
|
157
164
|
|
|
158
165
|
def self.extract_path_from_url(url)
|
data/lib/braid/operations.rb
CHANGED
|
@@ -137,6 +137,72 @@ module Braid
|
|
|
137
137
|
end
|
|
138
138
|
end
|
|
139
139
|
|
|
140
|
+
class GitClone < Proxy
|
|
141
|
+
def in_rep_root_check
|
|
142
|
+
if ! File.exists?(".git")
|
|
143
|
+
raise("Not in root repository.")
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def add_gitignore(path)
|
|
148
|
+
# add mirror to .gitignore file
|
|
149
|
+
in_rep_root_check
|
|
150
|
+
if ! File.exists?(".gitignore")
|
|
151
|
+
f = File.new(".gitignore", "w+")
|
|
152
|
+
else
|
|
153
|
+
f = File.open( 'index', 'w+')
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
f.each { |line|
|
|
157
|
+
if line == path
|
|
158
|
+
path_ignored = line
|
|
159
|
+
end
|
|
160
|
+
}
|
|
161
|
+
if ! ignored
|
|
162
|
+
f.puts path
|
|
163
|
+
git.add(".gitignore")
|
|
164
|
+
end
|
|
165
|
+
f.close
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def remove_gitignore(path)
|
|
169
|
+
# remove mirror from .gitignore file
|
|
170
|
+
in_rep_root_check
|
|
171
|
+
if File.exists?(".gitignore")
|
|
172
|
+
f = File.open( 'index', 'w+')
|
|
173
|
+
|
|
174
|
+
f.each { |line|
|
|
175
|
+
if line == path
|
|
176
|
+
path_ignored = line
|
|
177
|
+
end
|
|
178
|
+
}
|
|
179
|
+
f.rewind
|
|
180
|
+
|
|
181
|
+
if path_ignored
|
|
182
|
+
date_str= Date.new.to_s
|
|
183
|
+
n = File.new(".gitignore-#{date_str}", "w+")
|
|
184
|
+
f.each { |line|
|
|
185
|
+
n.puts line unless line == path_ignored
|
|
186
|
+
}
|
|
187
|
+
n.close
|
|
188
|
+
end
|
|
189
|
+
f.close
|
|
190
|
+
File.rename( ".gitignore-#{date_str}", ".gitignore" )
|
|
191
|
+
git.add(".gitignore")
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
private
|
|
197
|
+
def command(name)
|
|
198
|
+
"#{self.class.command} #{name}"
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def git
|
|
202
|
+
GitClone.instance
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
140
206
|
class Git < Proxy
|
|
141
207
|
def commit(message, *args)
|
|
142
208
|
|