evilchelu-braid 0.4.0 → 0.4.10
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/{License.txt → LICENSE} +1 -1
- data/README.rdoc +27 -0
- data/Rakefile +17 -4
- data/bin/braid +29 -24
- data/braid.gemspec +7 -7
- data/lib/braid.rb +15 -18
- data/lib/braid/command.rb +94 -44
- data/lib/braid/commands/add.rb +20 -31
- data/lib/braid/commands/diff.rb +4 -3
- data/lib/braid/commands/remove.rb +8 -12
- data/lib/braid/commands/setup.rb +13 -18
- data/lib/braid/commands/update.rb +47 -48
- data/lib/braid/config.rb +54 -101
- data/lib/braid/mirror.rb +181 -0
- data/lib/braid/operations.rb +229 -204
- data/{spec/braid_spec.rb → test/braid_test.rb} +1 -1
- data/test/config_test.rb +62 -0
- data/test/fixtures/shiny/README +3 -0
- data/test/fixtures/skit1.1/layouts/layout.liquid +219 -0
- data/test/fixtures/skit1.2/layouts/layout.liquid +221 -0
- data/test/fixtures/skit1/layouts/layout.liquid +219 -0
- data/test/fixtures/skit1/preview.png +0 -0
- data/test/integration/adding_test.rb +80 -0
- data/test/integration/updating_test.rb +87 -0
- data/test/integration_helper.rb +69 -0
- data/test/mirror_test.rb +118 -0
- data/test/operations_test.rb +74 -0
- data/test/test_helper.rb +15 -0
- metadata +30 -33
- data/History.txt +0 -4
- data/Manifest.txt +0 -32
- data/README.txt +0 -53
- data/config/hoe.rb +0 -68
- data/config/requirements.rb +0 -17
- data/lib/braid/exceptions.rb +0 -33
- data/lib/braid/version.rb +0 -9
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/setup.rb +0 -1585
- data/spec/config_spec.rb +0 -117
- data/spec/operations_spec.rb +0 -48
- data/spec/spec.opts +0 -3
- data/spec/spec_helper.rb +0 -11
- data/tasks/deployment.rake +0 -27
- data/tasks/environment.rake +0 -7
- data/tasks/rspec.rake +0 -32
- data/tasks/website.rake +0 -9
data/lib/braid/commands/diff.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
module Braid
|
2
2
|
module Commands
|
3
3
|
class Diff < Command
|
4
|
-
def run(
|
5
|
-
|
6
|
-
|
4
|
+
def run(path)
|
5
|
+
mirror = config.get!(path)
|
6
|
+
diff = mirror.diff
|
7
|
+
puts diff unless diff.empty?
|
7
8
|
end
|
8
9
|
end
|
9
10
|
end
|
@@ -1,25 +1,21 @@
|
|
1
1
|
module Braid
|
2
2
|
module Commands
|
3
3
|
class Remove < Command
|
4
|
-
def run(
|
5
|
-
|
4
|
+
def run(path)
|
5
|
+
mirror = config.get!(path)
|
6
6
|
|
7
|
-
|
8
|
-
params = config.get(mirror)
|
9
|
-
unless params
|
10
|
-
msg "Mirror '#{mirror}/' does not exist."
|
11
|
-
return
|
12
|
-
end
|
7
|
+
bail_on_local_changes!
|
13
8
|
|
14
|
-
|
9
|
+
with_reset_on_error do
|
10
|
+
msg "Removing mirror from '#{mirror.path}/'."
|
15
11
|
|
16
|
-
|
12
|
+
git.rm_r(mirror.path)
|
17
13
|
|
18
14
|
config.remove(mirror)
|
19
15
|
add_config_file
|
20
16
|
|
21
|
-
commit_message = "Remove mirror '#{mirror}/'
|
22
|
-
|
17
|
+
commit_message = "Remove mirror '#{mirror.path}/'"
|
18
|
+
git.commit(commit_message)
|
23
19
|
end
|
24
20
|
end
|
25
21
|
end
|
data/lib/braid/commands/setup.rb
CHANGED
@@ -1,36 +1,31 @@
|
|
1
1
|
module Braid
|
2
2
|
module Commands
|
3
3
|
class Setup < Command
|
4
|
-
def run(
|
5
|
-
|
4
|
+
def run(path = nil)
|
5
|
+
path ? setup_one(path) : setup_all
|
6
6
|
end
|
7
7
|
|
8
8
|
protected
|
9
9
|
def setup_all
|
10
10
|
msg "Setting up all mirrors."
|
11
|
-
config.mirrors.each do |
|
12
|
-
setup_one(
|
11
|
+
config.mirrors.each do |path|
|
12
|
+
setup_one(path)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def setup_one(
|
17
|
-
|
18
|
-
unless params
|
19
|
-
msg "Mirror '#{mirror}/' does not exist. Skipping."
|
20
|
-
return
|
21
|
-
end
|
16
|
+
def setup_one(path)
|
17
|
+
mirror = config.get!(path)
|
22
18
|
|
23
|
-
if
|
24
|
-
msg "Mirror '#{mirror}/' already has a remote. Skipping."
|
19
|
+
if git.remote_exists?(mirror.remote)
|
20
|
+
msg "Mirror '#{mirror.path}/' already has a remote. Skipping."
|
25
21
|
return
|
26
22
|
end
|
27
23
|
|
28
|
-
msg "Setting up remote for '#{mirror}/'."
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
invoke(:git_svn_init, params["local_branch"], params["remote"])
|
24
|
+
msg "Setting up remote for '#{mirror.path}/'."
|
25
|
+
unless mirror.type == "svn"
|
26
|
+
git.remote_add(mirror.remote, mirror.cached_url, mirror.branch)
|
27
|
+
else
|
28
|
+
git_svn.init(mirror.remote, mirror.url)
|
34
29
|
end
|
35
30
|
end
|
36
31
|
end
|
@@ -1,78 +1,77 @@
|
|
1
1
|
module Braid
|
2
2
|
module Commands
|
3
3
|
class Update < Command
|
4
|
-
def run(
|
5
|
-
|
4
|
+
def run(path, options = {})
|
5
|
+
bail_on_local_changes!
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
with_reset_on_error do
|
8
|
+
path ? update_one(path, options) : update_all(options)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
protected
|
13
|
-
def update_all
|
13
|
+
def update_all(options = {})
|
14
|
+
options.reject! { |k,v| %w(revision head).include?(k) }
|
14
15
|
msg "Updating all mirrors."
|
15
|
-
config.mirrors.each do |
|
16
|
-
update_one(
|
16
|
+
config.mirrors.each do |path|
|
17
|
+
update_one(path, options)
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
20
|
-
def update_one(
|
21
|
-
|
22
|
-
unless params
|
23
|
-
msg "Mirror '#{mirror}/' does not exist. Skipping."
|
24
|
-
return
|
25
|
-
end
|
26
|
-
local_branch = params["local_branch"]
|
27
|
-
|
28
|
-
if check_for_lock(params, options)
|
29
|
-
msg "Mirror '#{mirror}/' is locked to #{display_revision(params["type"], params["revision"])}. Skipping."
|
30
|
-
return
|
31
|
-
end
|
21
|
+
def update_one(path, options = {})
|
22
|
+
mirror = config.get!(path)
|
32
23
|
|
33
|
-
#
|
34
|
-
if
|
35
|
-
|
36
|
-
|
24
|
+
# check options for lock modification
|
25
|
+
if mirror.locked?
|
26
|
+
if options["head"]
|
27
|
+
msg "Unlocking mirror '#{mirror.path}/'."
|
28
|
+
mirror.lock = nil
|
29
|
+
elsif !options["revision"]
|
30
|
+
msg "Mirror '#{mirror.path}/' is locked to #{display_revision(mirror, mirror.lock)}. Skipping."
|
31
|
+
return
|
32
|
+
end
|
37
33
|
end
|
38
34
|
|
39
|
-
|
40
|
-
fetch_remote(params["type"], local_branch)
|
35
|
+
mirror.fetch
|
41
36
|
|
42
|
-
|
43
|
-
|
37
|
+
new_revision = validate_new_revision(mirror, options["revision"])
|
38
|
+
target_hash = determine_target_commit(mirror, new_revision)
|
44
39
|
|
45
|
-
|
46
|
-
|
47
|
-
msg "Mirror '#{mirror}/' is already up to date. Skipping."
|
48
|
-
update_revision(mirror, options["revision"])
|
40
|
+
if mirror.merged?(target_hash)
|
41
|
+
msg "Mirror '#{mirror.path}/' is already up to date. Skipping."
|
49
42
|
return
|
50
43
|
end
|
51
44
|
|
52
|
-
|
45
|
+
diff = mirror.diff if mirror.squashed? # get diff before setting revision
|
46
|
+
|
47
|
+
mirror.revision = new_revision
|
48
|
+
mirror.lock = new_revision if options["revision"]
|
49
|
+
config.update(mirror)
|
53
50
|
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
msg "Updating mirror '#{mirror.path}/'."
|
52
|
+
if mirror.squashed?
|
53
|
+
git.rm_r(mirror.path)
|
54
|
+
git.read_tree(target_hash, mirror.path)
|
55
|
+
unless diff.empty?
|
56
|
+
git.apply(diff, *(options["safe"] ? ["--reject"] : []))
|
57
|
+
end
|
57
58
|
else
|
58
|
-
|
59
|
+
git.merge_subtree(target_hash)
|
59
60
|
end
|
60
61
|
|
61
|
-
update_revision(mirror, options["revision"])
|
62
62
|
add_config_file
|
63
63
|
|
64
|
-
revision_message = " to " + (options["revision"] ? display_revision(
|
65
|
-
commit_message = "Update mirror '#{mirror}/'#{revision_message}
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
def check_for_lock(params, options)
|
71
|
-
params["revision"] && !options["revision"] && !options["head"]
|
72
|
-
end
|
64
|
+
revision_message = " to " + (options["revision"] ? display_revision(mirror) : "HEAD")
|
65
|
+
commit_message = "Update mirror '#{mirror.path}/'#{revision_message}"
|
66
|
+
git.commit(commit_message)
|
73
67
|
|
74
|
-
|
75
|
-
|
68
|
+
rescue Operations::ShellExecutionError => error
|
69
|
+
if options["safe"]
|
70
|
+
msg "Caught shell error. Breaking."
|
71
|
+
exit(0)
|
72
|
+
else
|
73
|
+
raise error
|
74
|
+
end
|
76
75
|
end
|
77
76
|
end
|
78
77
|
end
|
data/lib/braid/config.rb
CHANGED
@@ -3,26 +3,26 @@ require 'yaml/store'
|
|
3
3
|
|
4
4
|
module Braid
|
5
5
|
class Config
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
class PathAlreadyInUse < BraidError
|
7
|
+
def message
|
8
|
+
"path already in use: #{super}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
class MirrorDoesNotExist < BraidError
|
12
|
+
def message
|
13
|
+
"mirror does not exist: #{super}"
|
14
|
+
end
|
11
15
|
end
|
12
16
|
|
13
|
-
def
|
14
|
-
|
17
|
+
def initialize(config_file = CONFIG_FILE)
|
18
|
+
@db = YAML::Store.new(config_file)
|
19
|
+
end
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
raise Braid::Config::BranchIsRequired unless params["type"] == "svn" || params["branch"]
|
19
|
-
raise Braid::Config::MirrorNameIsRequired unless mirror
|
20
|
-
raise Braid::Config::UnknownMirrorType unless MIRROR_TYPES.include?(params["type"])
|
21
|
+
def add_from_options(url, options)
|
22
|
+
mirror = Mirror.new_from_options(url, options)
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
add(mirror, params)
|
25
|
-
[mirror, get(mirror)]
|
24
|
+
add(mirror)
|
25
|
+
mirror
|
26
26
|
end
|
27
27
|
|
28
28
|
def mirrors
|
@@ -31,118 +31,71 @@ module Braid
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
35
|
-
mirror = remove_trailing_slash(mirror)
|
36
|
-
@db.transaction do
|
37
|
-
raise Braid::Config::MirrorNameAlreadyInUse if @db[mirror]
|
38
|
-
@db[mirror] = params.merge("remote" => remove_trailing_slash(params["remote"]))
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def get(mirror)
|
43
|
-
mirror = remove_trailing_slash(mirror)
|
34
|
+
def get(path)
|
44
35
|
@db.transaction(true) do
|
45
|
-
@db[
|
36
|
+
if attributes = @db[path.to_s.sub(/\/$/, '')]
|
37
|
+
Mirror.new(path, attributes)
|
38
|
+
end
|
46
39
|
end
|
47
40
|
end
|
48
41
|
|
49
|
-
def get!(
|
50
|
-
|
51
|
-
raise
|
52
|
-
|
42
|
+
def get!(path)
|
43
|
+
mirror = get(path)
|
44
|
+
raise MirrorDoesNotExist, path unless mirror
|
45
|
+
mirror
|
53
46
|
end
|
54
47
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
mirror = @db.roots.detect { |mirror| @db[mirror]["remote"] == remote }
|
48
|
+
def add(mirror)
|
49
|
+
@db.transaction do
|
50
|
+
raise PathAlreadyInUse, mirror.path if @db[mirror.path]
|
51
|
+
write_mirror(mirror)
|
60
52
|
end
|
61
|
-
[mirror, get(mirror)]
|
62
53
|
end
|
63
54
|
|
64
55
|
def remove(mirror)
|
65
|
-
mirror = remove_trailing_slash(mirror)
|
66
56
|
@db.transaction do
|
67
|
-
@db.delete(mirror)
|
57
|
+
@db.delete(mirror.path)
|
68
58
|
end
|
69
59
|
end
|
70
60
|
|
71
|
-
def update(mirror
|
72
|
-
mirror = remove_trailing_slash(mirror)
|
61
|
+
def update(mirror)
|
73
62
|
@db.transaction do
|
74
|
-
raise
|
75
|
-
|
76
|
-
|
63
|
+
raise MirrorDoesNotExist, mirror.path unless @db[mirror.path]
|
64
|
+
@db.delete(mirror.path)
|
65
|
+
write_mirror(mirror)
|
77
66
|
end
|
78
67
|
end
|
79
68
|
|
80
|
-
def
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
@db[mirror] = params
|
69
|
+
def valid?
|
70
|
+
@db.transaction(true) do
|
71
|
+
!@db.roots.any? do |path|
|
72
|
+
@db[path]["url"].nil?
|
73
|
+
end
|
86
74
|
end
|
87
75
|
end
|
88
76
|
|
89
|
-
def
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
if options["rails_plugin"]
|
103
|
-
mirror = "vendor/plugins/#{mirror}"
|
77
|
+
def migrate!
|
78
|
+
@db.transaction do
|
79
|
+
@db.roots.each do |path|
|
80
|
+
attributes = @db[path]
|
81
|
+
if attributes["local_branch"]
|
82
|
+
attributes["url"] = attributes.delete("remote")
|
83
|
+
attributes["remote"] = attributes.delete("local_branch")
|
84
|
+
attributes["squashed"] = attributes.delete("squash")
|
85
|
+
attributes["lock"] = attributes["revision"] # so far this has always been true
|
86
|
+
end
|
87
|
+
@db[path] = clean_attributes(attributes)
|
88
|
+
end
|
104
89
|
end
|
105
|
-
|
106
|
-
squash = !options["full"]
|
107
|
-
|
108
|
-
[remove_trailing_slash(mirror), { "type" => type, "remote" => remote, "branch" => branch, "squash" => squash }]
|
109
90
|
end
|
110
91
|
|
111
92
|
private
|
112
|
-
def
|
113
|
-
|
93
|
+
def write_mirror(mirror)
|
94
|
+
@db[mirror.path] = clean_attributes(mirror.attributes)
|
114
95
|
end
|
115
96
|
|
116
|
-
def
|
117
|
-
|
118
|
-
path.sub(/\/$/, '')
|
119
|
-
end
|
120
|
-
|
121
|
-
def self.extract_type_from_path(path)
|
122
|
-
return nil unless path
|
123
|
-
path = remove_trailing_slash(path)
|
124
|
-
|
125
|
-
# check for git:// and svn:// URLs
|
126
|
-
path_scheme = path.split(":").first
|
127
|
-
return path_scheme if %w[git svn].include?(path_scheme)
|
128
|
-
|
129
|
-
return "svn" if path[-6..-1] == "/trunk"
|
130
|
-
return "git" if path[-4..-1] == ".git"
|
131
|
-
end
|
132
|
-
|
133
|
-
def self.extract_mirror_from_path(path)
|
134
|
-
return nil unless path
|
135
|
-
name = File.basename(path)
|
136
|
-
|
137
|
-
if File.extname(name) == ".git"
|
138
|
-
# strip .git
|
139
|
-
name[0..-5]
|
140
|
-
elsif name == "trunk"
|
141
|
-
# use parent
|
142
|
-
File.basename(File.dirname(path))
|
143
|
-
else
|
144
|
-
name
|
145
|
-
end
|
97
|
+
def clean_attributes(hash)
|
98
|
+
hash.reject { |k,v| v.nil? }
|
146
99
|
end
|
147
100
|
end
|
148
101
|
end
|
data/lib/braid/mirror.rb
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
module Braid
|
2
|
+
class Mirror
|
3
|
+
TYPES = %w(git svn)
|
4
|
+
ATTRIBUTES = %w(url remote type branch squashed revision lock)
|
5
|
+
|
6
|
+
class UnknownType < BraidError
|
7
|
+
def message
|
8
|
+
"unknown type: #{super}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
class CannotGuessType < BraidError
|
12
|
+
def message
|
13
|
+
"cannot guess type: #{super}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
class PathRequired < BraidError
|
17
|
+
def message
|
18
|
+
"path is required"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
include Operations::VersionControl
|
23
|
+
|
24
|
+
attr_reader :path, :attributes
|
25
|
+
|
26
|
+
def initialize(path, attributes = {})
|
27
|
+
@path = path.sub(/\/$/, '')
|
28
|
+
@attributes = attributes
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.new_from_options(url, options = {})
|
32
|
+
url.sub!(/\/$/, '')
|
33
|
+
|
34
|
+
branch = options["branch"] || "master"
|
35
|
+
|
36
|
+
if type = options["type"] || extract_type_from_url(url)
|
37
|
+
raise UnknownType, type unless TYPES.include?(type)
|
38
|
+
else
|
39
|
+
raise CannotGuessType, url
|
40
|
+
end
|
41
|
+
|
42
|
+
unless path = options["path"] || extract_path_from_url(url)
|
43
|
+
raise PathRequired
|
44
|
+
end
|
45
|
+
|
46
|
+
if options["rails_plugin"]
|
47
|
+
path = "vendor/plugins/#{path}"
|
48
|
+
end
|
49
|
+
|
50
|
+
remote = "braid/#{path}".gsub("_", '-') # stupid git svn changes all _ to ., weird
|
51
|
+
squashed = !options["full"]
|
52
|
+
branch = nil if type == "svn"
|
53
|
+
|
54
|
+
attributes = { "url" => url, "remote" => remote, "type" => type, "branch" => branch, "squashed" => squashed }
|
55
|
+
self.new(path, attributes)
|
56
|
+
end
|
57
|
+
|
58
|
+
def ==(comparison)
|
59
|
+
path == comparison.path && attributes == comparison.attributes
|
60
|
+
end
|
61
|
+
|
62
|
+
def type
|
63
|
+
# override Object#type
|
64
|
+
attributes["type"]
|
65
|
+
end
|
66
|
+
|
67
|
+
def locked?
|
68
|
+
!!lock
|
69
|
+
end
|
70
|
+
|
71
|
+
def squashed?
|
72
|
+
!!squashed
|
73
|
+
end
|
74
|
+
|
75
|
+
def merged?(commit)
|
76
|
+
# tip from spearce in #git:
|
77
|
+
# `test z$(git merge-base A B) = z$(git rev-parse --verify A)`
|
78
|
+
commit = git.rev_parse(commit)
|
79
|
+
if squashed?
|
80
|
+
!!base_revision && git.merge_base(commit, base_revision) == commit
|
81
|
+
else
|
82
|
+
git.merge_base(commit, "HEAD") == commit
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def diff
|
87
|
+
remote_hash = git.rev_parse("#{base_revision}:")
|
88
|
+
local_hash = git.tree_hash(path)
|
89
|
+
remote_hash != local_hash ? git.diff_tree(remote_hash, local_hash, path) : ""
|
90
|
+
end
|
91
|
+
|
92
|
+
def fetch
|
93
|
+
unless type == "svn"
|
94
|
+
init_or_fetch_local_cache
|
95
|
+
git.fetch(remote)
|
96
|
+
else
|
97
|
+
git_svn.fetch(remote)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def cached_url
|
102
|
+
if Braid::USE_LOCAL_CACHE
|
103
|
+
File.join(Braid::LOCAL_CACHE_DIR, url.gsub(/[\/:@]/, "_"))
|
104
|
+
else
|
105
|
+
url
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def init_or_fetch_local_cache
|
110
|
+
git_cache.init_or_fetch(url, cached_url)
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
def method_missing(name, *args)
|
115
|
+
if ATTRIBUTES.find { |attribute| name.to_s =~ /^(#{attribute})(=)?$/ }
|
116
|
+
unless $2
|
117
|
+
attributes[$1]
|
118
|
+
else
|
119
|
+
attributes[$1] = args[0]
|
120
|
+
end
|
121
|
+
else
|
122
|
+
raise NameError, "unknown attribute `#{name}'"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def base_revision
|
127
|
+
if revision
|
128
|
+
unless type == "svn"
|
129
|
+
git.rev_parse(revision)
|
130
|
+
else
|
131
|
+
git_svn.commit_hash(remote, revision)
|
132
|
+
end
|
133
|
+
else
|
134
|
+
inferred_revision
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def inferred_revision
|
139
|
+
local_commits = git.rev_list("HEAD", "-- #{path}").split("\n")
|
140
|
+
remote_hashes = git.rev_list("--pretty=format:\"%T\"", remote).split("commit ").map do |chunk|
|
141
|
+
chunk.split("\n", 2).map { |value| value.strip }
|
142
|
+
end
|
143
|
+
hash = nil
|
144
|
+
local_commits.each do |local_commit|
|
145
|
+
local_tree = git.tree_hash(path, local_commit)
|
146
|
+
if match = remote_hashes.find { |_, remote_tree| local_tree == remote_tree }
|
147
|
+
hash = match[0]
|
148
|
+
break
|
149
|
+
end
|
150
|
+
end
|
151
|
+
hash
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.extract_type_from_url(url)
|
155
|
+
return nil unless url
|
156
|
+
url.sub!(/\/$/, '')
|
157
|
+
|
158
|
+
# check for git:// and svn:// URLs
|
159
|
+
url_scheme = url.split(":").first
|
160
|
+
return url_scheme if TYPES.include?(url_scheme)
|
161
|
+
|
162
|
+
return "svn" if url[-6..-1] == "/trunk"
|
163
|
+
return "git" if url[-4..-1] == ".git"
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.extract_path_from_url(url)
|
167
|
+
return nil unless url
|
168
|
+
name = File.basename(url)
|
169
|
+
|
170
|
+
if File.extname(name) == ".git"
|
171
|
+
# strip .git
|
172
|
+
name[0..-5]
|
173
|
+
elsif name == "trunk"
|
174
|
+
# use parent
|
175
|
+
File.basename(File.dirname(url))
|
176
|
+
else
|
177
|
+
name
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|