git-multirepo 1.0.0.beta39 → 1.0.0.beta40

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 (63) 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/Gemfile +4 -4
  8. data/Gemfile.lock +42 -42
  9. data/LICENSE +22 -22
  10. data/README.md +146 -145
  11. data/Rakefile +2 -2
  12. data/bin/multi +10 -10
  13. data/docs/bug-repros/91565510-repro.sh +20 -20
  14. data/git-multirepo.gemspec +31 -31
  15. data/lib/commands.rb +15 -14
  16. data/lib/git-multirepo.rb +2 -2
  17. data/lib/info.rb +4 -4
  18. data/lib/multirepo/commands/add-command.rb +53 -53
  19. data/lib/multirepo/commands/branch-command.rb +82 -82
  20. data/lib/multirepo/commands/checkout-command.rb +122 -122
  21. data/lib/multirepo/commands/clean-command.rb +31 -31
  22. data/lib/multirepo/commands/clone-command.rb +70 -70
  23. data/lib/multirepo/commands/command.rb +75 -75
  24. data/lib/multirepo/commands/do-command.rb +76 -0
  25. data/lib/multirepo/commands/fetch-command.rb +30 -30
  26. data/lib/multirepo/commands/graph-command.rb +45 -45
  27. data/lib/multirepo/commands/init-command.rb +119 -119
  28. data/lib/multirepo/commands/install-command.rb +103 -103
  29. data/lib/multirepo/commands/merge-command.rb +167 -167
  30. data/lib/multirepo/commands/open-command.rb +57 -57
  31. data/lib/multirepo/commands/remove-command.rb +50 -50
  32. data/lib/multirepo/commands/uninit-command.rb +20 -20
  33. data/lib/multirepo/commands/update-command.rb +60 -60
  34. data/lib/multirepo/config.rb +15 -15
  35. data/lib/multirepo/files/config-entry.rb +38 -38
  36. data/lib/multirepo/files/config-file.rb +45 -45
  37. data/lib/multirepo/files/lock-entry.rb +24 -24
  38. data/lib/multirepo/files/lock-file.rb +38 -38
  39. data/lib/multirepo/files/meta-file.rb +40 -40
  40. data/lib/multirepo/files/tracking-file.rb +8 -8
  41. data/lib/multirepo/files/tracking-files.rb +46 -46
  42. data/lib/multirepo/git/branch.rb +30 -30
  43. data/lib/multirepo/git/change.rb +10 -10
  44. data/lib/multirepo/git/commit.rb +17 -17
  45. data/lib/multirepo/git/git-runner.rb +46 -46
  46. data/lib/multirepo/git/remote.rb +16 -16
  47. data/lib/multirepo/git/repo.rb +77 -77
  48. data/lib/multirepo/hooks/post-commit-hook.rb +22 -22
  49. data/lib/multirepo/hooks/pre-commit-hook.rb +31 -31
  50. data/lib/multirepo/logic/merge-descriptor.rb +12 -12
  51. data/lib/multirepo/logic/node.rb +44 -44
  52. data/lib/multirepo/logic/performer.rb +62 -62
  53. data/lib/multirepo/logic/revision-selector.rb +34 -34
  54. data/lib/multirepo/multirepo-exception.rb +5 -5
  55. data/lib/multirepo/utility/console.rb +51 -51
  56. data/lib/multirepo/utility/runner.rb +34 -34
  57. data/lib/multirepo/utility/utils.rb +81 -81
  58. data/resources/.gitconfig +2 -2
  59. data/resources/post-commit +5 -5
  60. data/resources/pre-commit +5 -5
  61. data/spec/integration/init_spec.rb +18 -18
  62. data/spec/spec_helper.rb +89 -89
  63. metadata +4 -3
@@ -1,123 +1,123 @@
1
- require "multirepo/utility/console"
2
- require "multirepo/logic/revision-selector"
3
- require "multirepo/logic/performer"
4
-
5
- module MultiRepo
6
- class CheckoutCommand < Command
7
- self.command = "checkout"
8
- self.summary = "Checks out the specified commit or branch of the main repo and checks out matching versions of all dependencies."
9
-
10
- def self.options
11
- [
12
- ['<ref>', 'The main repo tag, branch or commit id to checkout.'],
13
- ['[--latest]', 'Checkout the HEAD of each dependency branch (as recorded in the lock file) instead of the exact required commits.'],
14
- ['[--exact]', 'Checkout the exact specified ref for each repo, regardless of what\'s stored in the lock file.']
15
- ].concat(super)
16
- end
17
-
18
- def initialize(argv)
19
- @ref = argv.shift_argument
20
- @checkout_latest = argv.flag?("latest")
21
- @checkout_exact = argv.flag?("exact")
22
- super
23
- end
24
-
25
- def validate!
26
- super
27
- help! "You must specify a branch or commit id to checkout" unless @ref
28
- unless validate_only_one_flag(@checkout_latest, @checkout_exact)
29
- help! "You can't provide more than one operation modifier (--latest, --exact, etc.)"
30
- end
31
- end
32
-
33
- def run
34
- super
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 = RevisionSelectionMode.name_for_mode(mode)
41
- Console.log_step("Checking out #{@ref} and its dependencies using the '#{strategy_name}' strategy...")
42
-
43
- main_repo = Repo.new(".")
44
-
45
- unless proceed_if_merge_commit?(main_repo, @ref, mode)
46
- raise MultiRepoException, "Aborting checkout"
47
- end
48
-
49
- checkout_core(main_repo, mode)
50
-
51
- Console.log_step("Done!")
52
- rescue MultiRepoException => e
53
- Console.log_error(e.message)
54
- end
55
-
56
- def checkout_core(main_repo, mode)
57
- initial_revision = main_repo.current_branch || main_repo.head_hash
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(main_repo)
63
- rescue MultiRepoException => e
64
- Console.log_error("Reverting main repo checkout")
65
- main_repo.checkout(initial_revision)
66
- raise e
67
- end
68
- dependencies_checkout_step(mode, @ref)
69
- end
70
-
71
- def checkout_main_repo_step(main_repo)
72
- Performer.perform_main_repo_checkout(main_repo, @ref)
73
- end
74
-
75
- def ensure_dependencies_clean_step(main_repo)
76
- unless Utils.ensure_dependencies_clean(ConfigFile.new(".").load_entries)
77
- raise MultiRepoException, "Dependencies are not clean!"
78
- end
79
- end
80
-
81
- def dependencies_checkout_step(mode, ref = nil)
82
- Performer.perform_on_dependencies do |config_entry, lock_entry|
83
- # Find out the required dependency revision based on the checkout mode
84
- revision = RevisionSelector.revision_for_mode(mode, ref, lock_entry)
85
- perform_dependency_checkout(config_entry, revision)
86
- end
87
- end
88
-
89
- def proceed_if_merge_commit?(main_repo, ref, mode)
90
- return true unless main_repo.commit(ref).is_merge?
91
-
92
- case mode
93
- when RevisionSelectionMode::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 RevisionSelectionMode::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
- raise MultiRepoException, "Couldn't check out the appropriate version of dependency #{dependency_name}"
120
- end
121
- end
122
- end
1
+ require "multirepo/utility/console"
2
+ require "multirepo/logic/revision-selector"
3
+ require "multirepo/logic/performer"
4
+
5
+ module MultiRepo
6
+ class CheckoutCommand < Command
7
+ self.command = "checkout"
8
+ self.summary = "Checks out the specified commit or branch of the main repo and checks out matching versions of all dependencies."
9
+
10
+ def self.options
11
+ [
12
+ ['<ref>', 'The main repo tag, branch or commit id to checkout.'],
13
+ ['[--latest]', 'Checkout the HEAD of each dependency branch (as recorded in the lock file) instead of the exact required commits.'],
14
+ ['[--exact]', 'Checkout the exact specified ref for each repo, regardless of what\'s stored in the lock file.']
15
+ ].concat(super)
16
+ end
17
+
18
+ def initialize(argv)
19
+ @ref = argv.shift_argument
20
+ @checkout_latest = argv.flag?("latest")
21
+ @checkout_exact = argv.flag?("exact")
22
+ super
23
+ end
24
+
25
+ def validate!
26
+ super
27
+ help! "You must specify a branch or commit id to checkout" unless @ref
28
+ unless validate_only_one_flag(@checkout_latest, @checkout_exact)
29
+ help! "You can't provide more than one operation modifier (--latest, --exact, etc.)"
30
+ end
31
+ end
32
+
33
+ def run
34
+ super
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 = RevisionSelectionMode.name_for_mode(mode)
41
+ Console.log_step("Checking out #{@ref} and its dependencies using the '#{strategy_name}' strategy...")
42
+
43
+ main_repo = Repo.new(".")
44
+
45
+ unless proceed_if_merge_commit?(main_repo, @ref, mode)
46
+ raise MultiRepoException, "Aborting checkout"
47
+ end
48
+
49
+ checkout_core(main_repo, mode)
50
+
51
+ Console.log_step("Done!")
52
+ rescue MultiRepoException => e
53
+ Console.log_error(e.message)
54
+ end
55
+
56
+ def checkout_core(main_repo, mode)
57
+ initial_revision = main_repo.current_branch || main_repo.head_hash
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(main_repo)
63
+ rescue MultiRepoException => e
64
+ Console.log_error("Reverting main repo checkout")
65
+ main_repo.checkout(initial_revision)
66
+ raise e
67
+ end
68
+ dependencies_checkout_step(mode, @ref)
69
+ end
70
+
71
+ def checkout_main_repo_step(main_repo)
72
+ Performer.perform_main_repo_checkout(main_repo, @ref)
73
+ end
74
+
75
+ def ensure_dependencies_clean_step(main_repo)
76
+ unless Utils.ensure_dependencies_clean(ConfigFile.new(".").load_entries)
77
+ raise MultiRepoException, "Dependencies are not clean!"
78
+ end
79
+ end
80
+
81
+ def dependencies_checkout_step(mode, ref = nil)
82
+ Performer.perform_on_dependencies do |config_entry, lock_entry|
83
+ # Find out the required dependency revision based on the checkout mode
84
+ revision = RevisionSelector.revision_for_mode(mode, ref, lock_entry)
85
+ perform_dependency_checkout(config_entry, revision)
86
+ end
87
+ end
88
+
89
+ def proceed_if_merge_commit?(main_repo, ref, mode)
90
+ return true unless main_repo.commit(ref).is_merge?
91
+
92
+ case mode
93
+ when RevisionSelectionMode::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 RevisionSelectionMode::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
+ raise MultiRepoException, "Couldn't check out the appropriate version of dependency #{dependency_name}"
120
+ end
121
+ end
122
+ end
123
123
  end
@@ -1,32 +1,32 @@
1
- require "multirepo/utility/console"
2
-
3
- module MultiRepo
4
- class CleanCommand < Command
5
- self.command = "clean"
6
- self.summary = "Performs a 'git clean -df' on the main repo and all dependencies."
7
-
8
- def run
9
- super
10
- ensure_in_work_tree
11
- ensure_multirepo_enabled
12
-
13
- Console.log_step("Fetching dependencies...")
14
-
15
- Console.log_substep("Cleaning main repo...")
16
- clean(".")
17
-
18
- ConfigFile.new(".").load_entries.each do |entry|
19
- Console.log_substep("Cleaning #{entry.repo.path} ...")
20
- clean(entry.repo.path)
21
- end
22
-
23
- Console.log_step("Done!")
24
- rescue MultiRepoException => e
25
- Console.log_error(e.message)
26
- end
27
-
28
- def clean(repo_path)
29
- GitRunner.run_in_working_dir(repo_path, "clean -df", Runner::Verbosity::OUTPUT_ALWAYS)
30
- end
31
- end
1
+ require "multirepo/utility/console"
2
+
3
+ module MultiRepo
4
+ class CleanCommand < Command
5
+ self.command = "clean"
6
+ self.summary = "Performs a 'git clean -df' on the main repo and all dependencies."
7
+
8
+ def run
9
+ super
10
+ ensure_in_work_tree
11
+ ensure_multirepo_enabled
12
+
13
+ Console.log_step("Fetching dependencies...")
14
+
15
+ Console.log_substep("Cleaning main repo...")
16
+ clean(".")
17
+
18
+ ConfigFile.new(".").load_entries.each do |entry|
19
+ Console.log_substep("Cleaning #{entry.repo.path} ...")
20
+ clean(entry.repo.path)
21
+ end
22
+
23
+ Console.log_step("Done!")
24
+ rescue MultiRepoException => e
25
+ Console.log_error(e.message)
26
+ end
27
+
28
+ def clean(repo_path)
29
+ GitRunner.run_in_working_dir(repo_path, "clean -df", Runner::Verbosity::OUTPUT_ALWAYS)
30
+ end
31
+ end
32
32
  end
@@ -1,71 +1,71 @@
1
- require "multirepo/utility/console"
2
- require "multirepo/utility/utils"
3
- require "multirepo/git/repo"
4
- require_relative "install-command"
5
-
6
- module MultiRepo
7
- class CloneCommand < Command
8
- self.command = "clone"
9
- self.summary = "Clones the specified repository in a subfolder, then installs it."
10
-
11
- def self.options
12
- [
13
- ['<url>', 'The repository to clone.'],
14
- ['<name>', 'The name of the containing folder that will be created.'],
15
- ['[<ref>]', 'The branch, tag or commit id to checkout. Checkout will use "master" if unspecified.']
16
- ].concat(super)
17
- end
18
-
19
- def initialize(argv)
20
- @url = argv.shift_argument
21
- @name = argv.shift_argument
22
- @ref = argv.shift_argument || "master"
23
- super
24
- end
25
-
26
- def validate!
27
- super
28
- help! "You must specify a repository to clone" unless @url
29
- help! "You must specify a containing folder name" unless @name
30
- end
31
-
32
- def run
33
- super
34
- Console.log_step("Cloning #{@url} ...")
35
-
36
- raise MultiRepoException, "A directory named #{@name} already exists" if Dir.exists?(@name)
37
-
38
- main_repo_path = "#{@name}/#{@name}"
39
- main_repo = Repo.new(main_repo_path)
40
-
41
- # Recursively create the directory where we'll clone the main repo
42
- FileUtils.mkpath(main_repo_path)
43
-
44
- # Clone the specified remote in the just-created directory
45
- raise MultiRepoException, "Could not clone repo from #{@url}" unless main_repo.clone(@url)
46
-
47
- # Checkout the specified main repo ref so that install reads the proper config file
48
- unless main_repo.checkout(@ref)
49
- raise MultiRepoException, "Couldn't perform checkout of main repo #{@ref}!"
50
- end
51
-
52
- Console.log_substep("Checked out main repo #{@ref}")
53
-
54
- # Make sure the ref we just checked out is tracked by multirepo
55
- unless Utils.is_multirepo_tracked(main_repo_path)
56
- raise MultiRepoException, "Ref #{@ref} is not tracked by multirepo"
57
- end
58
-
59
- # Install
60
- original_path = Dir.pwd
61
- Dir.chdir(main_repo_path)
62
- install_command = InstallCommand.new(CLAide::ARGV.new([]))
63
- install_command.full_install
64
- Dir.chdir(original_path)
65
-
66
- Console.log_step("Done!")
67
- rescue MultiRepoException => e
68
- Console.log_error(e.message)
69
- end
70
- end
1
+ require "multirepo/utility/console"
2
+ require "multirepo/utility/utils"
3
+ require "multirepo/git/repo"
4
+ require_relative "install-command"
5
+
6
+ module MultiRepo
7
+ class CloneCommand < Command
8
+ self.command = "clone"
9
+ self.summary = "Clones the specified repository in a subfolder, then installs it."
10
+
11
+ def self.options
12
+ [
13
+ ['<url>', 'The repository to clone.'],
14
+ ['<name>', 'The name of the containing folder that will be created.'],
15
+ ['[<ref>]', 'The branch, tag or commit id to checkout. Checkout will use "master" if unspecified.']
16
+ ].concat(super)
17
+ end
18
+
19
+ def initialize(argv)
20
+ @url = argv.shift_argument
21
+ @name = argv.shift_argument
22
+ @ref = argv.shift_argument || "master"
23
+ super
24
+ end
25
+
26
+ def validate!
27
+ super
28
+ help! "You must specify a repository to clone" unless @url
29
+ help! "You must specify a containing folder name" unless @name
30
+ end
31
+
32
+ def run
33
+ super
34
+ Console.log_step("Cloning #{@url} ...")
35
+
36
+ raise MultiRepoException, "A directory named #{@name} already exists" if Dir.exists?(@name)
37
+
38
+ main_repo_path = "#{@name}/#{@name}"
39
+ main_repo = Repo.new(main_repo_path)
40
+
41
+ # Recursively create the directory where we'll clone the main repo
42
+ FileUtils.mkpath(main_repo_path)
43
+
44
+ # Clone the specified remote in the just-created directory
45
+ raise MultiRepoException, "Could not clone repo from #{@url}" unless main_repo.clone(@url)
46
+
47
+ # Checkout the specified main repo ref so that install reads the proper config file
48
+ unless main_repo.checkout(@ref)
49
+ raise MultiRepoException, "Couldn't perform checkout of main repo #{@ref}!"
50
+ end
51
+
52
+ Console.log_substep("Checked out main repo #{@ref}")
53
+
54
+ # Make sure the ref we just checked out is tracked by multirepo
55
+ unless Utils.is_multirepo_tracked(main_repo_path)
56
+ raise MultiRepoException, "Ref #{@ref} is not tracked by multirepo"
57
+ end
58
+
59
+ # Install
60
+ original_path = Dir.pwd
61
+ Dir.chdir(main_repo_path)
62
+ install_command = InstallCommand.new(CLAide::ARGV.new([]))
63
+ install_command.full_install
64
+ Dir.chdir(original_path)
65
+
66
+ Console.log_step("Done!")
67
+ rescue MultiRepoException => e
68
+ Console.log_error(e.message)
69
+ end
70
+ end
71
71
  end