git-multirepo 1.0.0.beta27 → 1.0.0.beta29
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/.gitignore +38 -38
- data/.rspec +2 -2
- data/Gemfile +4 -4
- data/Gemfile.lock +38 -38
- data/LICENSE +22 -22
- data/README.md +141 -141
- data/Rakefile +2 -2
- data/bin/multi +10 -10
- data/git-multirepo.gemspec +29 -29
- data/lib/commands.rb +11 -11
- data/lib/git-multirepo.rb +1 -3
- data/lib/info.rb +4 -4
- data/lib/multirepo/commands/add-command.rb +50 -51
- data/lib/multirepo/commands/branch-command.rb +59 -59
- data/lib/multirepo/commands/checkout-command.rb +139 -119
- data/lib/multirepo/commands/clone-command.rb +69 -69
- data/lib/multirepo/commands/command.rb +62 -62
- data/lib/multirepo/commands/fetch-command.rb +23 -23
- data/lib/multirepo/commands/init-command.rb +94 -51
- data/lib/multirepo/commands/install-command.rb +104 -87
- data/lib/multirepo/commands/open-command.rb +25 -25
- data/lib/multirepo/commands/remove-command.rb +48 -48
- data/lib/multirepo/commands/uninit-command.rb +19 -19
- data/lib/multirepo/commands/update-command.rb +53 -47
- data/lib/multirepo/config.rb +15 -15
- data/lib/multirepo/files/config-entry.rb +34 -34
- data/lib/multirepo/files/config-file.rb +33 -37
- data/lib/multirepo/files/lock-entry.rb +25 -25
- data/lib/multirepo/files/lock-file.rb +44 -39
- data/lib/multirepo/git/branch.rb +27 -27
- data/lib/multirepo/git/change.rb +10 -10
- data/lib/multirepo/git/commit.rb +18 -0
- data/lib/multirepo/git/git.rb +42 -42
- data/lib/multirepo/git/remote.rb +15 -15
- data/lib/multirepo/git/repo.rb +71 -66
- data/lib/multirepo/hooks/pre-commit-hook.rb +29 -25
- data/lib/multirepo/multirepo-exception.rb +5 -5
- data/lib/multirepo/utility/console.rb +51 -51
- data/lib/multirepo/utility/runner.rb +32 -32
- data/lib/multirepo/utility/utils.rb +66 -54
- data/resources/.gitconfig +3 -0
- data/resources/pre-commit +5 -5
- data/spec/integration/init_spec.rb +18 -22
- data/spec/spec_helper.rb +89 -89
- metadata +5 -7
- data/lib/multirepo/hooks/post-merge-hook.rb +0 -20
- data/lib/multirepo/hooks/prepare-commit-msg-hook.rb +0 -28
- data/resources/post-merge +0 -6
- data/resources/prepare-commit-msg +0 -6
data/lib/multirepo/config.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
require "singleton"
|
2
|
-
|
3
|
-
module MultiRepo
|
4
|
-
class Config
|
5
|
-
include Singleton
|
6
|
-
|
7
|
-
attr_accessor :verbose
|
8
|
-
@verbose = false
|
9
|
-
|
10
|
-
attr_accessor :running_git_hook
|
11
|
-
@running_git_hook = false
|
12
|
-
|
13
|
-
attr_accessor :git_executable
|
14
|
-
@git_executable = nil
|
15
|
-
end
|
1
|
+
require "singleton"
|
2
|
+
|
3
|
+
module MultiRepo
|
4
|
+
class Config
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
attr_accessor :verbose
|
8
|
+
@verbose = false
|
9
|
+
|
10
|
+
attr_accessor :running_git_hook
|
11
|
+
@running_git_hook = false
|
12
|
+
|
13
|
+
attr_accessor :git_executable
|
14
|
+
@git_executable = nil
|
15
|
+
end
|
16
16
|
end
|
@@ -1,35 +1,35 @@
|
|
1
|
-
require "securerandom"
|
2
|
-
|
3
|
-
require "multirepo/utility/console"
|
4
|
-
require "multirepo/git/repo"
|
5
|
-
|
6
|
-
module MultiRepo
|
7
|
-
class ConfigEntry
|
8
|
-
attr_accessor :id
|
9
|
-
attr_accessor :path
|
10
|
-
attr_accessor :url
|
11
|
-
attr_accessor :repo
|
12
|
-
|
13
|
-
def encode_with(coder)
|
14
|
-
coder["id"] = @id
|
15
|
-
coder["path"] = @path
|
16
|
-
coder["url"] = @url
|
17
|
-
end
|
18
|
-
|
19
|
-
def ==(entry)
|
20
|
-
entry_path = Pathname.new(entry.path)
|
21
|
-
self_path = Pathname.new(self.path)
|
22
|
-
entry_path.exist? && self_path.exist? && entry_path.realpath == self_path.realpath
|
23
|
-
end
|
24
|
-
|
25
|
-
def initialize(repo)
|
26
|
-
@id = SecureRandom.uuid
|
27
|
-
@path = repo.path
|
28
|
-
@url = repo.exists? ? repo.remote('origin').url : nil
|
29
|
-
end
|
30
|
-
|
31
|
-
def repo
|
32
|
-
Repo.new(path)
|
33
|
-
end
|
34
|
-
end
|
1
|
+
require "securerandom"
|
2
|
+
|
3
|
+
require "multirepo/utility/console"
|
4
|
+
require "multirepo/git/repo"
|
5
|
+
|
6
|
+
module MultiRepo
|
7
|
+
class ConfigEntry
|
8
|
+
attr_accessor :id
|
9
|
+
attr_accessor :path
|
10
|
+
attr_accessor :url
|
11
|
+
attr_accessor :repo
|
12
|
+
|
13
|
+
def encode_with(coder)
|
14
|
+
coder["id"] = @id
|
15
|
+
coder["path"] = @path
|
16
|
+
coder["url"] = @url
|
17
|
+
end
|
18
|
+
|
19
|
+
def ==(entry)
|
20
|
+
entry_path = Pathname.new(entry.path)
|
21
|
+
self_path = Pathname.new(self.path)
|
22
|
+
entry_path.exist? && self_path.exist? && entry_path.realpath == self_path.realpath
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(repo)
|
26
|
+
@id = SecureRandom.uuid
|
27
|
+
@path = repo.path
|
28
|
+
@url = repo.exists? ? repo.remote('origin').url : nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def repo
|
32
|
+
Repo.new(path)
|
33
|
+
end
|
34
|
+
end
|
35
35
|
end
|
@@ -1,38 +1,34 @@
|
|
1
|
-
require "fileutils"
|
2
|
-
require "pathname"
|
3
|
-
|
4
|
-
require_relative "config-entry"
|
5
|
-
|
6
|
-
module MultiRepo
|
7
|
-
class ConfigFile
|
8
|
-
FILE = Pathname.new(".multirepo")
|
9
|
-
|
10
|
-
def self.exists?
|
11
|
-
FILE.exist?
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.load
|
15
|
-
Psych.load(FILE.read)
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.save(entries)
|
19
|
-
File.write(FILE.to_s, Psych.dump(entries))
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.entry_exists?(entry)
|
23
|
-
load.any? { |e| e == entry }
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.add_entry(entry)
|
27
|
-
save(load.push(entry))
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.remove_entry(entry)
|
31
|
-
save(load.delete_if { |e| e == entry })
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.stage
|
35
|
-
Git.run_in_current_dir("add -A -f #{FILE.to_s}", Runner::Verbosity::NEVER_OUTPUT)
|
36
|
-
end
|
37
|
-
end
|
1
|
+
require "fileutils"
|
2
|
+
require "pathname"
|
3
|
+
|
4
|
+
require_relative "config-entry"
|
5
|
+
|
6
|
+
module MultiRepo
|
7
|
+
class ConfigFile
|
8
|
+
FILE = Pathname.new(".multirepo")
|
9
|
+
|
10
|
+
def self.exists?
|
11
|
+
FILE.exist?
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.load
|
15
|
+
Psych.load(FILE.read)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.save(entries)
|
19
|
+
File.write(FILE.to_s, Psych.dump(entries))
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.entry_exists?(entry)
|
23
|
+
load.any? { |e| e == entry }
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.add_entry(entry)
|
27
|
+
save(load.push(entry))
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.remove_entry(entry)
|
31
|
+
save(load.delete_if { |e| e == entry })
|
32
|
+
end
|
33
|
+
end
|
38
34
|
end
|
@@ -1,26 +1,26 @@
|
|
1
|
-
require "multirepo/utility/console"
|
2
|
-
require "multirepo/git/repo"
|
3
|
-
|
4
|
-
module MultiRepo
|
5
|
-
class LockEntry
|
6
|
-
attr_accessor :config_entry
|
7
|
-
attr_accessor :name
|
8
|
-
attr_accessor :id
|
9
|
-
attr_accessor :head
|
10
|
-
attr_accessor :branch
|
11
|
-
|
12
|
-
def encode_with(coder)
|
13
|
-
coder["name"] = @name
|
14
|
-
coder["id"] = @id
|
15
|
-
coder["head"] = @head
|
16
|
-
coder["branch"] = @branch
|
17
|
-
end
|
18
|
-
|
19
|
-
def initialize(config_entry)
|
20
|
-
@name = config_entry.repo.basename
|
21
|
-
@id = config_entry.id
|
22
|
-
@head = config_entry.repo.head_hash
|
23
|
-
@branch = config_entry.repo.current_branch
|
24
|
-
end
|
25
|
-
end
|
1
|
+
require "multirepo/utility/console"
|
2
|
+
require "multirepo/git/repo"
|
3
|
+
|
4
|
+
module MultiRepo
|
5
|
+
class LockEntry
|
6
|
+
attr_accessor :config_entry
|
7
|
+
attr_accessor :name
|
8
|
+
attr_accessor :id
|
9
|
+
attr_accessor :head
|
10
|
+
attr_accessor :branch
|
11
|
+
|
12
|
+
def encode_with(coder)
|
13
|
+
coder["name"] = @name
|
14
|
+
coder["id"] = @id
|
15
|
+
coder["head"] = @head
|
16
|
+
coder["branch"] = @branch
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(config_entry)
|
20
|
+
@name = config_entry.repo.basename
|
21
|
+
@id = config_entry.id
|
22
|
+
@head = config_entry.repo.head_hash
|
23
|
+
@branch = config_entry.repo.current_branch
|
24
|
+
end
|
25
|
+
end
|
26
26
|
end
|
@@ -1,40 +1,45 @@
|
|
1
|
-
require "pathname"
|
2
|
-
require "psych"
|
3
|
-
|
4
|
-
require "multirepo/git/git"
|
5
|
-
require_relative "lock-entry"
|
6
|
-
require_relative "config-file"
|
7
|
-
|
8
|
-
module MultiRepo
|
9
|
-
class LockFile
|
10
|
-
FILE = Pathname.new(".multirepo.lock")
|
11
|
-
|
12
|
-
def self.exists?
|
13
|
-
FILE.exist?
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.load
|
17
|
-
Psych.load(FILE.read)
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.update
|
21
|
-
config_entries = ConfigFile.load
|
22
|
-
lock_entries = config_entries.map { |c| LockEntry.new(c) }
|
23
|
-
|
24
|
-
File.
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
1
|
+
require "pathname"
|
2
|
+
require "psych"
|
3
|
+
|
4
|
+
require "multirepo/git/git"
|
5
|
+
require_relative "lock-entry"
|
6
|
+
require_relative "config-file"
|
7
|
+
|
8
|
+
module MultiRepo
|
9
|
+
class LockFile
|
10
|
+
FILE = Pathname.new(".multirepo.lock")
|
11
|
+
|
12
|
+
def self.exists?
|
13
|
+
FILE.exist?
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.load
|
17
|
+
Psych.load(FILE.read)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.update
|
21
|
+
config_entries = ConfigFile.load
|
22
|
+
lock_entries = config_entries.map { |c| LockEntry.new(c) }
|
23
|
+
|
24
|
+
old_content = File.read(FILE.to_s)
|
25
|
+
new_content = Psych.dump(lock_entries)
|
26
|
+
File.write(FILE.to_s, new_content)
|
27
|
+
|
28
|
+
return new_content != old_content
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.stage
|
32
|
+
Git.run_in_current_dir("add -A #{FILE.to_s}", Runner::Verbosity::OUTPUT_ON_ERROR)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.commit(message)
|
36
|
+
Git.run_in_current_dir("commit -m \"#{message}\" -o -- #{FILE.to_s}", Runner::Verbosity::OUTPUT_ON_ERROR)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.validate_components(line, components)
|
40
|
+
unless components.count == 2
|
41
|
+
raise MultiRepoException, "Wrong entry format in .multirepo.lock file: #{line}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
40
45
|
end
|
data/lib/multirepo/git/branch.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
|
-
require_relative "git"
|
2
|
-
|
3
|
-
module MultiRepo
|
4
|
-
class Branch
|
5
|
-
attr_accessor :name
|
6
|
-
|
7
|
-
def initialize(repo, name)
|
8
|
-
@repo = repo
|
9
|
-
@name = name
|
10
|
-
end
|
11
|
-
|
12
|
-
def exists?
|
13
|
-
lines = Git.run_in_working_dir(@repo.path, "branch", Runner::Verbosity::NEVER_OUTPUT).split("\n")
|
14
|
-
branch_names = lines.map { |line| line.tr("* ", "")}
|
15
|
-
branch_names.include?(@name)
|
16
|
-
end
|
17
|
-
|
18
|
-
def create(remote_tracking = false)
|
19
|
-
Git.run_in_working_dir(@repo.path, "branch #{@name}", Runner::Verbosity::OUTPUT_ON_ERROR)
|
20
|
-
Git.run_in_working_dir(@repo.path, "push -u origin #{name}", Runner::Verbosity::OUTPUT_ON_ERROR) if remote_tracking
|
21
|
-
end
|
22
|
-
|
23
|
-
def checkout
|
24
|
-
Git.run_in_working_dir(@repo.path, "checkout #{@name}", Runner::Verbosity::OUTPUT_ON_ERROR)
|
25
|
-
Git.last_command_succeeded
|
26
|
-
end
|
27
|
-
end
|
1
|
+
require_relative "git"
|
2
|
+
|
3
|
+
module MultiRepo
|
4
|
+
class Branch
|
5
|
+
attr_accessor :name
|
6
|
+
|
7
|
+
def initialize(repo, name)
|
8
|
+
@repo = repo
|
9
|
+
@name = name
|
10
|
+
end
|
11
|
+
|
12
|
+
def exists?
|
13
|
+
lines = Git.run_in_working_dir(@repo.path, "branch", Runner::Verbosity::NEVER_OUTPUT).split("\n")
|
14
|
+
branch_names = lines.map { |line| line.tr("* ", "")}
|
15
|
+
branch_names.include?(@name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create(remote_tracking = false)
|
19
|
+
Git.run_in_working_dir(@repo.path, "branch #{@name}", Runner::Verbosity::OUTPUT_ON_ERROR)
|
20
|
+
Git.run_in_working_dir(@repo.path, "push -u origin #{name}", Runner::Verbosity::OUTPUT_ON_ERROR) if remote_tracking
|
21
|
+
end
|
22
|
+
|
23
|
+
def checkout
|
24
|
+
Git.run_in_working_dir(@repo.path, "checkout #{@name}", Runner::Verbosity::OUTPUT_ON_ERROR)
|
25
|
+
Git.last_command_succeeded
|
26
|
+
end
|
27
|
+
end
|
28
28
|
end
|
data/lib/multirepo/git/change.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
module MultiRepo
|
2
|
-
class Change
|
3
|
-
attr_accessor :status
|
4
|
-
attr_accessor :path
|
5
|
-
|
6
|
-
def initialize(line)
|
7
|
-
@status = line[0...2].strip
|
8
|
-
@path = line[3..-1]
|
9
|
-
end
|
10
|
-
end
|
1
|
+
module MultiRepo
|
2
|
+
class Change
|
3
|
+
attr_accessor :status
|
4
|
+
attr_accessor :path
|
5
|
+
|
6
|
+
def initialize(line)
|
7
|
+
@status = line[0...2].strip
|
8
|
+
@path = line[3..-1]
|
9
|
+
end
|
10
|
+
end
|
11
11
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative "git"
|
2
|
+
|
3
|
+
module MultiRepo
|
4
|
+
class Commit
|
5
|
+
attr_accessor :ref
|
6
|
+
|
7
|
+
def initialize(repo, ref)
|
8
|
+
@repo = repo
|
9
|
+
@ref = ref
|
10
|
+
end
|
11
|
+
|
12
|
+
def is_merge?
|
13
|
+
lines = Git.run_in_working_dir(@repo.path, "cat-file -p #{@ref}", Runner::Verbosity::NEVER_OUTPUT).split("\n")
|
14
|
+
parents = lines.grep(/^parent /)
|
15
|
+
return parents.count > 1
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/multirepo/git/git.rb
CHANGED
@@ -1,43 +1,43 @@
|
|
1
|
-
require "multirepo/utility/runner"
|
2
|
-
require "multirepo/git/git"
|
3
|
-
require "multirepo/config"
|
4
|
-
|
5
|
-
module MultiRepo
|
6
|
-
class Git
|
7
|
-
class << self
|
8
|
-
attr_accessor :last_command_succeeded
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.is_inside_git_repo(path)
|
12
|
-
return false unless Dir.exist?("#{path}/.git")
|
13
|
-
return Git.run_in_working_dir(path, "rev-parse --is-inside-work-tree", Runner::Verbosity::NEVER_OUTPUT).strip == "true"
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.run_in_current_dir(git_command, verbosity)
|
17
|
-
full_command = "#{git_executable} #{git_command}"
|
18
|
-
run(full_command, verbosity)
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.run_in_working_dir(path, git_command, verbosity)
|
22
|
-
full_command = "#{git_executable} -C \"#{path}\" #{git_command}";
|
23
|
-
|
24
|
-
# True fix for the -C flag issue in pre-commit hook where the status command would
|
25
|
-
# fail to provide correct results if a pathspec was provided when performing a commit.
|
26
|
-
# http://thread.gmane.org/gmane.comp.version-control.git/263319/focus=263323
|
27
|
-
full_command = "sh -c 'unset $(git rev-parse --local-env-vars); #{full_command};'" if Config.instance.running_git_hook
|
28
|
-
|
29
|
-
run(full_command, verbosity)
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.run(full_command, verbosity)
|
33
|
-
Console.log_info(full_command) if Config.instance.verbose
|
34
|
-
result = Runner.run(full_command, verbosity)
|
35
|
-
@last_command_succeeded = Runner.last_command_succeeded
|
36
|
-
return result
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.git_executable
|
40
|
-
Config.instance.git_executable || "git"
|
41
|
-
end
|
42
|
-
end
|
1
|
+
require "multirepo/utility/runner"
|
2
|
+
require "multirepo/git/git"
|
3
|
+
require "multirepo/config"
|
4
|
+
|
5
|
+
module MultiRepo
|
6
|
+
class Git
|
7
|
+
class << self
|
8
|
+
attr_accessor :last_command_succeeded
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.is_inside_git_repo(path)
|
12
|
+
return false unless Dir.exist?("#{path}/.git")
|
13
|
+
return Git.run_in_working_dir(path, "rev-parse --is-inside-work-tree", Runner::Verbosity::NEVER_OUTPUT).strip == "true"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.run_in_current_dir(git_command, verbosity)
|
17
|
+
full_command = "#{git_executable} #{git_command}"
|
18
|
+
run(full_command, verbosity)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.run_in_working_dir(path, git_command, verbosity)
|
22
|
+
full_command = "#{git_executable} -C \"#{path}\" #{git_command}";
|
23
|
+
|
24
|
+
# True fix for the -C flag issue in pre-commit hook where the status command would
|
25
|
+
# fail to provide correct results if a pathspec was provided when performing a commit.
|
26
|
+
# http://thread.gmane.org/gmane.comp.version-control.git/263319/focus=263323
|
27
|
+
full_command = "sh -c 'unset $(git rev-parse --local-env-vars); #{full_command};'" if Config.instance.running_git_hook
|
28
|
+
|
29
|
+
run(full_command, verbosity)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.run(full_command, verbosity)
|
33
|
+
Console.log_info(full_command) if Config.instance.verbose
|
34
|
+
result = Runner.run(full_command, verbosity)
|
35
|
+
@last_command_succeeded = Runner.last_command_succeeded
|
36
|
+
return result
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.git_executable
|
40
|
+
Config.instance.git_executable || "git"
|
41
|
+
end
|
42
|
+
end
|
43
43
|
end
|