git-multirepo 1.0.0.beta51 → 1.0.0.beta52

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -2
  3. data/.gitbugtraq +3 -3
  4. data/.gitignore +38 -38
  5. data/.multirepo.meta +2 -2
  6. data/.rspec +2 -2
  7. data/.rubocop.yml +79 -79
  8. data/CHANGELOG.md +48 -43
  9. data/Gemfile +4 -4
  10. data/Gemfile.lock +42 -42
  11. data/LICENSE +22 -22
  12. data/README.md +178 -154
  13. data/Rakefile +1 -1
  14. data/bin/multi +11 -11
  15. data/docs/bug-repros/91565510-repro.sh +20 -20
  16. data/docs/git-multirepo-cheatsheet.docx +0 -0
  17. data/git-multirepo.gemspec +31 -31
  18. data/lib/git-multirepo.rb +3 -3
  19. data/lib/multirepo/commands/add-command.rb +51 -51
  20. data/lib/multirepo/commands/branch-command.rb +82 -82
  21. data/lib/multirepo/commands/checkout-command.rb +123 -121
  22. data/lib/multirepo/commands/clone-command.rb +68 -68
  23. data/lib/multirepo/commands/command.rb +86 -86
  24. data/lib/multirepo/commands/commands.rb +15 -15
  25. data/lib/multirepo/commands/do-command.rb +101 -101
  26. data/lib/multirepo/commands/graph-command.rb +43 -43
  27. data/lib/multirepo/commands/init-command.rb +121 -121
  28. data/lib/multirepo/commands/inspect-command.rb +48 -39
  29. data/lib/multirepo/commands/install-command.rb +153 -153
  30. data/lib/multirepo/commands/merge-command.rb +249 -249
  31. data/lib/multirepo/commands/open-command.rb +55 -55
  32. data/lib/multirepo/commands/remove-command.rb +48 -48
  33. data/lib/multirepo/commands/uninit-command.rb +18 -18
  34. data/lib/multirepo/commands/update-command.rb +112 -112
  35. data/lib/multirepo/config.rb +16 -16
  36. data/lib/multirepo/files/config-entry.rb +39 -39
  37. data/lib/multirepo/files/config-file.rb +46 -46
  38. data/lib/multirepo/files/lock-entry.rb +29 -29
  39. data/lib/multirepo/files/lock-file.rb +56 -56
  40. data/lib/multirepo/files/meta-file.rb +41 -41
  41. data/lib/multirepo/files/tracking-file.rb +9 -9
  42. data/lib/multirepo/files/tracking-files.rb +47 -47
  43. data/lib/multirepo/git/branch.rb +32 -32
  44. data/lib/multirepo/git/change.rb +11 -11
  45. data/lib/multirepo/git/commit.rb +7 -7
  46. data/lib/multirepo/git/git-runner.rb +56 -56
  47. data/lib/multirepo/git/git.rb +10 -10
  48. data/lib/multirepo/git/ref.rb +38 -38
  49. data/lib/multirepo/git/remote.rb +17 -17
  50. data/lib/multirepo/git/repo.rb +124 -124
  51. data/lib/multirepo/hooks/post-commit-hook.rb +23 -23
  52. data/lib/multirepo/hooks/pre-commit-hook.rb +35 -35
  53. data/lib/multirepo/info.rb +5 -5
  54. data/lib/multirepo/logic/dependency.rb +6 -6
  55. data/lib/multirepo/logic/merge-descriptor.rb +95 -95
  56. data/lib/multirepo/logic/node.rb +72 -72
  57. data/lib/multirepo/logic/performer.rb +55 -55
  58. data/lib/multirepo/logic/repo-selection.rb +25 -25
  59. data/lib/multirepo/logic/revision-selection.rb +15 -15
  60. data/lib/multirepo/logic/revision-selector.rb +23 -23
  61. data/lib/multirepo/multirepo-exception.rb +6 -6
  62. data/lib/multirepo/utility/console.rb +52 -52
  63. data/lib/multirepo/utility/popen-runner.rb +27 -27
  64. data/lib/multirepo/utility/system-runner.rb +14 -14
  65. data/lib/multirepo/utility/utils.rb +99 -99
  66. data/lib/multirepo/utility/verbosity.rb +6 -6
  67. data/resources/.gitconfig +2 -2
  68. data/resources/post-commit +6 -6
  69. data/resources/pre-commit +6 -6
  70. data/spec/integration/init_spec.rb +19 -19
  71. data/spec/spec_helper.rb +89 -89
  72. metadata +3 -3
@@ -1,31 +1,31 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "multirepo/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 = "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
- spec.add_runtime_dependency "terminal-table", "~> 1.4.5"
30
- spec.add_runtime_dependency "ruby-graphviz", "~> 1.2.1"
31
- end
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "multirepo/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 = "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
+ spec.add_runtime_dependency "terminal-table", "~> 1.4.5"
30
+ spec.add_runtime_dependency "ruby-graphviz", "~> 1.2.1"
31
+ end
data/lib/git-multirepo.rb CHANGED
@@ -1,3 +1,3 @@
1
- require "multirepo/utility/console"
2
- require "multirepo/hooks/pre-commit-hook"
3
- require "multirepo/hooks/post-commit-hook"
1
+ require "multirepo/utility/console"
2
+ require "multirepo/hooks/pre-commit-hook"
3
+ require "multirepo/hooks/post-commit-hook"
@@ -1,51 +1,51 @@
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
- ensure_in_work_tree
25
- ensure_multirepo_enabled
26
- ensure_repo_valid
27
-
28
- config_file = ConfigFile.new(".")
29
- entry = ConfigEntry.new(Repo.new(@path))
30
-
31
- if config_file.entry_exists?(entry)
32
- Console.log_info("There is already an entry for '#{@path}' in the .multirepo file")
33
- else
34
- config_file.add_entry(entry)
35
- Console.log_step("Added '#{@path}' to the .multirepo file")
36
- end
37
- end
38
-
39
- def ensure_repo_valid
40
- fail MultiRepoException, "The provided path is not a direct sibling of the main repository" unless validate_is_sibling_repo(@path)
41
- fail MultiRepoException, "There is no folder at path '#{@path}'" unless Dir.exist?(@path)
42
- fail MultiRepoException, "'#{@path}' is not a repository" unless Repo.new(@path).exists?
43
- end
44
-
45
- def validate_is_sibling_repo(path)
46
- parent_dir = File.expand_path("..")
47
- path = File.expand_path("..", path)
48
- return parent_dir == path
49
- end
50
- end
51
- 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
+ ensure_in_work_tree
25
+ ensure_multirepo_enabled
26
+ ensure_repo_valid
27
+
28
+ config_file = ConfigFile.new(".")
29
+ entry = ConfigEntry.new(Repo.new(@path))
30
+
31
+ if config_file.entry_exists?(entry)
32
+ Console.log_info("There is already an entry for '#{@path}' in the .multirepo file")
33
+ else
34
+ config_file.add_entry(entry)
35
+ Console.log_step("Added '#{@path}' to the .multirepo file")
36
+ end
37
+ end
38
+
39
+ def ensure_repo_valid
40
+ fail MultiRepoException, "The provided path is not a direct sibling of the main repository" unless validate_is_sibling_repo(@path)
41
+ fail MultiRepoException, "There is no folder at path '#{@path}'" unless Dir.exist?(@path)
42
+ fail MultiRepoException, "'#{@path}' is not a repository" unless Repo.new(@path).exists?
43
+ end
44
+
45
+ def validate_is_sibling_repo(path)
46
+ parent_dir = File.expand_path("..")
47
+ path = File.expand_path("..", path)
48
+ return parent_dir == path
49
+ end
50
+ end
51
+ end
@@ -1,82 +1,82 @@
1
- require "multirepo/utility/console"
2
- require "multirepo/git/git"
3
- require "multirepo/files/config-file"
4
- require "multirepo/files/tracking-files"
5
- require "multirepo/logic/performer"
6
-
7
- module MultiRepo
8
- class BranchCommand < Command
9
- self.command = "branch"
10
- self.summary = "Create and/or checkout a new branch for all repos."
11
-
12
- def self.options
13
- [
14
- ['<branch name>', 'The name of the branch to create and checkout.'],
15
- ['[--force]', 'Force creating the branch even if the repos contain uncommmitted changes.'],
16
- ['[--no-push]', 'Do not push the branch on creation.']
17
- ].concat(super)
18
- end
19
-
20
- def initialize(argv)
21
- @branch_name = argv.shift_argument
22
- @force = argv.flag?("force")
23
- @remote_tracking = argv.flag?("push", true)
24
- super
25
- end
26
-
27
- def validate!
28
- super
29
- help! "You must specify a branch name" unless @branch_name
30
- help! "Please provide a valid branch name" unless Git.valid_branch_name?(@branch_name)
31
- end
32
-
33
- def run
34
- ensure_in_work_tree
35
- ensure_multirepo_enabled
36
-
37
- Console.log_step("Branching...")
38
-
39
- main_repo = Repo.new(".")
40
-
41
- # Ensure the main repo is clean
42
- fail MultiRepoException, "Main repo is not clean; multi branch aborted" unless main_repo.clean?
43
-
44
- # Ensure dependencies are clean
45
- config_entries = ConfigFile.new(".").load_entries
46
- unless Utils.dependencies_clean?(config_entries)
47
- fail MultiRepoException, "Dependencies are not clean; multi branch aborted"
48
- end
49
-
50
- # Branch dependencies
51
- Performer.dependencies.each do |dependency|
52
- perform_branch(dependency.config_entry.repo)
53
- end
54
-
55
- # Branch the main repo
56
- perform_branch(main_repo)
57
-
58
- Console.log_step("Done!")
59
- end
60
-
61
- def perform_branch(repo)
62
- Console.log_substep("Branching '#{repo.path}' ...")
63
- Console.log_info("Creating and checking out branch #{@branch_name} ...")
64
-
65
- branch = repo.branch(@branch_name)
66
- branch.create unless branch.exists?
67
- branch.checkout
68
-
69
- if Utils.multirepo_enabled?(repo.path)
70
- Console.log_info("Updating and committing tracking files")
71
- tracking_files = TrackingFiles.new(repo.path)
72
- tracking_files.update
73
- tracking_files.commit("[multirepo] Post-branch tracking files update")
74
- end
75
-
76
- return unless @remote_tracking
77
-
78
- Console.log_info("Pushing #{@branch_name} to origin/#{@branch_name}")
79
- repo.branch(@branch_name).push
80
- end
81
- end
82
- end
1
+ require "multirepo/utility/console"
2
+ require "multirepo/git/git"
3
+ require "multirepo/files/config-file"
4
+ require "multirepo/files/tracking-files"
5
+ require "multirepo/logic/performer"
6
+
7
+ module MultiRepo
8
+ class BranchCommand < Command
9
+ self.command = "branch"
10
+ self.summary = "Create and/or checkout a new branch for all repos."
11
+
12
+ def self.options
13
+ [
14
+ ['<branch name>', 'The name of the branch to create and checkout.'],
15
+ ['[--force]', 'Force creating the branch even if there are uncommmitted changes.'],
16
+ ['[--no-push]', 'Do not push the branch on creation.']
17
+ ].concat(super)
18
+ end
19
+
20
+ def initialize(argv)
21
+ @branch_name = argv.shift_argument
22
+ @force = argv.flag?("force")
23
+ @remote_tracking = argv.flag?("push", true)
24
+ super
25
+ end
26
+
27
+ def validate!
28
+ super
29
+ help! "You must specify a branch name" unless @branch_name
30
+ help! "Please provide a valid branch name" unless Git.valid_branch_name?(@branch_name)
31
+ end
32
+
33
+ def run
34
+ ensure_in_work_tree
35
+ ensure_multirepo_enabled
36
+
37
+ Console.log_step("Branching...")
38
+
39
+ main_repo = Repo.new(".")
40
+
41
+ # Ensure the main repo is clean
42
+ fail MultiRepoException, "Main repo is not clean; multi branch aborted" unless main_repo.clean?
43
+
44
+ # Ensure dependencies are clean
45
+ config_entries = ConfigFile.new(".").load_entries
46
+ unless Utils.dependencies_clean?(config_entries)
47
+ fail MultiRepoException, "Dependencies are not clean; multi branch aborted"
48
+ end
49
+
50
+ # Branch dependencies
51
+ Performer.dependencies.each do |dependency|
52
+ perform_branch(dependency.config_entry.repo)
53
+ end
54
+
55
+ # Branch the main repo
56
+ perform_branch(main_repo)
57
+
58
+ Console.log_step("Done!")
59
+ end
60
+
61
+ def perform_branch(repo)
62
+ Console.log_substep("Branching '#{repo.path}' ...")
63
+ Console.log_info("Creating and checking out branch #{@branch_name} ...")
64
+
65
+ branch = repo.branch(@branch_name)
66
+ branch.create unless branch.exists?
67
+ branch.checkout
68
+
69
+ if Utils.multirepo_enabled?(repo.path)
70
+ Console.log_info("Updating and committing tracking files")
71
+ tracking_files = TrackingFiles.new(repo.path)
72
+ tracking_files.update
73
+ tracking_files.commit("[multirepo] Post-branch tracking files update")
74
+ end
75
+
76
+ return unless @remote_tracking
77
+
78
+ Console.log_info("Pushing #{@branch_name} to origin/#{@branch_name}")
79
+ repo.branch(@branch_name).push
80
+ end
81
+ end
82
+ end
@@ -1,121 +1,123 @@
1
- require "multirepo/utility/console"
2
- require "multirepo/utility/utils"
3
- require "multirepo/logic/revision-selector"
4
- require "multirepo/logic/performer"
5
-
6
- module MultiRepo
7
- class CheckoutCommand < Command
8
- self.command = "checkout"
9
- self.summary = "Checks out the specified commit or branch of the main repo and checks out matching versions of all dependencies."
10
-
11
- def self.options
12
- [
13
- ['<refname>', 'The main repo tag, branch or commit id to checkout.'],
14
- ['[--latest]', 'Checkout the HEAD of each dependency branch (as recorded in the lock file) instead of the exact required commits.'],
15
- ['[--exact]', 'Checkout the exact specified ref for each repo, regardless of what\'s stored in the lock file.']
16
- ].concat(super)
17
- end
18
-
19
- def initialize(argv)
20
- @ref_name = argv.shift_argument
21
- @checkout_latest = argv.flag?("latest")
22
- @checkout_exact = argv.flag?("exact")
23
- super
24
- end
25
-
26
- def validate!
27
- super
28
- help! "You must specify a branch or commit id to checkout" unless @ref_name
29
- unless Utils.only_one_true?(@checkout_latest, @checkout_exact)
30
- help! "You can't provide more than one operation modifier (--latest, --exact, etc.)"
31
- end
32
- end
33
-
34
- def run
35
- ensure_in_work_tree
36
-
37
- # Find out the checkout mode based on command-line options
38
- mode = RevisionSelector.mode_for_args(@checkout_latest, @checkout_exact)
39
-
40
- strategy_name = RevisionSelection.name_for_mode(mode)
41
- Console.log_step("Checking out #{@ref_name} and its dependencies using the '#{strategy_name}' strategy...")
42
-
43
- main_repo = Repo.new(".")
44
-
45
- unless proceed_if_merge_commit?(main_repo, @ref_name, mode)
46
- fail MultiRepoException, "Aborting checkout"
47
- end
48
-
49
- checkout_core(main_repo, mode)
50
-
51
- Console.log_step("Done!")
52
- end
53
-
54
- def checkout_core(main_repo, mode)
55
- initial_revision = main_repo.current_revision
56
- begin
57
- # Checkout first because the current ref might not be multirepo-enabled
58
- checkout_main_repo_step(main_repo)
59
- # Only then can we check for dependencies and make sure they are clean
60
- ensure_dependencies_clean_step
61
- rescue MultiRepoException => e
62
- Console.log_warning("Restoring working copy to #{initial_revision}")
63
- main_repo.checkout(initial_revision)
64
- raise e
65
- end
66
- dependencies_checkout_step(mode, @ref_name)
67
- end
68
-
69
- def checkout_main_repo_step(main_repo)
70
- Performer.perform_main_repo_checkout(main_repo, @ref_name)
71
- end
72
-
73
- def ensure_dependencies_clean_step
74
- unless Utils.dependencies_clean?(ConfigFile.new(".").load_entries)
75
- fail MultiRepoException, "Dependencies are not clean!"
76
- end
77
- end
78
-
79
- def dependencies_checkout_step(mode, ref_name = nil)
80
- Performer.dependencies.each do |dependency|
81
- # Find out the required dependency revision based on the checkout mode
82
- revision = RevisionSelector.revision_for_mode(mode, ref_name, dependency.lock_entry)
83
- perform_dependency_checkout(dependency.config_entry, revision)
84
- end
85
- end
86
-
87
- def proceed_if_merge_commit?(main_repo, ref_name, mode)
88
- return true unless main_repo.ref(ref_name).merge_commit?
89
-
90
- case mode
91
- when RevisionSelection::AS_LOCK
92
- Console.log_error("The specified ref is a merge commit and an \"as-lock\" checkout was requested.")
93
- Console.log_error("The resulting checkout would most probably not result in a valid project state.")
94
- return false
95
- when RevisionSelection::LATEST
96
- Console.log_warning("The specified ref is a merge commit and a \"latest\" checkout was requested.")
97
- Console.log_warning("The work branches recorded in the branch from which the merge was performed will be checked out.")
98
- end
99
-
100
- return true
101
- end
102
-
103
- def perform_dependency_checkout(config_entry, revision)
104
- dependency_name = config_entry.repo.basename
105
-
106
- # Make sure the repo exists on disk, and clone it if it doesn't
107
- # (in case the checked-out revision had an additional dependency)
108
- unless config_entry.repo.exists?
109
- Console.log_substep("Cloning missing dependency '#{config_entry.path}' from #{config_entry.url}")
110
- config_entry.repo.clone(config_entry.url)
111
- end
112
-
113
- # Checkout!
114
- if config_entry.repo.checkout(revision)
115
- Console.log_substep("Checked out #{dependency_name} '#{revision}'")
116
- else
117
- fail MultiRepoException, "Couldn't check out the appropriate version of dependency #{dependency_name}"
118
- end
119
- end
120
- end
121
- end
1
+ require "multirepo/utility/console"
2
+ require "multirepo/utility/utils"
3
+ require "multirepo/logic/revision-selector"
4
+ require "multirepo/logic/performer"
5
+
6
+ module MultiRepo
7
+ class CheckoutCommand < Command
8
+ self.command = "checkout"
9
+ self.summary = "Checks out the specified commit or branch of the main repo and checks out matching versions of all dependencies."
10
+
11
+ def self.options
12
+ [
13
+ ['<refname>', 'The main repo tag, branch or commit id to checkout.'],
14
+ ['[--latest]', 'Checkout the HEAD of each dependency branch (as recorded in the lock file) instead of the exact required commits.'],
15
+ ['[--exact]', 'Checkout the exact specified ref for each repo, regardless of what\'s stored in the lock file.'],
16
+ ['[--force]', 'Force checkout even if there are uncommmitted changes.']
17
+ ].concat(super)
18
+ end
19
+
20
+ def initialize(argv)
21
+ @ref_name = argv.shift_argument
22
+ @checkout_latest = argv.flag?("latest")
23
+ @checkout_exact = argv.flag?("exact")
24
+ @force = argv.flag?("force")
25
+ super
26
+ end
27
+
28
+ def validate!
29
+ super
30
+ help! "You must specify a branch or commit id to checkout" unless @ref_name
31
+ unless Utils.only_one_true?(@checkout_latest, @checkout_exact)
32
+ help! "You can't provide more than one operation modifier (--latest, --exact, etc.)"
33
+ end
34
+ end
35
+
36
+ def run
37
+ ensure_in_work_tree
38
+
39
+ # Find out the checkout mode based on command-line options
40
+ mode = RevisionSelector.mode_for_args(@checkout_latest, @checkout_exact)
41
+
42
+ strategy_name = RevisionSelection.name_for_mode(mode)
43
+ Console.log_step("Checking out #{@ref_name} and its dependencies using the '#{strategy_name}' strategy...")
44
+
45
+ main_repo = Repo.new(".")
46
+
47
+ unless proceed_if_merge_commit?(main_repo, @ref_name, mode)
48
+ fail MultiRepoException, "Aborting checkout"
49
+ end
50
+
51
+ checkout_core(main_repo, mode)
52
+
53
+ Console.log_step("Done!")
54
+ end
55
+
56
+ def checkout_core(main_repo, mode)
57
+ initial_revision = main_repo.current_revision
58
+ begin
59
+ # Checkout first because the current ref might not be multirepo-enabled
60
+ checkout_main_repo_step(main_repo)
61
+ # Only then can we check for dependencies and make sure they are clean
62
+ ensure_dependencies_clean_step if !@force
63
+ rescue MultiRepoException => e
64
+ Console.log_warning("Restoring working copy to #{initial_revision}")
65
+ main_repo.checkout(initial_revision)
66
+ raise e
67
+ end
68
+ dependencies_checkout_step(mode, @ref_name)
69
+ end
70
+
71
+ def checkout_main_repo_step(main_repo)
72
+ Performer.perform_main_repo_checkout(main_repo, @ref_name, @force)
73
+ end
74
+
75
+ def ensure_dependencies_clean_step
76
+ unless Utils.dependencies_clean?(ConfigFile.new(".").load_entries)
77
+ fail MultiRepoException, "Dependencies are not clean!"
78
+ end
79
+ end
80
+
81
+ def dependencies_checkout_step(mode, ref_name = nil)
82
+ Performer.dependencies.each do |dependency|
83
+ # Find out the required dependency revision based on the checkout mode
84
+ revision = RevisionSelector.revision_for_mode(mode, ref_name, dependency.lock_entry)
85
+ perform_dependency_checkout(dependency.config_entry, revision)
86
+ end
87
+ end
88
+
89
+ def proceed_if_merge_commit?(main_repo, ref_name, mode)
90
+ return true unless main_repo.ref(ref_name).merge_commit?
91
+
92
+ case mode
93
+ when RevisionSelection::AS_LOCK
94
+ Console.log_error("The specified ref is a merge commit and an \"as-lock\" checkout was requested.")
95
+ Console.log_error("The resulting checkout would most probably not result in a valid project state.")
96
+ return false
97
+ when RevisionSelection::LATEST
98
+ Console.log_warning("The specified ref is a merge commit and a \"latest\" checkout was requested.")
99
+ Console.log_warning("The work branches recorded in the branch from which the merge was performed will be checked out.")
100
+ end
101
+
102
+ return true
103
+ end
104
+
105
+ def perform_dependency_checkout(config_entry, revision)
106
+ dependency_name = config_entry.repo.basename
107
+
108
+ # Make sure the repo exists on disk, and clone it if it doesn't
109
+ # (in case the checked-out revision had an additional dependency)
110
+ unless config_entry.repo.exists?
111
+ Console.log_substep("Cloning missing dependency '#{config_entry.path}' from #{config_entry.url}")
112
+ config_entry.repo.clone(config_entry.url)
113
+ end
114
+
115
+ # Checkout!
116
+ if config_entry.repo.checkout(revision)
117
+ Console.log_substep("Checked out #{dependency_name} '#{revision}'")
118
+ else
119
+ fail MultiRepoException, "Couldn't check out the appropriate version of dependency #{dependency_name}"
120
+ end
121
+ end
122
+ end
123
+ end