git-multirepo 1.0.0.beta49 → 1.0.0.beta50

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 (70) 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 +29 -25
  9. data/Gemfile +4 -4
  10. data/Gemfile.lock +42 -42
  11. data/LICENSE +22 -22
  12. data/README.md +154 -154
  13. data/Rakefile +1 -1
  14. data/bin/multi +11 -11
  15. data/docs/bug-repros/91565510-repro.sh +20 -20
  16. data/git-multirepo.gemspec +31 -31
  17. data/lib/git-multirepo.rb +3 -3
  18. data/lib/multirepo/commands/add-command.rb +51 -51
  19. data/lib/multirepo/commands/branch-command.rb +82 -82
  20. data/lib/multirepo/commands/checkout-command.rb +120 -120
  21. data/lib/multirepo/commands/clone-command.rb +68 -68
  22. data/lib/multirepo/commands/command.rb +90 -90
  23. data/lib/multirepo/commands/commands.rb +15 -0
  24. data/lib/multirepo/commands/do-command.rb +103 -103
  25. data/lib/multirepo/commands/graph-command.rb +43 -43
  26. data/lib/multirepo/commands/init-command.rb +121 -121
  27. data/lib/multirepo/commands/inspect-command.rb +39 -39
  28. data/lib/multirepo/commands/install-command.rb +153 -153
  29. data/lib/multirepo/commands/merge-command.rb +249 -225
  30. data/lib/multirepo/commands/open-command.rb +57 -57
  31. data/lib/multirepo/commands/remove-command.rb +48 -48
  32. data/lib/multirepo/commands/uninit-command.rb +18 -18
  33. data/lib/multirepo/commands/update-command.rb +106 -94
  34. data/lib/multirepo/config.rb +16 -16
  35. data/lib/multirepo/files/config-entry.rb +39 -39
  36. data/lib/multirepo/files/config-file.rb +46 -46
  37. data/lib/multirepo/files/lock-entry.rb +29 -29
  38. data/lib/multirepo/files/lock-file.rb +56 -56
  39. data/lib/multirepo/files/meta-file.rb +41 -41
  40. data/lib/multirepo/files/tracking-file.rb +9 -9
  41. data/lib/multirepo/files/tracking-files.rb +47 -47
  42. data/lib/multirepo/git/branch.rb +32 -32
  43. data/lib/multirepo/git/change.rb +11 -11
  44. data/lib/multirepo/git/commit.rb +7 -7
  45. data/lib/multirepo/git/git-runner.rb +56 -56
  46. data/lib/multirepo/git/git.rb +10 -10
  47. data/lib/multirepo/git/ref.rb +38 -38
  48. data/lib/multirepo/git/remote.rb +17 -17
  49. data/lib/multirepo/git/repo.rb +124 -124
  50. data/lib/multirepo/hooks/post-commit-hook.rb +23 -23
  51. data/lib/multirepo/hooks/pre-commit-hook.rb +35 -35
  52. data/lib/{info.rb → multirepo/info.rb} +5 -5
  53. data/lib/multirepo/logic/dependency.rb +6 -6
  54. data/lib/multirepo/logic/merge-descriptor.rb +95 -95
  55. data/lib/multirepo/logic/node.rb +72 -72
  56. data/lib/multirepo/logic/performer.rb +55 -55
  57. data/lib/multirepo/logic/revision-selector.rb +35 -35
  58. data/lib/multirepo/multirepo-exception.rb +6 -6
  59. data/lib/multirepo/utility/console.rb +52 -52
  60. data/lib/multirepo/utility/popen-runner.rb +27 -27
  61. data/lib/multirepo/utility/system-runner.rb +14 -14
  62. data/lib/multirepo/utility/utils.rb +95 -95
  63. data/lib/multirepo/utility/verbosity.rb +6 -6
  64. data/resources/.gitconfig +2 -2
  65. data/resources/post-commit +6 -6
  66. data/resources/pre-commit +6 -6
  67. data/spec/integration/init_spec.rb +19 -19
  68. data/spec/spec_helper.rb +89 -89
  69. metadata +33 -33
  70. data/lib/commands.rb +0 -15
@@ -1,68 +1,68 @@
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
- ['[<refname>]', '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_name = 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
- Console.log_step("Cloning #{@url} ...")
34
-
35
- fail MultiRepoException, "A directory named #{@name} already exists" if Dir.exist?(@name)
36
-
37
- main_repo_path = "#{@name}/#{@name}"
38
- main_repo = Repo.new(main_repo_path)
39
-
40
- # Recursively create the directory where we'll clone the main repo
41
- FileUtils.mkpath(main_repo_path)
42
-
43
- # Clone the specified remote in the just-created directory
44
- fail MultiRepoException, "Could not clone repo from #{@url}" unless main_repo.clone(@url)
45
-
46
- # Checkout the specified main repo ref so that install reads the proper config file
47
- unless main_repo.checkout(@ref_name)
48
- fail MultiRepoException, "Couldn't perform checkout of main repo #{@ref_name}!"
49
- end
50
-
51
- Console.log_substep("Checked out main repo #{@ref_name}")
52
-
53
- # Make sure the ref we just checked out is tracked by multirepo
54
- unless Utils.multirepo_tracked?(main_repo_path)
55
- fail MultiRepoException, "Ref #{@ref_name} is not tracked by multirepo"
56
- end
57
-
58
- # Install
59
- original_path = Dir.pwd
60
- Dir.chdir(main_repo_path)
61
- install_command = InstallCommand.new(CLAide::ARGV.new([]))
62
- install_command.full_install
63
- Dir.chdir(original_path)
64
-
65
- Console.log_step("Done!")
66
- end
67
- end
68
- 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
+ ['[<refname>]', '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_name = 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
+ Console.log_step("Cloning #{@url} ...")
34
+
35
+ fail MultiRepoException, "A directory named #{@name} already exists" if Dir.exist?(@name)
36
+
37
+ main_repo_path = "#{@name}/#{@name}"
38
+ main_repo = Repo.new(main_repo_path)
39
+
40
+ # Recursively create the directory where we'll clone the main repo
41
+ FileUtils.mkpath(main_repo_path)
42
+
43
+ # Clone the specified remote in the just-created directory
44
+ fail MultiRepoException, "Could not clone repo from #{@url}" unless main_repo.clone(@url)
45
+
46
+ # Checkout the specified main repo ref so that install reads the proper config file
47
+ unless main_repo.checkout(@ref_name)
48
+ fail MultiRepoException, "Couldn't perform checkout of main repo #{@ref_name}!"
49
+ end
50
+
51
+ Console.log_substep("Checked out main repo #{@ref_name}")
52
+
53
+ # Make sure the ref we just checked out is tracked by multirepo
54
+ unless Utils.multirepo_tracked?(main_repo_path)
55
+ fail MultiRepoException, "Ref #{@ref_name} is not tracked by multirepo"
56
+ end
57
+
58
+ # Install
59
+ original_path = Dir.pwd
60
+ Dir.chdir(main_repo_path)
61
+ install_command = InstallCommand.new(CLAide::ARGV.new([]))
62
+ install_command.full_install
63
+ Dir.chdir(original_path)
64
+
65
+ Console.log_step("Done!")
66
+ end
67
+ end
68
+ end
@@ -1,90 +1,90 @@
1
- require "claide"
2
-
3
- require "info"
4
- require "multirepo/multirepo-exception"
5
- require "multirepo/config"
6
- require "multirepo/files/config-file"
7
- require "multirepo/files/lock-file"
8
-
9
- module MultiRepo
10
- class Command < CLAide::Command
11
- self.abstract_command = true
12
- self.command = "multi"
13
- self.version = VERSION
14
- self.description = DESCRIPTION
15
-
16
- def self.report_error(exception)
17
- if exception.instance_of?(MultiRepoException)
18
- Console.log_error(exception.message)
19
- exit 1
20
- end
21
- fail exception
22
- end
23
-
24
- def initialize(argv)
25
- @argv = argv
26
- Config.instance.verbose |= argv.flag?("verbose") ? true : false
27
- Config.instance.git_executable = argv.option("git-exe", "git")
28
- super
29
- end
30
-
31
- def run
32
- help!
33
- end
34
-
35
- def validate!
36
- super
37
- path = Config.instance.git_executable
38
- is_git_exe = path =~ /.*(git)|(git.exe)$/
39
- file_exists = path == "git" || File.exist?(path)
40
- help! "Invalid git executable '#{path}'" unless is_git_exe && file_exists
41
- end
42
-
43
- def install_hooks(path)
44
- actual_path = path || "."
45
- Utils.install_hook("pre-commit", actual_path)
46
- Utils.install_hook("post-commit", actual_path)
47
- end
48
-
49
- def uninstall_hooks
50
- FileUtils.rm_f(".git/hooks/pre-commit")
51
- FileUtils.rm_f(".git/hooks/post-commit")
52
- end
53
-
54
- def update_gitconfig(path)
55
- actual_path = path || "."
56
- resource_file = Utils.path_for_resource(".gitconfig")
57
- target_file = File.join(actual_path, '.git/config')
58
-
59
- template = File.read(resource_file)
60
- first_template_line = template.lines.first
61
-
62
- Utils.append_if_missing(target_file, Regexp.new(Regexp.quote(first_template_line)), template)
63
- end
64
-
65
- def multirepo_enabled_dependencies
66
- ConfigFile.new(".").load_entries.select { |e| Utils.multirepo_enabled?(e.repo.path) }
67
- end
68
-
69
- def validate_only_one_flag(*flags)
70
- flags.reduce(0) { |count, flag| count += 1 if flag; count } <= 1
71
- end
72
-
73
- def ensure_in_work_tree
74
- repo = Repo.new(".")
75
- fail MultiRepoException, "Not a git repository" unless repo.exists?
76
- fail MultiRepoException, "HEAD is unborn (you must perform at least one commit)" unless repo.head_born?
77
- end
78
-
79
- def ensure_multirepo_enabled
80
- fail MultiRepoException, "multirepo is not initialized in this repository." unless Utils.multirepo_enabled?(".")
81
- end
82
-
83
- def ensure_multirepo_tracked
84
- fail MultiRepoException, "Revision is not tracked by multirepo." unless Utils.multirepo_tracked?(".")
85
-
86
- lock_file_valid = LockFile.new(".").validate!
87
- fail MultiRepoException, "Revision is multirepo-enabled but contains a corrupted lock file!" unless lock_file_valid
88
- end
89
- end
90
- end
1
+ require "claide"
2
+
3
+ require "multirepo/info"
4
+ require "multirepo/multirepo-exception"
5
+ require "multirepo/config"
6
+ require "multirepo/files/config-file"
7
+ require "multirepo/files/lock-file"
8
+
9
+ module MultiRepo
10
+ class Command < CLAide::Command
11
+ self.abstract_command = true
12
+ self.command = "multi"
13
+ self.version = VERSION
14
+ self.description = DESCRIPTION
15
+
16
+ def self.report_error(exception)
17
+ if exception.instance_of?(MultiRepoException)
18
+ Console.log_error(exception.message)
19
+ exit 1
20
+ end
21
+ fail exception
22
+ end
23
+
24
+ def initialize(argv)
25
+ @argv = argv
26
+ Config.instance.verbose |= argv.flag?("verbose") ? true : false
27
+ Config.instance.git_executable = argv.option("git-exe", "git")
28
+ super
29
+ end
30
+
31
+ def run
32
+ help!
33
+ end
34
+
35
+ def validate!
36
+ super
37
+ path = Config.instance.git_executable
38
+ is_git_exe = path =~ /.*(git)|(git.exe)$/
39
+ file_exists = path == "git" || File.exist?(path)
40
+ help! "Invalid git executable '#{path}'" unless is_git_exe && file_exists
41
+ end
42
+
43
+ def install_hooks(path)
44
+ actual_path = path || "."
45
+ Utils.install_hook("pre-commit", actual_path)
46
+ Utils.install_hook("post-commit", actual_path)
47
+ end
48
+
49
+ def uninstall_hooks
50
+ FileUtils.rm_f(".git/hooks/pre-commit")
51
+ FileUtils.rm_f(".git/hooks/post-commit")
52
+ end
53
+
54
+ def update_gitconfig(path)
55
+ actual_path = path || "."
56
+ resource_file = Utils.path_for_resource(".gitconfig")
57
+ target_file = File.join(actual_path, '.git/config')
58
+
59
+ template = File.read(resource_file)
60
+ first_template_line = template.lines.first
61
+
62
+ Utils.append_if_missing(target_file, Regexp.new(Regexp.quote(first_template_line)), template)
63
+ end
64
+
65
+ def multirepo_enabled_dependencies
66
+ ConfigFile.new(".").load_entries.select { |e| Utils.multirepo_enabled?(e.repo.path) }
67
+ end
68
+
69
+ def validate_only_one_flag(*flags)
70
+ flags.reduce(0) { |count, flag| count += 1 if flag; count } <= 1
71
+ end
72
+
73
+ def ensure_in_work_tree
74
+ repo = Repo.new(".")
75
+ fail MultiRepoException, "Not a git repository" unless repo.exists?
76
+ fail MultiRepoException, "HEAD is unborn (you must perform at least one commit)" unless repo.head_born?
77
+ end
78
+
79
+ def ensure_multirepo_enabled
80
+ fail MultiRepoException, "multirepo is not initialized in this repository." unless Utils.multirepo_enabled?(".")
81
+ end
82
+
83
+ def ensure_multirepo_tracked
84
+ fail MultiRepoException, "Revision is not tracked by multirepo." unless Utils.multirepo_tracked?(".")
85
+
86
+ lock_file_valid = LockFile.new(".").validate!
87
+ fail MultiRepoException, "Revision is multirepo-enabled but contains a corrupted lock file!" unless lock_file_valid
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,15 @@
1
+ require_relative "command"
2
+ require_relative "add-command"
3
+ require_relative "branch-command"
4
+ require_relative "checkout-command"
5
+ require_relative "clone-command"
6
+ require_relative "do-command"
7
+ require_relative "graph-command"
8
+ require_relative "init-command"
9
+ require_relative "inspect-command"
10
+ require_relative "install-command"
11
+ require_relative "merge-command"
12
+ require_relative "open-command"
13
+ require_relative "remove-command"
14
+ require_relative "uninit-command"
15
+ require_relative "update-command"
@@ -1,103 +1,103 @@
1
- require_relative "command"
2
- require "multirepo/utility/utils"
3
- require "multirepo/utility/console"
4
- require "multirepo/files/config-file"
5
- require "multirepo/git/repo"
6
- require "multirepo/git/git-runner"
7
- require "multirepo/logic/performer"
8
-
9
- module MultiRepo
10
- class DoCommand < Command
11
- self.command = "do"
12
- self.summary = "Perform an arbitrary Git operation in the main repository, dependency repositories or all repositories."
13
-
14
- def self.options
15
- [
16
- ['"<operation>"', 'The git command to perform, between quotes, omitting the executable name (ex: "reset --hard HEAD")'],
17
- ['[--main]', 'Perform the operation in the main repository only.'],
18
- ['[--deps]', 'Perform the operation in dependencies only.'],
19
- ['[--all]', 'Perform the operation in the main repository and all dependencies.']
20
- ].concat(super)
21
- end
22
-
23
- def initialize(argv)
24
- @operation = argv.shift_argument
25
- @all = argv.flag?("all")
26
- @main_only = argv.flag?("main")
27
- @deps_only = argv.flag?("deps")
28
- super
29
- end
30
-
31
- def validate!
32
- super
33
- help! "You must provide a git operation to perform" unless @operation
34
- unless validate_only_one_flag(@all, @main_only, @deps_only)
35
- help! "You can't provide more than one operation modifier (--deps, --main, etc.)"
36
- end
37
- end
38
-
39
- def run
40
- ensure_in_work_tree
41
- ensure_multirepo_enabled
42
-
43
- @operation = @operation.sub(/^git /, "")
44
-
45
- success = true
46
- if @main_only
47
- confirm_main_repo_operation
48
- success &= perform_operation_on_main(@operation)
49
- elsif @deps_only
50
- confirm_dependencies_operation
51
- success &= perform_operation_on_dependencies(@operation)
52
- else
53
- confirm_main_repo_operation
54
- confirm_dependencies_operation
55
- success &= perform_operation_on_dependencies(@operation) # Ordered dependencies first
56
- success &= perform_operation_on_main(@operation) # Main last
57
- end
58
-
59
- Console.log_warning("Some operations finished with non-zero exit status. Please review the above.") unless success
60
- end
61
-
62
- def perform_operation_on_main(operation)
63
- perform_operation(".", operation)
64
- end
65
-
66
- def perform_operation_on_dependencies(operation)
67
- success = true
68
- Performer.dependencies.each do |dependency|
69
- success &= perform_operation(dependency.config_entry.repo.path, operation)
70
- end
71
- return success
72
- end
73
-
74
- def perform_operation(path, operation)
75
- Console.log_step("Performing operation on '#{path}'")
76
- GitRunner.run_as_system(path, operation)
77
- GitRunner.last_command_succeeded
78
- end
79
-
80
- def confirm_main_repo_operation
81
- unless main_repo_clean?
82
- Console.log_warning("Main repo contains uncommitted changes")
83
- fail MultiRepoException, "Aborted" unless Console.ask_yes_no("Proceed anyway?")
84
- end
85
- end
86
-
87
- def confirm_dependencies_operation
88
- unless dependencies_clean?
89
- Console.log_warning("Some dependencies contain uncommitted changes")
90
- fail MultiRepoException, "Aborted" unless Console.ask_yes_no("Proceed anyway?")
91
- end
92
- end
93
-
94
- def main_repo_clean?
95
- Repo.new(".").clean?
96
- end
97
-
98
- def dependencies_clean?
99
- config_entries = ConfigFile.new(".").load_entries
100
- return Utils.dependencies_clean?(config_entries)
101
- end
102
- end
103
- end
1
+ require_relative "command"
2
+ require "multirepo/utility/utils"
3
+ require "multirepo/utility/console"
4
+ require "multirepo/files/config-file"
5
+ require "multirepo/git/repo"
6
+ require "multirepo/git/git-runner"
7
+ require "multirepo/logic/performer"
8
+
9
+ module MultiRepo
10
+ class DoCommand < Command
11
+ self.command = "do"
12
+ self.summary = "Perform an arbitrary Git operation in the main repository, dependency repositories or all repositories."
13
+
14
+ def self.options
15
+ [
16
+ ['"<operation>"', 'The git command to perform, between quotes, omitting the executable name (ex: "reset --hard HEAD")'],
17
+ ['[--main]', 'Perform the operation in the main repository only.'],
18
+ ['[--deps]', 'Perform the operation in dependencies only.'],
19
+ ['[--all]', 'Perform the operation in the main repository and all dependencies.']
20
+ ].concat(super)
21
+ end
22
+
23
+ def initialize(argv)
24
+ @operation = argv.shift_argument
25
+ @all = argv.flag?("all")
26
+ @main_only = argv.flag?("main")
27
+ @deps_only = argv.flag?("deps")
28
+ super
29
+ end
30
+
31
+ def validate!
32
+ super
33
+ help! "You must provide a git operation to perform" unless @operation
34
+ unless validate_only_one_flag(@all, @main_only, @deps_only)
35
+ help! "You can't provide more than one operation modifier (--deps, --main, etc.)"
36
+ end
37
+ end
38
+
39
+ def run
40
+ ensure_in_work_tree
41
+ ensure_multirepo_enabled
42
+
43
+ @operation = @operation.sub(/^git /, "")
44
+
45
+ success = true
46
+ if @main_only
47
+ confirm_main_repo_operation
48
+ success &= perform_operation_on_main(@operation)
49
+ elsif @deps_only
50
+ confirm_dependencies_operation
51
+ success &= perform_operation_on_dependencies(@operation)
52
+ else
53
+ confirm_main_repo_operation
54
+ confirm_dependencies_operation
55
+ success &= perform_operation_on_dependencies(@operation) # Ordered dependencies first
56
+ success &= perform_operation_on_main(@operation) # Main last
57
+ end
58
+
59
+ Console.log_warning("Some operations finished with non-zero exit status. Please review the above.") unless success
60
+ end
61
+
62
+ def perform_operation_on_main(operation)
63
+ perform_operation(".", operation)
64
+ end
65
+
66
+ def perform_operation_on_dependencies(operation)
67
+ success = true
68
+ Performer.dependencies.each do |dependency|
69
+ success &= perform_operation(dependency.config_entry.repo.path, operation)
70
+ end
71
+ return success
72
+ end
73
+
74
+ def perform_operation(path, operation)
75
+ Console.log_step("Performing operation on '#{path}'")
76
+ GitRunner.run_as_system(path, operation)
77
+ GitRunner.last_command_succeeded
78
+ end
79
+
80
+ def confirm_main_repo_operation
81
+ unless main_repo_clean?
82
+ Console.log_warning("Main repo contains uncommitted changes")
83
+ fail MultiRepoException, "Aborted" unless Console.ask("Proceed anyway?")
84
+ end
85
+ end
86
+
87
+ def confirm_dependencies_operation
88
+ unless dependencies_clean?
89
+ Console.log_warning("Some dependencies contain uncommitted changes")
90
+ fail MultiRepoException, "Aborted" unless Console.ask("Proceed anyway?")
91
+ end
92
+ end
93
+
94
+ def main_repo_clean?
95
+ Repo.new(".").clean?
96
+ end
97
+
98
+ def dependencies_clean?
99
+ config_entries = ConfigFile.new(".").load_entries
100
+ return Utils.dependencies_clean?(config_entries)
101
+ end
102
+ end
103
+ end