git-multirepo 1.0.0.beta16 → 1.0.0.beta17

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +38 -38
  3. data/.rspec +2 -2
  4. data/Gemfile +4 -4
  5. data/Gemfile.lock +37 -37
  6. data/LICENSE +22 -22
  7. data/README.md +139 -137
  8. data/Rakefile +2 -2
  9. data/bin/multi +5 -5
  10. data/git-multirepo.gemspec +29 -29
  11. data/lib/commands.rb +12 -12
  12. data/lib/git-multirepo.rb +2 -1
  13. data/lib/info.rb +4 -4
  14. data/lib/multirepo/commands/add-command.rb +51 -44
  15. data/lib/multirepo/commands/branch-command.rb +52 -52
  16. data/lib/multirepo/commands/checkout-command.rb +84 -84
  17. data/lib/multirepo/commands/clone-command.rb +53 -53
  18. data/lib/multirepo/commands/command.rb +32 -36
  19. data/lib/multirepo/commands/edit-command.rb +21 -21
  20. data/lib/multirepo/commands/fetch-command.rb +23 -23
  21. data/lib/multirepo/commands/init-command.rb +53 -53
  22. data/lib/multirepo/commands/install-command.rb +68 -68
  23. data/lib/multirepo/commands/open-command.rb +25 -25
  24. data/lib/multirepo/commands/remove-command.rb +48 -48
  25. data/lib/multirepo/commands/uninit-command.rb +21 -20
  26. data/lib/multirepo/commands/update-command.rb +50 -50
  27. data/lib/multirepo/config.rb +12 -12
  28. data/lib/multirepo/files/config-entry.rb +37 -37
  29. data/lib/multirepo/files/config-file.rb +37 -37
  30. data/lib/multirepo/files/lock-entry.rb +25 -25
  31. data/lib/multirepo/files/lock-file.rb +39 -38
  32. data/lib/multirepo/git/branch.rb +27 -27
  33. data/lib/multirepo/git/change.rb +10 -10
  34. data/lib/multirepo/git/git.rb +38 -38
  35. data/lib/multirepo/git/remote.rb +15 -15
  36. data/lib/multirepo/git/repo.rb +66 -66
  37. data/lib/multirepo/hooks/post-merge-hook.rb +18 -0
  38. data/lib/multirepo/hooks/pre-commit-hook.rb +23 -23
  39. data/lib/multirepo/multirepo-exception.rb +5 -5
  40. data/lib/multirepo/utility/console.rb +51 -51
  41. data/lib/multirepo/utility/runner.rb +32 -32
  42. data/lib/multirepo/utility/utils.rb +41 -41
  43. data/resources/post-merge +6 -0
  44. data/resources/pre-commit +5 -5
  45. data/spec/integration/init_spec.rb +26 -22
  46. data/spec/spec_helper.rb +89 -89
  47. metadata +5 -3
data/Rakefile CHANGED
@@ -1,2 +1,2 @@
1
- require "bundler/gem_tasks"
2
-
1
+ require "bundler/gem_tasks"
2
+
data/bin/multi CHANGED
@@ -1,6 +1,6 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "claide"
4
- require "commands"
5
-
1
+ #!/usr/bin/env ruby
2
+
3
+ require "claide"
4
+ require "commands"
5
+
6
6
  MultiRepo::Command.run(ARGV)
@@ -1,29 +1,29 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'info'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = MultiRepo::NAME
8
- spec.version = MultiRepo::VERSION
9
- spec.authors = ["Michaël Fortin"]
10
- spec.email = ["fortinmike@irradiated.net"]
11
- spec.summary = %q{Track multiple Git repositories side-by-side}
12
- spec.description = MultiRepo::DESCRIPTION
13
- spec.homepage = "https://github.com/fortinmike/git-multirepo"
14
- spec.license = "MIT"
15
-
16
- spec.required_ruby_version = '~> 2.0'
17
- spec.files = `git ls-files -z`.split("\x0")
18
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
- spec.require_paths = ["lib"]
21
-
22
- spec.add_development_dependency "bundler", "~> 1.7"
23
- spec.add_development_dependency "rake", "~> 10.0"
24
- spec.add_development_dependency "rspec", "~> 3.1.0"
25
-
26
- spec.add_runtime_dependency "claide", "~> 0.8", ">= 0.8.0"
27
- spec.add_runtime_dependency "colored", "~> 1.2"
28
- spec.add_runtime_dependency "os", "~> 0.9.6"
29
- end
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'info'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = MultiRepo::NAME
8
+ spec.version = MultiRepo::VERSION
9
+ spec.authors = ["Michaël Fortin"]
10
+ spec.email = ["fortinmike@irradiated.net"]
11
+ spec.summary = %q{Track multiple Git repositories side-by-side}
12
+ spec.description = MultiRepo::DESCRIPTION
13
+ spec.homepage = "https://github.com/fortinmike/git-multirepo"
14
+ spec.license = "MIT"
15
+
16
+ spec.required_ruby_version = '~> 2.0'
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.7"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec", "~> 3.1.0"
25
+
26
+ spec.add_runtime_dependency "claide", "~> 0.8", ">= 0.8.0"
27
+ spec.add_runtime_dependency "colored", "~> 1.2"
28
+ spec.add_runtime_dependency "os", "~> 0.9.6"
29
+ end
data/lib/commands.rb CHANGED
@@ -1,13 +1,13 @@
1
- require_relative "multirepo/commands/command"
2
- require_relative "multirepo/commands/add-command"
3
- require_relative "multirepo/commands/branch-command"
4
- require_relative "multirepo/commands/checkout-command"
5
- require_relative "multirepo/commands/clone-command"
6
- require_relative "multirepo/commands/edit-command"
7
- require_relative "multirepo/commands/fetch-command"
8
- require_relative "multirepo/commands/init-command"
9
- require_relative "multirepo/commands/install-command"
10
- require_relative "multirepo/commands/open-command"
11
- require_relative "multirepo/commands/remove-command"
12
- require_relative "multirepo/commands/uninit-command"
1
+ require_relative "multirepo/commands/command"
2
+ require_relative "multirepo/commands/add-command"
3
+ require_relative "multirepo/commands/branch-command"
4
+ require_relative "multirepo/commands/checkout-command"
5
+ require_relative "multirepo/commands/clone-command"
6
+ require_relative "multirepo/commands/edit-command"
7
+ require_relative "multirepo/commands/fetch-command"
8
+ require_relative "multirepo/commands/init-command"
9
+ require_relative "multirepo/commands/install-command"
10
+ require_relative "multirepo/commands/open-command"
11
+ require_relative "multirepo/commands/remove-command"
12
+ require_relative "multirepo/commands/uninit-command"
13
13
  require_relative "multirepo/commands/update-command"
data/lib/git-multirepo.rb CHANGED
@@ -1 +1,2 @@
1
- require "multirepo/hooks/pre-commit-hook.rb"
1
+ require "multirepo/hooks/pre-commit-hook.rb"
2
+ require "multirepo/hooks/post-merge-hook.rb"
data/lib/info.rb CHANGED
@@ -1,5 +1,5 @@
1
- module MultiRepo
2
- NAME = "git-multirepo"
3
- VERSION = "1.0.0.beta16"
4
- DESCRIPTION = "Track multiple Git repositories side-by-side."
1
+ module MultiRepo
2
+ NAME = "git-multirepo"
3
+ VERSION = "1.0.0.beta17"
4
+ DESCRIPTION = "Track multiple Git repositories side-by-side."
5
5
  end
@@ -1,45 +1,52 @@
1
- require "multirepo/utility/console"
2
- require "multirepo/files/config-file"
3
-
4
- module MultiRepo
5
- class AddCommand < Command
6
- self.command = "add"
7
- self.summary = "Track an additional dependency with multirepo."
8
-
9
- def self.options
10
- [['[path]', 'The relative path to the new dependency (e.g. ../MyNewDependency)']].concat(super)
11
- end
12
-
13
- def initialize(argv)
14
- @path = argv.shift_argument
15
- super
16
- end
17
-
18
- def validate!
19
- super
20
- help! "You must specify a repository to add as a dependency" unless @path
21
- end
22
-
23
- def run
24
- validate_in_work_tree
25
- ensure_multirepo_initialized
26
- ensure_repo_exists
27
-
28
- entry = ConfigEntry.new(Repo.new(@path))
29
- if ConfigFile.entry_exists?(entry)
30
- Console.log_info("There is already an entry for '#{@path}' in the .multirepo file")
31
- else
32
- ConfigFile.add_entry(entry)
33
- ConfigFile.stage
34
- Console.log_step("Added '#{@path}' to the .multirepo file")
35
- end
36
- rescue MultiRepoException => e
37
- Console.log_error(e.message)
38
- end
39
-
40
- def ensure_repo_exists
41
- raise MultiRepoException, "There is no folder at path '#{@path}'" unless Dir.exists?(@path)
42
- raise MultiRepoException, "'#{@path}' is not a repository" unless Repo.new(@path).exists?
43
- end
44
- end
1
+ require "multirepo/utility/console"
2
+ require "multirepo/files/config-file"
3
+
4
+ module MultiRepo
5
+ class AddCommand < Command
6
+ self.command = "add"
7
+ self.summary = "Track an additional dependency with multirepo."
8
+
9
+ def self.options
10
+ [['[path]', 'The relative path to the new dependency (e.g. ../MyNewDependency)']].concat(super)
11
+ end
12
+
13
+ def initialize(argv)
14
+ @path = argv.shift_argument
15
+ super
16
+ end
17
+
18
+ def validate!
19
+ super
20
+ help! "You must specify a repository to add as a dependency" unless @path
21
+ end
22
+
23
+ def run
24
+ validate_in_work_tree
25
+ ensure_multirepo_initialized
26
+ ensure_repo_valid
27
+
28
+ entry = ConfigEntry.new(Repo.new(@path))
29
+ if ConfigFile.entry_exists?(entry)
30
+ Console.log_info("There is already an entry for '#{@path}' in the .multirepo file")
31
+ else
32
+ ConfigFile.add_entry(entry)
33
+ ConfigFile.stage
34
+ Console.log_step("Added '#{@path}' to the .multirepo file")
35
+ end
36
+ rescue MultiRepoException => e
37
+ Console.log_error(e.message)
38
+ end
39
+
40
+ def ensure_repo_valid
41
+ raise MultiRepoException, "The provided path is not a direct sibling of the main repository" unless validate_is_sibling_repo(@path)
42
+ raise MultiRepoException, "There is no folder at path '#{@path}'" unless Dir.exists?(@path)
43
+ raise MultiRepoException, "'#{@path}' is not a repository" unless Repo.new(@path).exists?
44
+ end
45
+
46
+ def validate_is_sibling_repo(path)
47
+ parent_dir = File.expand_path("..")
48
+ path = File.expand_path("..", path)
49
+ return parent_dir == path
50
+ end
51
+ end
45
52
  end
@@ -1,53 +1,53 @@
1
- require "multirepo/utility/console"
2
- require "multirepo/files/config-file"
3
-
4
- module MultiRepo
5
- class BranchCommand < Command
6
- self.command = "branch"
7
- self.summary = "Create and/or checkout a new branch for all repos."
8
-
9
- def self.options
10
- [
11
- ['[branch name]', 'The name of the branch to create and checkout.'],
12
- ['--force', 'Force creating the branch even if the repos contain uncommmitted changes.'],
13
- ['--no-track', 'Do not configure as a remote-tracking branch on creation.']
14
- ].concat(super)
15
- end
16
-
17
- def initialize(argv)
18
- @branch_name = argv.shift_argument
19
- @force = argv.flag?("force")
20
- @remote_tracking = !argv.flag?("no-track")
21
- super
22
- end
23
-
24
- def validate!
25
- super
26
- help! "You must specify a branch name" unless @branch_name
27
- end
28
-
29
- def run
30
- validate_in_work_tree
31
- ensure_multirepo_initialized
32
-
33
- Console.log_step("Branching and checking out #{@branch_name}...")
34
-
35
- main_repo = main_repo = Repo.new(".")
36
- repos = ConfigFile.load.map{ |entry| entry.repo }.push(main_repo)
37
-
38
- if !Utils.ensure_working_copies_clean(repos) && !@force
39
- raise MultiRepoException, "Can't branch because not all repos are clean"
40
- end
41
-
42
- repos.each do |repo|
43
- branch = repo.branch(@branch_name)
44
- branch.create(@remote_tracking) unless branch.exists?
45
- branch.checkout
46
- end
47
-
48
- Console.log_step("Done!")
49
- rescue MultiRepoException => e
50
- Console.log_error(e.message)
51
- end
52
- end
1
+ require "multirepo/utility/console"
2
+ require "multirepo/files/config-file"
3
+
4
+ module MultiRepo
5
+ class BranchCommand < Command
6
+ self.command = "branch"
7
+ self.summary = "Create and/or checkout a new branch for all repos."
8
+
9
+ def self.options
10
+ [
11
+ ['[branch name]', 'The name of the branch to create and checkout.'],
12
+ ['--force', 'Force creating the branch even if the repos contain uncommmitted changes.'],
13
+ ['--no-track', 'Do not configure as a remote-tracking branch on creation.']
14
+ ].concat(super)
15
+ end
16
+
17
+ def initialize(argv)
18
+ @branch_name = argv.shift_argument
19
+ @force = argv.flag?("force")
20
+ @remote_tracking = !argv.flag?("no-track")
21
+ super
22
+ end
23
+
24
+ def validate!
25
+ super
26
+ help! "You must specify a branch name" unless @branch_name
27
+ end
28
+
29
+ def run
30
+ validate_in_work_tree
31
+ ensure_multirepo_initialized
32
+
33
+ Console.log_step("Branching and checking out #{@branch_name}...")
34
+
35
+ main_repo = main_repo = Repo.new(".")
36
+ repos = ConfigFile.load.map{ |entry| entry.repo }.push(main_repo)
37
+
38
+ if !Utils.ensure_working_copies_clean(repos) && !@force
39
+ raise MultiRepoException, "Can't branch because not all repos are clean"
40
+ end
41
+
42
+ repos.each do |repo|
43
+ branch = repo.branch(@branch_name)
44
+ branch.create(@remote_tracking) unless branch.exists?
45
+ branch.checkout
46
+ end
47
+
48
+ Console.log_step("Done!")
49
+ rescue MultiRepoException => e
50
+ Console.log_error(e.message)
51
+ end
52
+ end
53
53
  end
@@ -1,85 +1,85 @@
1
- require "multirepo/utility/console"
2
-
3
- module MultiRepo
4
- class CheckoutCommand < Command
5
- self.command = "checkout"
6
- self.summary = "Checks out the specified commit or branch of the main repo and checks out matching versions of all dependencies."
7
-
8
- def self.options
9
- [
10
- ['[ref]', 'The main repo tag, branch or commit hash to checkout.'],
11
- ['--latest', 'Checkout the HEAD of each dependency branch (as recorded in the lock file) instead of the exact required commits.'],
12
- ['--exact', 'Checkout the exact specified ref for each repo, regardless of what\'s stored in the lock file.']
13
- ].concat(super)
14
- end
15
-
16
- def initialize(argv)
17
- @ref = argv.shift_argument
18
- @checkout_latest = argv.flag?("latest")
19
- @checkout_exact = argv.flag?("exact")
20
- super
21
- end
22
-
23
- def validate!
24
- super
25
- help! "You must specify a branch or commit id to checkout" unless @ref
26
- help! "You can't provide more than one operation modifier (--latest, --exact, etc.)" if @checkout_latest && @checkout_exact
27
- end
28
-
29
- def run
30
- validate_in_work_tree
31
- ensure_multirepo_initialized
32
-
33
- main_repo = Repo.new(".")
34
- initial_revision = main_repo.current_branch || main_repo.head_hash
35
-
36
- Console.log_step("Checking out #{@ref} and its dependencies...")
37
-
38
- unless main_repo.is_clean?
39
- raise MultiRepoException, "Can't checkout #{@ref} because the main repo contains uncommitted changes"
40
- end
41
-
42
- unless main_repo.checkout(@ref)
43
- raise MultiRepoException, "Couldn't perform checkout of main repo #{@ref}!"
44
- end
45
-
46
- Console.log_substep("Checked out main repo #{@ref}")
47
-
48
- unless LockFile.exists?
49
- main_repo.checkout(initial_revision)
50
- raise MultiRepoException, "The specified revision was not managed by multirepo. Checkout reverted."
51
- end
52
-
53
- unless Utils.ensure_dependencies_clean(ConfigFile.load)
54
- main_repo.checkout(initial_revision)
55
- raise MultiRepoException, "'#{e.path}' contains uncommitted changes. Checkout reverted."
56
- end
57
-
58
- config_entries = ConfigFile.load # Load the post-checkout config entries, which might be different than pre-checkout
59
- LockFile.load.each do |lock_entry|
60
- config_entry = config_entries.select{ |config_entry| config_entry.id == lock_entry.id }.first
61
-
62
- # First, make sure the repo exists on disk (in case the checked-out revision had an additional dependency)
63
- unless config_entry.repo.exists?
64
- Console.log_substep("Cloning missing dependency #{config_entry.path} from #{config_entry.url}")
65
- config_entry.repo.clone(config_entry.url)
66
- end
67
-
68
- # Find out the actual revision to checkout based on command flags
69
- revision = @checkout_latest ? lock_entry.branch : lock_entry.head
70
- revision = @checkout_exact ? @ref : revision
71
-
72
- # Checkout!
73
- if config_entry.repo.checkout(revision)
74
- Console.log_substep("Checked out #{lock_entry.name} #{revision}")
75
- else
76
- raise MultiRepoException, "Couldn't check out the appropriate version of dependency #{lock_entry.name}"
77
- end
78
- end
79
-
80
- Console.log_step("Done!")
81
- rescue MultiRepoException => e
82
- Console.log_error(e.message)
83
- end
84
- end
1
+ require "multirepo/utility/console"
2
+
3
+ module MultiRepo
4
+ class CheckoutCommand < Command
5
+ self.command = "checkout"
6
+ self.summary = "Checks out the specified commit or branch of the main repo and checks out matching versions of all dependencies."
7
+
8
+ def self.options
9
+ [
10
+ ['[ref]', 'The main repo tag, branch or commit hash to checkout.'],
11
+ ['--latest', 'Checkout the HEAD of each dependency branch (as recorded in the lock file) instead of the exact required commits.'],
12
+ ['--exact', 'Checkout the exact specified ref for each repo, regardless of what\'s stored in the lock file.']
13
+ ].concat(super)
14
+ end
15
+
16
+ def initialize(argv)
17
+ @ref = argv.shift_argument
18
+ @checkout_latest = argv.flag?("latest")
19
+ @checkout_exact = argv.flag?("exact")
20
+ super
21
+ end
22
+
23
+ def validate!
24
+ super
25
+ help! "You must specify a branch or commit id to checkout" unless @ref
26
+ help! "You can't provide more than one operation modifier (--latest, --exact, etc.)" if @checkout_latest && @checkout_exact
27
+ end
28
+
29
+ def run
30
+ validate_in_work_tree
31
+ ensure_multirepo_initialized
32
+
33
+ main_repo = Repo.new(".")
34
+ initial_revision = main_repo.current_branch || main_repo.head_hash
35
+
36
+ Console.log_step("Checking out #{@ref} and its dependencies...")
37
+
38
+ unless main_repo.is_clean?
39
+ raise MultiRepoException, "Can't checkout #{@ref} because the main repo contains uncommitted changes"
40
+ end
41
+
42
+ unless main_repo.checkout(@ref)
43
+ raise MultiRepoException, "Couldn't perform checkout of main repo #{@ref}!"
44
+ end
45
+
46
+ Console.log_substep("Checked out main repo #{@ref}")
47
+
48
+ unless LockFile.exists?
49
+ main_repo.checkout(initial_revision)
50
+ raise MultiRepoException, "The specified revision was not managed by multirepo. Checkout reverted."
51
+ end
52
+
53
+ unless Utils.ensure_dependencies_clean(ConfigFile.load)
54
+ main_repo.checkout(initial_revision)
55
+ raise MultiRepoException, "'#{e.path}' contains uncommitted changes. Checkout reverted."
56
+ end
57
+
58
+ config_entries = ConfigFile.load # Load the post-checkout config entries, which might be different than pre-checkout
59
+ LockFile.load.each do |lock_entry|
60
+ config_entry = config_entries.select{ |config_entry| config_entry.id == lock_entry.id }.first
61
+
62
+ # First, make sure the repo exists on disk (in case the checked-out revision had an additional dependency)
63
+ unless config_entry.repo.exists?
64
+ Console.log_substep("Cloning missing dependency #{config_entry.path} from #{config_entry.url}")
65
+ config_entry.repo.clone(config_entry.url)
66
+ end
67
+
68
+ # Find out the actual revision to checkout based on command flags
69
+ revision = @checkout_latest ? lock_entry.branch : lock_entry.head
70
+ revision = @checkout_exact ? @ref : revision
71
+
72
+ # Checkout!
73
+ if config_entry.repo.checkout(revision)
74
+ Console.log_substep("Checked out #{lock_entry.name} #{revision}")
75
+ else
76
+ raise MultiRepoException, "Couldn't check out the appropriate version of dependency #{lock_entry.name}"
77
+ end
78
+ end
79
+
80
+ Console.log_step("Done!")
81
+ rescue MultiRepoException => e
82
+ Console.log_error(e.message)
83
+ end
84
+ end
85
85
  end