git-multirepo 1.0.0.beta60 → 1.0.0.beta61

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -2
  3. data/.gitbugtraq +3 -3
  4. data/.gitignore +38 -38
  5. data/.rspec +2 -2
  6. data/.rubocop.yml +79 -79
  7. data/CHANGELOG.md +75 -71
  8. data/Gemfile +4 -4
  9. data/Gemfile.lock +49 -47
  10. data/LICENSE +22 -22
  11. data/README.md +179 -179
  12. data/Rakefile +1 -1
  13. data/bin/multi +11 -11
  14. data/docs/bug-repros/91565510-repro.sh +20 -20
  15. data/git-multirepo.gemspec +32 -32
  16. data/lib/git-multirepo.rb +3 -3
  17. data/lib/multirepo/commands/add-command.rb +51 -51
  18. data/lib/multirepo/commands/branch-command.rb +88 -88
  19. data/lib/multirepo/commands/checkout-command.rb +127 -127
  20. data/lib/multirepo/commands/clone-command.rb +68 -68
  21. data/lib/multirepo/commands/command.rb +87 -87
  22. data/lib/multirepo/commands/commands.rb +15 -15
  23. data/lib/multirepo/commands/do-command.rb +101 -101
  24. data/lib/multirepo/commands/graph-command.rb +43 -43
  25. data/lib/multirepo/commands/init-command.rb +121 -121
  26. data/lib/multirepo/commands/inspect-command.rb +48 -48
  27. data/lib/multirepo/commands/install-command.rb +170 -170
  28. data/lib/multirepo/commands/merge-command.rb +249 -249
  29. data/lib/multirepo/commands/open-command.rb +55 -55
  30. data/lib/multirepo/commands/remove-command.rb +48 -48
  31. data/lib/multirepo/commands/uninit-command.rb +18 -18
  32. data/lib/multirepo/commands/update-command.rb +112 -112
  33. data/lib/multirepo/config.rb +19 -19
  34. data/lib/multirepo/files/config-entry.rb +39 -39
  35. data/lib/multirepo/files/config-file.rb +52 -48
  36. data/lib/multirepo/files/lock-entry.rb +29 -29
  37. data/lib/multirepo/files/lock-file.rb +62 -58
  38. data/lib/multirepo/files/meta-file.rb +51 -47
  39. data/lib/multirepo/files/tracking-file.rb +9 -9
  40. data/lib/multirepo/files/tracking-files.rb +65 -65
  41. data/lib/multirepo/git/branch.rb +32 -32
  42. data/lib/multirepo/git/change.rb +11 -11
  43. data/lib/multirepo/git/commit.rb +7 -7
  44. data/lib/multirepo/git/git-runner.rb +56 -56
  45. data/lib/multirepo/git/git.rb +10 -10
  46. data/lib/multirepo/git/ref.rb +38 -38
  47. data/lib/multirepo/git/remote.rb +17 -17
  48. data/lib/multirepo/git/repo.rb +129 -129
  49. data/lib/multirepo/hooks/post-commit-hook.rb +23 -23
  50. data/lib/multirepo/hooks/pre-commit-hook.rb +35 -35
  51. data/lib/multirepo/info.rb +5 -5
  52. data/lib/multirepo/logic/dependency.rb +6 -6
  53. data/lib/multirepo/logic/merge-descriptor.rb +95 -95
  54. data/lib/multirepo/logic/node.rb +72 -72
  55. data/lib/multirepo/logic/performer.rb +55 -55
  56. data/lib/multirepo/logic/repo-selection.rb +25 -25
  57. data/lib/multirepo/logic/revision-selection.rb +15 -15
  58. data/lib/multirepo/logic/revision-selector.rb +23 -23
  59. data/lib/multirepo/logic/version-comparer.rb +10 -10
  60. data/lib/multirepo/multirepo-exception.rb +6 -6
  61. data/lib/multirepo/output/extra-output.rb +12 -12
  62. data/lib/multirepo/output/teamcity-extra-output.rb +11 -11
  63. data/lib/multirepo/utility/console.rb +52 -52
  64. data/lib/multirepo/utility/popen-runner.rb +27 -27
  65. data/lib/multirepo/utility/system-runner.rb +14 -14
  66. data/lib/multirepo/utility/utils.rb +99 -99
  67. data/lib/multirepo/utility/verbosity.rb +6 -6
  68. data/resources/.gitconfig +2 -2
  69. data/resources/post-commit +6 -6
  70. data/resources/pre-commit +6 -6
  71. data/spec/integration/init_spec.rb +19 -19
  72. data/spec/spec_helper.rb +89 -89
  73. metadata +9 -15
@@ -1,48 +1,48 @@
1
- require "multirepo/utility/console"
2
- require "multirepo/files/config-file"
3
-
4
- module MultiRepo
5
- class RemoveCommand < Command
6
- self.command = "remove"
7
- self.summary = "Removes the specified dependency from multirepo."
8
-
9
- def self.options
10
- [
11
- ['<path>', 'The relative path to the dependency to remove (e.g. ../MyOldDependency).'],
12
- ['[--delete]', 'Delete the dependency on disk in addition to removing it from the multirepo config.']
13
- ].concat(super)
14
- end
15
-
16
- def initialize(argv)
17
- @path = argv.shift_argument
18
- @delete = argv.flag?("delete")
19
- super
20
- end
21
-
22
- def validate!
23
- super
24
- help! "You must specify a dependency repository to remove" unless @path
25
- end
26
-
27
- def run
28
- ensure_in_work_tree
29
- ensure_multirepo_enabled
30
-
31
- repo = Repo.new(@path)
32
- entry = ConfigEntry.new(repo)
33
-
34
- config_file = ConfigFile.new(".")
35
- if config_file.entry_exists?(entry)
36
- config_file.remove_entry(entry)
37
- Console.log_step("Removed '#{@path}' from the .multirepo file")
38
-
39
- if @delete
40
- FileUtils.rm_rf(@path)
41
- Console.log_step("Deleted '#{@path}' from disk")
42
- end
43
- else
44
- fail MultiRepoException, "'#{@path}' isn't tracked by multirepo"
45
- end
46
- end
47
- end
48
- end
1
+ require "multirepo/utility/console"
2
+ require "multirepo/files/config-file"
3
+
4
+ module MultiRepo
5
+ class RemoveCommand < Command
6
+ self.command = "remove"
7
+ self.summary = "Removes the specified dependency from multirepo."
8
+
9
+ def self.options
10
+ [
11
+ ['<path>', 'The relative path to the dependency to remove (e.g. ../MyOldDependency).'],
12
+ ['[--delete]', 'Delete the dependency on disk in addition to removing it from the multirepo config.']
13
+ ].concat(super)
14
+ end
15
+
16
+ def initialize(argv)
17
+ @path = argv.shift_argument
18
+ @delete = argv.flag?("delete")
19
+ super
20
+ end
21
+
22
+ def validate!
23
+ super
24
+ help! "You must specify a dependency repository to remove" unless @path
25
+ end
26
+
27
+ def run
28
+ ensure_in_work_tree
29
+ ensure_multirepo_enabled
30
+
31
+ repo = Repo.new(@path)
32
+ entry = ConfigEntry.new(repo)
33
+
34
+ config_file = ConfigFile.new(".")
35
+ if config_file.entry_exists?(entry)
36
+ config_file.remove_entry(entry)
37
+ Console.log_step("Removed '#{@path}' from the .multirepo file")
38
+
39
+ if @delete
40
+ FileUtils.rm_rf(@path)
41
+ Console.log_step("Deleted '#{@path}' from disk")
42
+ end
43
+ else
44
+ fail MultiRepoException, "'#{@path}' isn't tracked by multirepo"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,18 +1,18 @@
1
- require "multirepo/utility/console"
2
-
3
- module MultiRepo
4
- class UninitCommand < Command
5
- self.command = "uninit"
6
- self.summary = "Removes all traces of multirepo in the current multirepo repository."
7
-
8
- def run
9
- ensure_in_work_tree
10
-
11
- FileUtils.rm_f(".multirepo")
12
- TrackingFiles.new(".").delete
13
- uninstall_hooks
14
-
15
- Console.log_step("All traces of multirepo have been removed from this repository")
16
- end
17
- end
18
- end
1
+ require "multirepo/utility/console"
2
+
3
+ module MultiRepo
4
+ class UninitCommand < Command
5
+ self.command = "uninit"
6
+ self.summary = "Removes all traces of multirepo in the current multirepo repository."
7
+
8
+ def run
9
+ ensure_in_work_tree
10
+
11
+ FileUtils.rm_f(".multirepo")
12
+ TrackingFiles.new(".").delete
13
+ uninstall_hooks
14
+
15
+ Console.log_step("All traces of multirepo have been removed from this repository")
16
+ end
17
+ end
18
+ end
@@ -1,112 +1,112 @@
1
- require "multirepo/utility/console"
2
- require "multirepo/utility/utils"
3
- require "multirepo/logic/performer"
4
- require "multirepo/logic/repo-selection"
5
- require "multirepo/files/tracking-files"
6
- require "multirepo/git/git-runner"
7
-
8
- module MultiRepo
9
- class UpdateCommand < Command
10
- self.command = "update"
11
- self.summary = "Force-updates the multirepo tracking files."
12
-
13
- def self.options
14
- [
15
- ['[--all]', 'Update the main repository and all dependencies.'],
16
- ['[--main]', 'Update the main repository.'],
17
- ['[--deps]', 'Update dependencies.'],
18
- ['[--force]', 'Update the tracking files even if dependencies contain uncommitted changes.'],
19
- ['[--commit]', 'Commit the tracking files after updating them.'],
20
- ['[--no-diff]', 'Don\'t show lock file diff(s) after updating.']
21
- ].concat(super)
22
- end
23
-
24
- def initialize(argv)
25
- @repo_selection = RepoSelection.new(argv)
26
- @commit = argv.flag?("commit")
27
- @force = argv.flag?("force")
28
- @diff = argv.flag?("diff", true)
29
- super
30
- end
31
-
32
- def validate!
33
- super
34
- help! "You can't provide more than one operation modifier (--deps, --main, etc.)" unless @repo_selection.valid?
35
- end
36
-
37
- def run
38
- ensure_in_work_tree
39
- ensure_multirepo_enabled
40
-
41
- dependencies_clean = Utils.dependencies_clean?(ConfigFile.new(".").load_entries)
42
- if dependencies_clean || @force
43
- update_tracking_files_step(@repo_selection.value)
44
- else
45
- fail MultiRepoException, "Can't update because not all dependencies are clean"
46
- end
47
-
48
- Console.log_step("Done!")
49
- end
50
-
51
- def update_tracking_files_step(repo_selection_value)
52
- case repo_selection_value
53
- when RepoSelection::MAIN
54
- Console.log_step("Updating main repo...")
55
- update_main
56
- when RepoSelection::DEPS
57
- Console.log_step("Updating dependencies...")
58
- update_dependencies
59
- when RepoSelection::ALL
60
- Console.log_step("Updating main repo and dependencies...")
61
- update_dependencies
62
- update_main
63
- end
64
- end
65
-
66
- def update_dependencies
67
- any_changed = false
68
- Performer.depth_ordered_dependencies.each do |dependency|
69
- path = dependency.config_entry.path
70
- name = dependency.config_entry.name
71
- any_changed |= update_one(path, name) if Utils.multirepo_enabled?(path)
72
- end
73
- return any_changed
74
- end
75
-
76
- def update_main
77
- update_one(".", "main repo")
78
- end
79
-
80
- def update_one(path, name)
81
- updated = update_tracking_files(path, name)
82
- show_diff(path) if updated && @diff
83
- commit_tracking_files(path) if @commit
84
- return updated
85
- end
86
-
87
- def update_tracking_files(path, name)
88
- Console.log_substep("Updating tracking files in #{name}")
89
-
90
- tracking_files = TrackingFiles.new(path)
91
- changed = tracking_files.update
92
-
93
- if changed
94
- Console.log_info("Updated tracking files")
95
- else
96
- Console.log_info("Tracking files are already up-to-date")
97
- end
98
-
99
- return changed
100
- end
101
-
102
- def commit_tracking_files(path)
103
- tracking_files = TrackingFiles.new(path)
104
- committed = tracking_files.commit("[multirepo] Updated tracking files manually")
105
- Console.log_info("Committed tracking files") if committed
106
- end
107
-
108
- def show_diff(path)
109
- GitRunner.run_as_system(path, "diff .multirepo.lock")
110
- end
111
- end
112
- end
1
+ require "multirepo/utility/console"
2
+ require "multirepo/utility/utils"
3
+ require "multirepo/logic/performer"
4
+ require "multirepo/logic/repo-selection"
5
+ require "multirepo/files/tracking-files"
6
+ require "multirepo/git/git-runner"
7
+
8
+ module MultiRepo
9
+ class UpdateCommand < Command
10
+ self.command = "update"
11
+ self.summary = "Force-updates the multirepo tracking files."
12
+
13
+ def self.options
14
+ [
15
+ ['[--all]', 'Update the main repository and all dependencies.'],
16
+ ['[--main]', 'Update the main repository.'],
17
+ ['[--deps]', 'Update dependencies.'],
18
+ ['[--force]', 'Update the tracking files even if dependencies contain uncommitted changes.'],
19
+ ['[--commit]', 'Commit the tracking files after updating them.'],
20
+ ['[--no-diff]', 'Don\'t show lock file diff(s) after updating.']
21
+ ].concat(super)
22
+ end
23
+
24
+ def initialize(argv)
25
+ @repo_selection = RepoSelection.new(argv)
26
+ @commit = argv.flag?("commit")
27
+ @force = argv.flag?("force")
28
+ @diff = argv.flag?("diff", true)
29
+ super
30
+ end
31
+
32
+ def validate!
33
+ super
34
+ help! "You can't provide more than one operation modifier (--deps, --main, etc.)" unless @repo_selection.valid?
35
+ end
36
+
37
+ def run
38
+ ensure_in_work_tree
39
+ ensure_multirepo_enabled
40
+
41
+ dependencies_clean = Utils.dependencies_clean?(ConfigFile.new(".").load_entries)
42
+ if dependencies_clean || @force
43
+ update_tracking_files_step(@repo_selection.value)
44
+ else
45
+ fail MultiRepoException, "Can't update because not all dependencies are clean"
46
+ end
47
+
48
+ Console.log_step("Done!")
49
+ end
50
+
51
+ def update_tracking_files_step(repo_selection_value)
52
+ case repo_selection_value
53
+ when RepoSelection::MAIN
54
+ Console.log_step("Updating main repo...")
55
+ update_main
56
+ when RepoSelection::DEPS
57
+ Console.log_step("Updating dependencies...")
58
+ update_dependencies
59
+ when RepoSelection::ALL
60
+ Console.log_step("Updating main repo and dependencies...")
61
+ update_dependencies
62
+ update_main
63
+ end
64
+ end
65
+
66
+ def update_dependencies
67
+ any_changed = false
68
+ Performer.depth_ordered_dependencies.each do |dependency|
69
+ path = dependency.config_entry.path
70
+ name = dependency.config_entry.name
71
+ any_changed |= update_one(path, name) if Utils.multirepo_enabled?(path)
72
+ end
73
+ return any_changed
74
+ end
75
+
76
+ def update_main
77
+ update_one(".", "main repo")
78
+ end
79
+
80
+ def update_one(path, name)
81
+ updated = update_tracking_files(path, name)
82
+ show_diff(path) if updated && @diff
83
+ commit_tracking_files(path) if @commit
84
+ return updated
85
+ end
86
+
87
+ def update_tracking_files(path, name)
88
+ Console.log_substep("Updating tracking files in #{name}")
89
+
90
+ tracking_files = TrackingFiles.new(path)
91
+ changed = tracking_files.update
92
+
93
+ if changed
94
+ Console.log_info("Updated tracking files")
95
+ else
96
+ Console.log_info("Tracking files are already up-to-date")
97
+ end
98
+
99
+ return changed
100
+ end
101
+
102
+ def commit_tracking_files(path)
103
+ tracking_files = TrackingFiles.new(path)
104
+ committed = tracking_files.commit("[multirepo] Updated tracking files manually")
105
+ Console.log_info("Committed tracking files") if committed
106
+ end
107
+
108
+ def show_diff(path)
109
+ GitRunner.run_as_system(path, "diff .multirepo.lock")
110
+ end
111
+ end
112
+ end
@@ -1,19 +1,19 @@
1
- require "singleton"
2
-
3
- module MultiRepo
4
- class Config
5
- include Singleton
6
-
7
- attr_accessor :verbose
8
- @verbose = false
9
-
10
- attr_accessor :running_git_hook
11
- @running_git_hook = false
12
-
13
- attr_accessor :git_executable
14
- @git_executable = nil
15
-
16
- attr_accessor :extra_output
17
- @extra_output = nil
18
- end
19
- end
1
+ require "singleton"
2
+
3
+ module MultiRepo
4
+ class Config
5
+ include Singleton
6
+
7
+ attr_accessor :verbose
8
+ @verbose = false
9
+
10
+ attr_accessor :running_git_hook
11
+ @running_git_hook = false
12
+
13
+ attr_accessor :git_executable
14
+ @git_executable = nil
15
+
16
+ attr_accessor :extra_output
17
+ @extra_output = nil
18
+ end
19
+ end
@@ -1,39 +1,39 @@
1
- require "securerandom"
2
-
3
- require "multirepo/utility/console"
4
- require "multirepo/git/repo"
5
-
6
- module MultiRepo
7
- class ConfigEntry
8
- attr_accessor :id
9
- attr_accessor :path
10
- attr_accessor :url
11
- attr_accessor :repo
12
-
13
- def encode_with(coder)
14
- coder["id"] = @id
15
- coder["path"] = @path
16
- coder["url"] = @url
17
- end
18
-
19
- def initialize(repo)
20
- @id = SecureRandom.uuid
21
- @path = repo.path
22
- @url = repo.exists? ? repo.remote('origin').url : nil
23
- end
24
-
25
- def ==(other)
26
- other_path = Pathname.new(other.path)
27
- self_path = Pathname.new(path)
28
- other_path.exist? && self_path.exist? && other_path.realpath == self_path.realpath
29
- end
30
-
31
- def repo
32
- Repo.new(path)
33
- end
34
-
35
- def name
36
- repo.basename
37
- end
38
- end
39
- end
1
+ require "securerandom"
2
+
3
+ require "multirepo/utility/console"
4
+ require "multirepo/git/repo"
5
+
6
+ module MultiRepo
7
+ class ConfigEntry
8
+ attr_accessor :id
9
+ attr_accessor :path
10
+ attr_accessor :url
11
+ attr_accessor :repo
12
+
13
+ def encode_with(coder)
14
+ coder["id"] = @id
15
+ coder["path"] = @path
16
+ coder["url"] = @url
17
+ end
18
+
19
+ def initialize(repo)
20
+ @id = SecureRandom.uuid
21
+ @path = repo.path
22
+ @url = repo.exists? ? repo.remote('origin').url : nil
23
+ end
24
+
25
+ def ==(other)
26
+ other_path = Pathname.new(other.path)
27
+ self_path = Pathname.new(path)
28
+ other_path.exist? && self_path.exist? && other_path.realpath == self_path.realpath
29
+ end
30
+
31
+ def repo
32
+ Repo.new(path)
33
+ end
34
+
35
+ def name
36
+ repo.basename
37
+ end
38
+ end
39
+ end
@@ -1,48 +1,52 @@
1
- require "fileutils"
2
- require "pathname"
3
-
4
- require_relative "config-entry"
5
-
6
- module MultiRepo
7
- class ConfigFile
8
- FILENAME = ".multirepo"
9
-
10
- def initialize(path)
11
- @path = path
12
- end
13
-
14
- def file
15
- File.join(@path, FILENAME)
16
- end
17
-
18
- def filename
19
- FILENAME
20
- end
21
-
22
- def exists?
23
- File.exist?(file)
24
- end
25
-
26
- def load_entries
27
- fail MultiRepoException, "Can't read config file (no permission)" if !File.stat(file).readable?
28
- Psych.load(File.read(file))
29
- end
30
-
31
- def save_entries(entries)
32
- fail MultiRepoException, "Can't write config file (no permission)" if !File.stat(file).writable?
33
- File.write(file, Psych.dump(entries))
34
- end
35
-
36
- def entry_exists?(entry)
37
- load_entries.any? { |e| e == entry }
38
- end
39
-
40
- def add_entry(entry)
41
- save_entries(load_entries.push(entry))
42
- end
43
-
44
- def remove_entry(entry)
45
- save_entries(load_entries.delete_if { |e| e == entry })
46
- end
47
- end
48
- end
1
+ require "fileutils"
2
+ require "pathname"
3
+
4
+ require_relative "config-entry"
5
+
6
+ module MultiRepo
7
+ class ConfigFile
8
+ FILENAME = ".multirepo"
9
+
10
+ def initialize(path)
11
+ @path = path
12
+ end
13
+
14
+ def file
15
+ File.join(@path, FILENAME)
16
+ end
17
+
18
+ def filename
19
+ FILENAME
20
+ end
21
+
22
+ def exists?
23
+ File.exist?(file)
24
+ end
25
+
26
+ def load_entries
27
+ ensure_access(file, "Can't read config file (permissions)") { |stat| stat.readable? }
28
+ Psych.load(File.read(file))
29
+ end
30
+
31
+ def save_entries(entries)
32
+ ensure_access(file, "Can't write config file (permissions)") { |stat| stat.writable? }
33
+ File.write(file, Psych.dump(entries))
34
+ end
35
+
36
+ def entry_exists?(entry)
37
+ load_entries.any? { |e| e == entry }
38
+ end
39
+
40
+ def add_entry(entry)
41
+ save_entries(load_entries.push(entry))
42
+ end
43
+
44
+ def remove_entry(entry)
45
+ save_entries(load_entries.delete_if { |e| e == entry })
46
+ end
47
+
48
+ def ensure_access(file, error_message, &check)
49
+ fail MultiRepoException, error_message if File.exists?(file) && !check.call(File.stat(file))
50
+ end
51
+ end
52
+ end
@@ -1,29 +1,29 @@
1
- require "multirepo/utility/console"
2
- require "multirepo/git/repo"
3
-
4
- module MultiRepo
5
- class LockEntry
6
- attr_accessor :name
7
- attr_accessor :id
8
- attr_accessor :head
9
- attr_accessor :branch
10
-
11
- def encode_with(coder)
12
- coder["name"] = @name
13
- coder["id"] = @id
14
- coder["head"] = @head
15
- coder["branch"] = @branch
16
- end
17
-
18
- def initialize(config_entry)
19
- @name = config_entry.name
20
- @id = config_entry.id
21
-
22
- head = config_entry.repo.head
23
- @head = head.commit_id
24
-
25
- current_branch = config_entry.repo.current_branch
26
- @branch = current_branch ? current_branch.name : nil
27
- end
28
- end
29
- end
1
+ require "multirepo/utility/console"
2
+ require "multirepo/git/repo"
3
+
4
+ module MultiRepo
5
+ class LockEntry
6
+ attr_accessor :name
7
+ attr_accessor :id
8
+ attr_accessor :head
9
+ attr_accessor :branch
10
+
11
+ def encode_with(coder)
12
+ coder["name"] = @name
13
+ coder["id"] = @id
14
+ coder["head"] = @head
15
+ coder["branch"] = @branch
16
+ end
17
+
18
+ def initialize(config_entry)
19
+ @name = config_entry.name
20
+ @id = config_entry.id
21
+
22
+ head = config_entry.repo.head
23
+ @head = head.commit_id
24
+
25
+ current_branch = config_entry.repo.current_branch
26
+ @branch = current_branch ? current_branch.name : nil
27
+ end
28
+ end
29
+ end