git-multirepo 1.0.0.beta39 → 1.0.0.beta40

Sign up to get free protection for your applications and to get access to all the features.
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