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,58 +1,62 @@
1
- require "pathname"
2
- require "psych"
3
-
4
- require_relative "tracking-file"
5
- require_relative "lock-entry"
6
- require_relative "config-file"
7
-
8
- module MultiRepo
9
- class LockFile < TrackingFile
10
- FILENAME = ".multirepo.lock"
11
-
12
- def initialize(path)
13
- @path = path
14
- end
15
-
16
- def file
17
- File.join(@path, FILENAME)
18
- end
19
-
20
- def filename
21
- FILENAME
22
- end
23
-
24
- def exists?
25
- File.exist?(file)
26
- end
27
-
28
- def load_entries
29
- fail MultiRepoException, "Can't read lock file (no permission)" if !File.stat(file).readable?
30
- Psych.load(File.read(file))
31
- end
32
-
33
- def update
34
- fail MultiRepoException, "Can't write lock file (no permission)" if !File.stat(file).writable?
35
- config_entries = ConfigFile.new(@path).load_entries
36
- lock_entries = config_entries.map { |c| LockEntry.new(c) }
37
- content = Psych.dump(lock_entries)
38
- return update_internal(file, content)
39
- end
40
-
41
- def validate!
42
- load_entries.all? { |e| validate_entry! e }
43
- end
44
-
45
- def validate_entry!(entry)
46
- valid = true
47
-
48
- # head
49
- valid &= /\b([a-f0-9]{40})\b/ =~ entry.head.to_s
50
-
51
- # branch
52
- GitRunner.run(@path, "check-ref-format --branch #{entry.branch}", Verbosity::OUTPUT_NEVER)
53
- valid &= (entry.branch == "" || GitRunner.last_command_succeeded)
54
-
55
- return valid
56
- end
57
- end
58
- end
1
+ require "pathname"
2
+ require "psych"
3
+
4
+ require_relative "tracking-file"
5
+ require_relative "lock-entry"
6
+ require_relative "config-file"
7
+
8
+ module MultiRepo
9
+ class LockFile < TrackingFile
10
+ FILENAME = ".multirepo.lock"
11
+
12
+ def initialize(path)
13
+ @path = path
14
+ end
15
+
16
+ def file
17
+ File.join(@path, FILENAME)
18
+ end
19
+
20
+ def filename
21
+ FILENAME
22
+ end
23
+
24
+ def exists?
25
+ File.exist?(file)
26
+ end
27
+
28
+ def load_entries
29
+ ensure_access(file, "Can't read lock file (permissions)") { |stat| stat.readable? }
30
+ Psych.load(File.read(file))
31
+ end
32
+
33
+ def update
34
+ ensure_access(file, "Can't write lock file (permissions)") { |stat| stat.writable? }
35
+ config_entries = ConfigFile.new(@path).load_entries
36
+ lock_entries = config_entries.map { |c| LockEntry.new(c) }
37
+ content = Psych.dump(lock_entries)
38
+ return update_internal(file, content)
39
+ end
40
+
41
+ def validate!
42
+ load_entries.all? { |e| validate_entry! e }
43
+ end
44
+
45
+ def validate_entry!(entry)
46
+ valid = true
47
+
48
+ # head
49
+ valid &= /\b([a-f0-9]{40})\b/ =~ entry.head.to_s
50
+
51
+ # branch
52
+ GitRunner.run(@path, "check-ref-format --branch #{entry.branch}", Verbosity::OUTPUT_NEVER)
53
+ valid &= (entry.branch == "" || GitRunner.last_command_succeeded)
54
+
55
+ return valid
56
+ end
57
+
58
+ def ensure_access(file, error_message, &check)
59
+ fail MultiRepoException, error_message if File.exists?(file) && !check.call(File.stat(file))
60
+ end
61
+ end
62
+ end
@@ -1,47 +1,51 @@
1
- require "pathname"
2
- require "psych"
3
-
4
- require "multirepo/info"
5
- require_relative "tracking-file"
6
- require_relative "lock-entry"
7
- require_relative "config-file"
8
-
9
- module MultiRepo
10
- class MetaFile < TrackingFile
11
- FILENAME = ".multirepo.meta"
12
-
13
- attr_accessor :version
14
-
15
- def initialize(path)
16
- @path = path
17
- @version = MultiRepo::VERSION
18
- end
19
-
20
- def file
21
- File.join(@path, FILENAME)
22
- end
23
-
24
- def filename
25
- FILENAME
26
- end
27
-
28
- def exists?
29
- File.exist?(file)
30
- end
31
-
32
- def encode_with(coder)
33
- coder["version"] = @version
34
- end
35
-
36
- def load
37
- fail MultiRepoException, "Can't read meta file (no permission)" if !File.stat(file).readable?
38
- Psych.load(File.read(file))
39
- end
40
-
41
- def update
42
- fail MultiRepoException, "Can't write meta file (no permission)" if !File.stat(file).writable?
43
- content = Psych.dump(self)
44
- return update_internal(file, content)
45
- end
46
- end
47
- end
1
+ require "pathname"
2
+ require "psych"
3
+
4
+ require "multirepo/info"
5
+ require_relative "tracking-file"
6
+ require_relative "lock-entry"
7
+ require_relative "config-file"
8
+
9
+ module MultiRepo
10
+ class MetaFile < TrackingFile
11
+ FILENAME = ".multirepo.meta"
12
+
13
+ attr_accessor :version
14
+
15
+ def initialize(path)
16
+ @path = path
17
+ @version = MultiRepo::VERSION
18
+ end
19
+
20
+ def file
21
+ File.join(@path, FILENAME)
22
+ end
23
+
24
+ def filename
25
+ FILENAME
26
+ end
27
+
28
+ def exists?
29
+ File.exist?(file)
30
+ end
31
+
32
+ def encode_with(coder)
33
+ coder["version"] = @version
34
+ end
35
+
36
+ def load
37
+ ensure_access(file, "Can't read meta file (permissions)") { |stat| stat.readable? }
38
+ Psych.load(File.read(file))
39
+ end
40
+
41
+ def update
42
+ ensure_access(file, "Can't write meta file (permissions)") { |stat| stat.writable? }
43
+ content = Psych.dump(self)
44
+ return update_internal(file, content)
45
+ end
46
+
47
+ def ensure_access(file, error_message, &check)
48
+ fail MultiRepoException, error_message if File.exists?(file) && !check.call(File.stat(file))
49
+ end
50
+ end
51
+ end
@@ -1,9 +1,9 @@
1
- module MultiRepo
2
- class TrackingFile
3
- def update_internal(file, new_content)
4
- old_content = File.exist?(file) ? File.read(file) : nil
5
- File.write(file, new_content)
6
- return new_content != old_content
7
- end
8
- end
9
- end
1
+ module MultiRepo
2
+ class TrackingFile
3
+ def update_internal(file, new_content)
4
+ old_content = File.exist?(file) ? File.read(file) : nil
5
+ File.write(file, new_content)
6
+ return new_content != old_content
7
+ end
8
+ end
9
+ end
@@ -1,65 +1,65 @@
1
- require "multirepo/git/git-runner"
2
- require_relative "meta-file"
3
- require_relative "lock-file"
4
- require "multirepo/info"
5
- require "multirepo/logic/version-comparer"
6
-
7
- module MultiRepo
8
- class TrackingFiles
9
- attr_accessor :files
10
-
11
- def initialize(path)
12
- @path = path
13
- @meta_file = MetaFile.new(path)
14
- @lock_file = LockFile.new(path)
15
- @files = [@meta_file, @lock_file]
16
- end
17
-
18
- def update
19
- ensure_tool_not_outdated
20
- updated = false
21
- files.each { |f| updated |= f.update }
22
- return updated
23
- end
24
-
25
- def ensure_tool_not_outdated
26
- base_message = "Can't update tracking files with an outdated version of git-multirepo"
27
-
28
- fail MultiRepoException, base_message if !@meta_file.exists?
29
-
30
- current_version = MultiRepo::VERSION
31
- meta_version = @meta_file.load.version
32
- outdated_tool = !VersionComparer.is_latest(current: current_version, last: meta_version)
33
- message = base_message + "\n Current version is #{current_version} and repo is tracked by #{meta_version}"
34
-
35
- fail MultiRepoException, message if outdated_tool
36
- end
37
-
38
- def stage
39
- GitRunner.run(@path, "add --force -- #{files_pathspec}", Verbosity::OUTPUT_ON_ERROR)
40
- end
41
-
42
- def commit(message)
43
- stage
44
-
45
- output = GitRunner.run(@path, "ls-files --modified --others -- #{files_pathspec}", Verbosity::OUTPUT_NEVER)
46
- files_are_untracked_or_modified = output.strip != ""
47
-
48
- output = GitRunner.run(@path, "diff --name-only --cached -- #{files_pathspec}", Verbosity::OUTPUT_NEVER)
49
- files_are_staged = output.strip != ""
50
-
51
- must_commit = files_are_untracked_or_modified || files_are_staged
52
- GitRunner.run(@path, "commit --no-verify -m \"#{message}\" --only -- #{files_pathspec}", Verbosity::OUTPUT_ON_ERROR) if must_commit
53
-
54
- return must_commit
55
- end
56
-
57
- def delete
58
- files.each { |f| FileUtils.rm_f(f.file) }
59
- end
60
-
61
- def files_pathspec
62
- files.map{ |f| File.basename(f.file) }.join(" ")
63
- end
64
- end
65
- end
1
+ require "multirepo/git/git-runner"
2
+ require_relative "meta-file"
3
+ require_relative "lock-file"
4
+ require "multirepo/info"
5
+ require "multirepo/logic/version-comparer"
6
+
7
+ module MultiRepo
8
+ class TrackingFiles
9
+ attr_accessor :files
10
+
11
+ def initialize(path)
12
+ @path = path
13
+ @meta_file = MetaFile.new(path)
14
+ @lock_file = LockFile.new(path)
15
+ @files = [@meta_file, @lock_file]
16
+ end
17
+
18
+ def update
19
+ ensure_tool_not_outdated
20
+ updated = false
21
+ files.each { |f| updated |= f.update }
22
+ return updated
23
+ end
24
+
25
+ def ensure_tool_not_outdated
26
+ base_message = "Can't update tracking files with an outdated version of git-multirepo"
27
+
28
+ fail MultiRepoException, base_message if !@meta_file.exists?
29
+
30
+ current_version = MultiRepo::VERSION
31
+ meta_version = @meta_file.load.version
32
+ outdated_tool = !VersionComparer.is_latest(current: current_version, last: meta_version)
33
+ message = base_message + "\n Current version is #{current_version} and repo is tracked by #{meta_version}"
34
+
35
+ fail MultiRepoException, message if outdated_tool
36
+ end
37
+
38
+ def stage
39
+ GitRunner.run(@path, "add --force -- #{files_pathspec}", Verbosity::OUTPUT_ON_ERROR)
40
+ end
41
+
42
+ def commit(message)
43
+ stage
44
+
45
+ output = GitRunner.run(@path, "ls-files --modified --others -- #{files_pathspec}", Verbosity::OUTPUT_NEVER)
46
+ files_are_untracked_or_modified = output.strip != ""
47
+
48
+ output = GitRunner.run(@path, "diff --name-only --cached -- #{files_pathspec}", Verbosity::OUTPUT_NEVER)
49
+ files_are_staged = output.strip != ""
50
+
51
+ must_commit = files_are_untracked_or_modified || files_are_staged
52
+ GitRunner.run(@path, "commit --no-verify -m \"#{message}\" --only -- #{files_pathspec}", Verbosity::OUTPUT_ON_ERROR) if must_commit
53
+
54
+ return must_commit
55
+ end
56
+
57
+ def delete
58
+ files.each { |f| FileUtils.rm_f(f.file) }
59
+ end
60
+
61
+ def files_pathspec
62
+ files.map{ |f| File.basename(f.file) }.join(" ")
63
+ end
64
+ end
65
+ end
@@ -1,32 +1,32 @@
1
- require_relative "ref"
2
- require_relative "git-runner"
3
-
4
- module MultiRepo
5
- class Branch < Ref
6
- def exists?
7
- lines = GitRunner.run(@repo.path, "branch", Verbosity::OUTPUT_NEVER).split("\n")
8
- branch_names = lines.map { |line| line.tr("* ", "") }
9
- branch_names.include?(@name)
10
- end
11
-
12
- def upstream_branch
13
- output = GitRunner.run(@repo.path, "config --get branch.#{@name}.merge", Verbosity::OUTPUT_NEVER)
14
- output.sub!("refs/heads/", "")
15
- return nil if output == ""
16
- Branch.new(@repo, "origin/#{output}")
17
- end
18
-
19
- def create
20
- GitRunner.run(@repo.path, "branch #{@name}", Verbosity::OUTPUT_ON_ERROR)
21
- end
22
-
23
- def push
24
- GitRunner.run(@repo.path, "push -u origin #{@name}", Verbosity::OUTPUT_ON_ERROR)
25
- end
26
-
27
- def checkout
28
- GitRunner.run(@repo.path, "checkout #{@name}", Verbosity::OUTPUT_ON_ERROR)
29
- GitRunner.last_command_succeeded
30
- end
31
- end
32
- end
1
+ require_relative "ref"
2
+ require_relative "git-runner"
3
+
4
+ module MultiRepo
5
+ class Branch < Ref
6
+ def exists?
7
+ lines = GitRunner.run(@repo.path, "branch", Verbosity::OUTPUT_NEVER).split("\n")
8
+ branch_names = lines.map { |line| line.tr("* ", "") }
9
+ branch_names.include?(@name)
10
+ end
11
+
12
+ def upstream_branch
13
+ output = GitRunner.run(@repo.path, "config --get branch.#{@name}.merge", Verbosity::OUTPUT_NEVER)
14
+ output.sub!("refs/heads/", "")
15
+ return nil if output == ""
16
+ Branch.new(@repo, "origin/#{output}")
17
+ end
18
+
19
+ def create
20
+ GitRunner.run(@repo.path, "branch #{@name}", Verbosity::OUTPUT_ON_ERROR)
21
+ end
22
+
23
+ def push
24
+ GitRunner.run(@repo.path, "push -u origin #{@name}", Verbosity::OUTPUT_ON_ERROR)
25
+ end
26
+
27
+ def checkout
28
+ GitRunner.run(@repo.path, "checkout #{@name}", Verbosity::OUTPUT_ON_ERROR)
29
+ GitRunner.last_command_succeeded
30
+ end
31
+ end
32
+ end
@@ -1,11 +1,11 @@
1
- module MultiRepo
2
- class Change
3
- attr_accessor :status
4
- attr_accessor :path
5
-
6
- def initialize(line)
7
- @status = line[0...2].strip
8
- @path = line[3..-1]
9
- end
10
- end
11
- end
1
+ module MultiRepo
2
+ class Change
3
+ attr_accessor :status
4
+ attr_accessor :path
5
+
6
+ def initialize(line)
7
+ @status = line[0...2].strip
8
+ @path = line[3..-1]
9
+ end
10
+ end
11
+ end
@@ -1,7 +1,7 @@
1
- require_relative "ref"
2
- require_relative "git-runner"
3
-
4
- module MultiRepo
5
- class Commit < Ref
6
- end
7
- end
1
+ require_relative "ref"
2
+ require_relative "git-runner"
3
+
4
+ module MultiRepo
5
+ class Commit < Ref
6
+ end
7
+ end
@@ -1,56 +1,56 @@
1
- require "multirepo/utility/verbosity"
2
- require "multirepo/utility/popen-runner"
3
- require "multirepo/utility/system-runner"
4
- require "multirepo/config"
5
-
6
- module MultiRepo
7
- class GitRunner
8
- class << self
9
- attr_accessor :last_command_succeeded
10
- end
11
-
12
- def self.run(path, git_command, verbosity)
13
- command = build_command(path, git_command)
14
- runner_popen(command, verbosity)
15
- end
16
-
17
- def self.run_as_system(path, git_command)
18
- command = build_command(path, git_command)
19
- runner_system(command)
20
- end
21
-
22
- def self.build_command(path, git_command)
23
- if path == "."
24
- # It is always better to skip -C when running git commands in the
25
- # current directory (especially in hooks). Doing this prevents
26
- # any future issues because we automatically fallback to non-"-C" for ".".
27
- # Fixes bug: https://www.pivotaltracker.com/story/show/94505654
28
- return "#{git_executable} #{git_command}"
29
- end
30
-
31
- full_command = "#{git_executable} -C \"#{path}\" #{git_command}"
32
- if Config.instance.running_git_hook
33
- # True fix for the -C flag issue in pre-commit hook where the status command would
34
- # fail to provide correct results if a pathspec was provided when performing a commit.
35
- # http://thread.gmane.org/gmane.comp.version-control.git/263319/focus=263323
36
- full_command = "sh -c 'unset $(git rev-parse --local-env-vars); #{full_command};'"
37
- end
38
-
39
- return full_command
40
- end
41
-
42
- def self.runner_popen(full_command, verbosity)
43
- result, @last_command_succeeded = PopenRunner.run(full_command, verbosity)
44
- return result
45
- end
46
-
47
- def self.runner_system(full_command)
48
- result, @last_command_succeeded = SystemRunner.run(full_command)
49
- return result
50
- end
51
-
52
- def self.git_executable
53
- Config.instance.git_executable || "git"
54
- end
55
- end
56
- end
1
+ require "multirepo/utility/verbosity"
2
+ require "multirepo/utility/popen-runner"
3
+ require "multirepo/utility/system-runner"
4
+ require "multirepo/config"
5
+
6
+ module MultiRepo
7
+ class GitRunner
8
+ class << self
9
+ attr_accessor :last_command_succeeded
10
+ end
11
+
12
+ def self.run(path, git_command, verbosity)
13
+ command = build_command(path, git_command)
14
+ runner_popen(command, verbosity)
15
+ end
16
+
17
+ def self.run_as_system(path, git_command)
18
+ command = build_command(path, git_command)
19
+ runner_system(command)
20
+ end
21
+
22
+ def self.build_command(path, git_command)
23
+ if path == "."
24
+ # It is always better to skip -C when running git commands in the
25
+ # current directory (especially in hooks). Doing this prevents
26
+ # any future issues because we automatically fallback to non-"-C" for ".".
27
+ # Fixes bug: https://www.pivotaltracker.com/story/show/94505654
28
+ return "#{git_executable} #{git_command}"
29
+ end
30
+
31
+ full_command = "#{git_executable} -C \"#{path}\" #{git_command}"
32
+ if Config.instance.running_git_hook
33
+ # True fix for the -C flag issue in pre-commit hook where the status command would
34
+ # fail to provide correct results if a pathspec was provided when performing a commit.
35
+ # http://thread.gmane.org/gmane.comp.version-control.git/263319/focus=263323
36
+ full_command = "sh -c 'unset $(git rev-parse --local-env-vars); #{full_command};'"
37
+ end
38
+
39
+ return full_command
40
+ end
41
+
42
+ def self.runner_popen(full_command, verbosity)
43
+ result, @last_command_succeeded = PopenRunner.run(full_command, verbosity)
44
+ return result
45
+ end
46
+
47
+ def self.runner_system(full_command)
48
+ result, @last_command_succeeded = SystemRunner.run(full_command)
49
+ return result
50
+ end
51
+
52
+ def self.git_executable
53
+ Config.instance.git_executable || "git"
54
+ end
55
+ end
56
+ end
@@ -1,10 +1,10 @@
1
- require "multirepo/git/git-runner"
2
-
3
- module MultiRepo
4
- class Git
5
- def self.valid_branch_name?(name)
6
- GitRunner.run(".", "check-ref-format --branch \"#{name}\"", Verbosity::OUTPUT_NEVER)
7
- GitRunner.last_command_succeeded
8
- end
9
- end
10
- end
1
+ require "multirepo/git/git-runner"
2
+
3
+ module MultiRepo
4
+ class Git
5
+ def self.valid_branch_name?(name)
6
+ GitRunner.run(".", "check-ref-format --branch \"#{name}\"", Verbosity::OUTPUT_NEVER)
7
+ GitRunner.last_command_succeeded
8
+ end
9
+ end
10
+ end