git-multirepo 1.0.0.beta34 → 1.0.0.beta37

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -2
  3. data/.gitignore +38 -38
  4. data/.multirepo.meta +2 -2
  5. data/.rspec +2 -2
  6. data/Gemfile +4 -4
  7. data/Gemfile.lock +38 -38
  8. data/LICENSE +22 -22
  9. data/README.md +143 -143
  10. data/Rakefile +2 -2
  11. data/bin/multi +10 -10
  12. data/docs/bug-repros/91565510-repro.sh +20 -20
  13. data/docs/git-multirepo-node-dependency-depth-algorithm.pdf +0 -0
  14. data/docs/graphs/dependencies-on-multiple-levels.graffle +0 -0
  15. data/docs/graphs/dependencies-on-one-level.graffle +0 -0
  16. data/git-multirepo.gemspec +29 -29
  17. data/lib/commands.rb +13 -12
  18. data/lib/git-multirepo.rb +1 -1
  19. data/lib/info.rb +4 -4
  20. data/lib/multirepo/commands/add-command.rb +53 -51
  21. data/lib/multirepo/commands/branch-command.rb +65 -60
  22. data/lib/multirepo/commands/checkout-command.rb +119 -140
  23. data/lib/multirepo/commands/clean-command.rb +31 -31
  24. data/lib/multirepo/commands/clone-command.rb +70 -70
  25. data/lib/multirepo/commands/command.rb +71 -71
  26. data/lib/multirepo/commands/fetch-command.rb +30 -30
  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 +126 -0
  30. data/lib/multirepo/commands/open-command.rb +26 -26
  31. data/lib/multirepo/commands/remove-command.rb +50 -49
  32. data/lib/multirepo/commands/uninit-command.rb +20 -20
  33. data/lib/multirepo/commands/update-command.rb +59 -59
  34. data/lib/multirepo/config.rb +15 -15
  35. data/lib/multirepo/files/config-entry.rb +34 -34
  36. data/lib/multirepo/files/config-file.rb +45 -34
  37. data/lib/multirepo/files/lock-entry.rb +24 -25
  38. data/lib/multirepo/files/lock-file.rb +39 -28
  39. data/lib/multirepo/files/meta-file.rb +41 -33
  40. data/lib/multirepo/files/tracking-file.rb +8 -8
  41. data/lib/multirepo/files/tracking-files.rb +41 -43
  42. data/lib/multirepo/git/branch.rb +27 -27
  43. data/lib/multirepo/git/change.rb +10 -10
  44. data/lib/multirepo/git/commit.rb +17 -17
  45. data/lib/multirepo/git/git.rb +39 -39
  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 +29 -29
  50. data/lib/multirepo/logic/node.rb +41 -0
  51. data/lib/multirepo/logic/performer.rb +59 -0
  52. data/lib/multirepo/logic/revision-selector.rb +27 -0
  53. data/lib/multirepo/multirepo-exception.rb +5 -5
  54. data/lib/multirepo/utility/console.rb +51 -51
  55. data/lib/multirepo/utility/runner.rb +34 -34
  56. data/lib/multirepo/utility/utils.rb +65 -66
  57. data/resources/.gitconfig +2 -2
  58. data/resources/post-commit +5 -5
  59. data/resources/pre-commit +5 -5
  60. data/spec/integration/init_spec.rb +18 -18
  61. data/spec/spec_helper.rb +89 -89
  62. metadata +10 -3
@@ -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.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
- Git.run_in_working_dir(repo_path, "clean -df", Runner::Verbosity::ALWAYS_OUTPUT)
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
+ Git.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
@@ -1,72 +1,72 @@
1
- require "claide"
2
-
3
- require "info"
4
- require "multirepo/multirepo-exception"
5
- require "multirepo/config"
6
-
7
- module MultiRepo
8
- class Command < CLAide::Command
9
- self.abstract_command = true
10
- self.command = "multi"
11
- self.version = VERSION
12
- self.description = DESCRIPTION
13
-
14
- def initialize(argv)
15
- @argv = argv
16
- Config.instance.verbose = argv.flag?("verbose") ? true : false
17
- Config.instance.git_executable = argv.option("git-exe", "git")
18
- super
19
- end
20
-
21
- def run
22
- help! "Unknown argument(s): #{@argv.remainder.join(', ')}" unless @argv.empty?
23
- end
24
-
25
- def validate!
26
- path = Config.instance.git_executable
27
- is_git_exe = path =~ /.*(git)|(git.exe)$/
28
- file_exists = path == "git" || File.exists?(path)
29
- help! "Invalid git executable '#{path}'" unless is_git_exe && file_exists
30
- end
31
-
32
- def install_hooks(path)
33
- actual_path = path || "."
34
- Utils.install_hook("pre-commit", actual_path)
35
- Utils.install_hook("post-commit", actual_path)
36
- end
37
-
38
- def uninstall_hooks
39
- FileUtils.rm_f(".git/hooks/pre-commit")
40
- FileUtils.rm_f(".git/hooks/post-commit")
41
- end
42
-
43
- def update_gitconfig(path)
44
- actual_path = path || "."
45
- resource_file = Utils.path_for_resource(".gitconfig")
46
- target_file = File.join(actual_path, '.git/config')
47
-
48
- template = File.read(resource_file)
49
- first_template_line = template.lines.first
50
-
51
- Utils.append_if_missing(target_file, Regexp.new(Regexp.quote(first_template_line)), template)
52
- end
53
-
54
- def multirepo_enabled_dependencies
55
- ConfigFile.load_entries.select { |e| Utils.is_multirepo_enabled(e.repo.path) }
56
- end
57
-
58
- def ensure_in_work_tree
59
- repo = Repo.new(".")
60
- raise MultiRepoException, "Not a git repository" unless repo.exists?
61
- raise MultiRepoException, "HEAD is unborn (you must perform at least one commit)" unless repo.head_born?
62
- end
63
-
64
- def ensure_multirepo_enabled
65
- raise MultiRepoException, "multirepo is not initialized in this repository." unless Utils.is_multirepo_enabled(".")
66
- end
67
-
68
- def ensure_multirepo_tracked
69
- raise MultiRepoException, "This revision is not tracked by multirepo." unless Utils.is_multirepo_tracked(".")
70
- end
71
- end
1
+ require "claide"
2
+
3
+ require "info"
4
+ require "multirepo/multirepo-exception"
5
+ require "multirepo/config"
6
+
7
+ module MultiRepo
8
+ class Command < CLAide::Command
9
+ self.abstract_command = true
10
+ self.command = "multi"
11
+ self.version = VERSION
12
+ self.description = DESCRIPTION
13
+
14
+ def initialize(argv)
15
+ @argv = argv
16
+ Config.instance.verbose = argv.flag?("verbose") ? true : false
17
+ Config.instance.git_executable = argv.option("git-exe", "git")
18
+ super
19
+ end
20
+
21
+ def run
22
+ help! "Unknown argument(s): #{@argv.remainder.join(', ')}" unless @argv.empty?
23
+ end
24
+
25
+ def validate!
26
+ path = Config.instance.git_executable
27
+ is_git_exe = path =~ /.*(git)|(git.exe)$/
28
+ file_exists = path == "git" || File.exists?(path)
29
+ help! "Invalid git executable '#{path}'" unless is_git_exe && file_exists
30
+ end
31
+
32
+ def install_hooks(path)
33
+ actual_path = path || "."
34
+ Utils.install_hook("pre-commit", actual_path)
35
+ Utils.install_hook("post-commit", actual_path)
36
+ end
37
+
38
+ def uninstall_hooks
39
+ FileUtils.rm_f(".git/hooks/pre-commit")
40
+ FileUtils.rm_f(".git/hooks/post-commit")
41
+ end
42
+
43
+ def update_gitconfig(path)
44
+ actual_path = path || "."
45
+ resource_file = Utils.path_for_resource(".gitconfig")
46
+ target_file = File.join(actual_path, '.git/config')
47
+
48
+ template = File.read(resource_file)
49
+ first_template_line = template.lines.first
50
+
51
+ Utils.append_if_missing(target_file, Regexp.new(Regexp.quote(first_template_line)), template)
52
+ end
53
+
54
+ def multirepo_enabled_dependencies
55
+ ConfigFile.new(".").load_entries.select { |e| Utils.is_multirepo_enabled(e.repo.path) }
56
+ end
57
+
58
+ def ensure_in_work_tree
59
+ repo = Repo.new(".")
60
+ raise MultiRepoException, "Not a git repository" unless repo.exists?
61
+ raise MultiRepoException, "HEAD is unborn (you must perform at least one commit)" unless repo.head_born?
62
+ end
63
+
64
+ def ensure_multirepo_enabled
65
+ raise MultiRepoException, "multirepo is not initialized in this repository." unless Utils.is_multirepo_enabled(".")
66
+ end
67
+
68
+ def ensure_multirepo_tracked
69
+ raise MultiRepoException, "This revision is not tracked by multirepo." unless Utils.is_multirepo_tracked(".")
70
+ end
71
+ end
72
72
  end
@@ -1,31 +1,31 @@
1
- require "multirepo/utility/console"
2
-
3
- module MultiRepo
4
- class FetchCommand < Command
5
- self.command = "fetch"
6
- self.summary = "Performs a git fetch on all dependencies."
7
-
8
- def run
9
- super
10
- ensure_in_work_tree
11
- ensure_multirepo_enabled
12
-
13
- Console.log_step("Fetching main repo...")
14
-
15
- main_repo = Repo.new(".")
16
- Console.log_substep("Fetching from #{main_repo.remote('origin').url}...")
17
- main_repo.fetch
18
-
19
- Console.log_step("Fetching dependencies...")
20
-
21
- ConfigFile.load_entries.each do |entry|
22
- Console.log_substep("Fetching from #{entry.repo.remote('origin').url}...")
23
- entry.repo.fetch
24
- end
25
-
26
- Console.log_step("Done!")
27
- rescue MultiRepoException => e
28
- Console.log_error(e.message)
29
- end
30
- end
1
+ require "multirepo/utility/console"
2
+
3
+ module MultiRepo
4
+ class FetchCommand < Command
5
+ self.command = "fetch"
6
+ self.summary = "Performs a git fetch on all dependencies."
7
+
8
+ def run
9
+ super
10
+ ensure_in_work_tree
11
+ ensure_multirepo_enabled
12
+
13
+ Console.log_step("Fetching main repo...")
14
+
15
+ main_repo = Repo.new(".")
16
+ Console.log_substep("Fetching from #{main_repo.remote('origin').url}...")
17
+ main_repo.fetch
18
+
19
+ Console.log_step("Fetching dependencies...")
20
+
21
+ ConfigFile.new(".").load_entries.each do |entry|
22
+ Console.log_substep("Fetching from #{entry.repo.remote('origin').url}...")
23
+ entry.repo.fetch
24
+ end
25
+
26
+ Console.log_step("Done!")
27
+ rescue MultiRepoException => e
28
+ Console.log_error(e.message)
29
+ end
30
+ end
31
31
  end
@@ -1,120 +1,120 @@
1
- require "multirepo/utility/console"
2
- require "multirepo/utility/utils"
3
- require "multirepo/files/config-file"
4
- require "multirepo/files/lock-file"
5
- require "multirepo/files/tracking-files"
6
- require "multirepo/commands/command"
7
-
8
- module MultiRepo
9
- class InitCommand < Command
10
- self.command = "init"
11
- self.summary = "Initialize the current repository as a multirepo project."
12
-
13
- def self.options
14
- [['[--extras]', 'Keep the current .multirepo config file as-is and initialize everything else.']].concat(super)
15
- end
16
-
17
- def initialize(argv)
18
- @only_extras = argv.flag?("extras")
19
- super
20
- end
21
-
22
- def run
23
- super
24
- ensure_in_work_tree
25
-
26
- if @only_extras
27
- ensure_multirepo_enabled
28
- Console.log_step("Initializing extras...")
29
- initialize_extras_step
30
- else
31
- Console.log_step("Initializing multirepo...")
32
- full_initialize_step
33
- end
34
-
35
- Console.log_step("Done!")
36
- rescue MultiRepoException => e
37
- Console.log_error(e.message)
38
- end
39
-
40
- def full_initialize_step
41
- if ConfigFile.exists?
42
- reinitialize = Console.ask_yes_no(".multirepo file already exists. Reinitialize?")
43
- raise MultiRepoException, "Initialization aborted" unless reinitialize
44
- end
45
-
46
- unless add_sibling_repos_step
47
- raise MultiRepoException, "There are no sibling repositories to track as dependencies. Initialization aborted."
48
- end
49
-
50
- initialize_extras_step
51
- end
52
-
53
- def add_sibling_repos_step
54
- sibling_repos = Utils.sibling_repos
55
- return false unless sibling_repos.any?
56
-
57
- Console.log_substep("Creating new multirepo config...")
58
-
59
- valid_repos = find_valid_repos(sibling_repos)
60
- entries = create_entries(valid_repos)
61
-
62
- raise MultiRepoException, "No sibling repositories were added as dependencies; aborting." unless entries.any?
63
-
64
- ConfigFile.save_entries(entries)
65
- return true
66
- end
67
-
68
- def initialize_extras_step
69
- install_hooks_step
70
- update_gitattributes_step
71
- update_gitconfig_step
72
- end
73
-
74
- def install_hooks_step
75
- install_hooks(".")
76
- Console.log_substep("Installed git hooks")
77
- end
78
-
79
- def update_gitattributes_step
80
- TrackingFiles::FILE_CLASSES.each do |c|
81
- filename = c::FILENAME
82
- regex_escaped_filename = Regexp.quote(filename)
83
- Utils.append_if_missing("./.gitattributes", /^#{regex_escaped_filename} .*/, "#{filename} merge=ours")
84
- end
85
- Console.log_substep("Updated .gitattributes file")
86
- end
87
-
88
- def update_gitconfig_step
89
- update_gitconfig(".")
90
- Console.log_substep("Updated .git/config file")
91
- end
92
-
93
- def find_valid_repos(repos)
94
- repos.select do |repo|
95
- next true if repo.head_born?
96
- Console.log_warning("Ignoring repo '#{repo.path}' because its HEAD is unborn. You must perform at least one commit.")
97
- end
98
- end
99
-
100
- def create_entries(repos)
101
- entries = []
102
- repos.each do |repo|
103
- origin_url = repo.remote('origin').url
104
- current_branch = repo.current_branch
105
-
106
- if Console.ask_yes_no("Do you want to add '#{repo.path}' as a dependency?\n [origin: #{origin_url || "NONE"}, branch: #{current_branch}]")
107
- raise MultiRepoException, "Repo 'origin' remote url is not set; aborting." unless origin_url
108
- entries.push(ConfigEntry.new(repo))
109
- Console.log_substep("Added the repository '#{repo.path}' to the .multirepo file")
110
- end
111
- end
112
- return entries
113
- end
114
-
115
- def check_repo_exists
116
- if !Dir.exists?(@repo.path) then raise MultiRepoException, "There is no folder at path '#{@repo.path}'" end
117
- if !@repo.exists? then raise MultiRepoException, "'#{@repo.path}' is not a repository" end
118
- end
119
- end
1
+ require "multirepo/utility/console"
2
+ require "multirepo/utility/utils"
3
+ require "multirepo/files/config-file"
4
+ require "multirepo/files/lock-file"
5
+ require "multirepo/files/tracking-files"
6
+ require "multirepo/commands/command"
7
+
8
+ module MultiRepo
9
+ class InitCommand < Command
10
+ self.command = "init"
11
+ self.summary = "Initialize the current repository as a multirepo project."
12
+
13
+ def self.options
14
+ [['[--extras]', 'Keep the current .multirepo config file as-is and initialize everything else.']].concat(super)
15
+ end
16
+
17
+ def initialize(argv)
18
+ @only_extras = argv.flag?("extras")
19
+ super
20
+ end
21
+
22
+ def run
23
+ super
24
+ ensure_in_work_tree
25
+
26
+ if @only_extras
27
+ ensure_multirepo_enabled
28
+ Console.log_step("Initializing extras...")
29
+ initialize_extras_step
30
+ else
31
+ Console.log_step("Initializing multirepo...")
32
+ full_initialize_step
33
+ end
34
+
35
+ Console.log_step("Done!")
36
+ rescue MultiRepoException => e
37
+ Console.log_error(e.message)
38
+ end
39
+
40
+ def full_initialize_step
41
+ if ConfigFile.new(".").exists?
42
+ reinitialize = Console.ask_yes_no(".multirepo file already exists. Reinitialize?")
43
+ raise MultiRepoException, "Initialization aborted" unless reinitialize
44
+ end
45
+
46
+ unless add_sibling_repos_step
47
+ raise MultiRepoException, "There are no sibling repositories to track as dependencies. Initialization aborted."
48
+ end
49
+
50
+ initialize_extras_step
51
+ end
52
+
53
+ def add_sibling_repos_step
54
+ sibling_repos = Utils.sibling_repos
55
+ return false unless sibling_repos.any?
56
+
57
+ Console.log_substep("Creating new multirepo config...")
58
+
59
+ valid_repos = find_valid_repos(sibling_repos)
60
+ entries = create_entries(valid_repos)
61
+
62
+ raise MultiRepoException, "No sibling repositories were added as dependencies; aborting." unless entries.any?
63
+
64
+ ConfigFile.new(".").save_entries(entries)
65
+ return true
66
+ end
67
+
68
+ def initialize_extras_step
69
+ install_hooks_step
70
+ update_gitattributes_step
71
+ update_gitconfig_step
72
+ end
73
+
74
+ def install_hooks_step
75
+ install_hooks(".")
76
+ Console.log_substep("Installed git hooks")
77
+ end
78
+
79
+ def update_gitattributes_step
80
+ TrackingFiles::FILES.each do |f|
81
+ filename = f.filename
82
+ regex_escaped_filename = Regexp.quote(filename)
83
+ Utils.append_if_missing("./.gitattributes", /^#{regex_escaped_filename} .*/, "#{filename} merge=ours")
84
+ end
85
+ Console.log_substep("Updated .gitattributes file")
86
+ end
87
+
88
+ def update_gitconfig_step
89
+ update_gitconfig(".")
90
+ Console.log_substep("Updated .git/config file")
91
+ end
92
+
93
+ def find_valid_repos(repos)
94
+ repos.select do |repo|
95
+ next true if repo.head_born?
96
+ Console.log_warning("Ignoring repo '#{repo.path}' because its HEAD is unborn. You must perform at least one commit.")
97
+ end
98
+ end
99
+
100
+ def create_entries(repos)
101
+ entries = []
102
+ repos.each do |repo|
103
+ origin_url = repo.remote('origin').url
104
+ current_branch = repo.current_branch
105
+
106
+ if Console.ask_yes_no("Do you want to add '#{repo.path}' as a dependency?\n [origin: #{origin_url || "NONE"}, branch: #{current_branch}]")
107
+ raise MultiRepoException, "Repo 'origin' remote url is not set; aborting." unless origin_url
108
+ entries.push(ConfigEntry.new(repo))
109
+ Console.log_substep("Added the repository '#{repo.path}' to the .multirepo file")
110
+ end
111
+ end
112
+ return entries
113
+ end
114
+
115
+ def check_repo_exists
116
+ if !Dir.exists?(@repo.path) then raise MultiRepoException, "There is no folder at path '#{@repo.path}'" end
117
+ if !@repo.exists? then raise MultiRepoException, "'#{@repo.path}' is not a repository" end
118
+ end
119
+ end
120
120
  end