git-multirepo 1.0.0.beta31 → 1.0.0.beta32

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 67e36cbef8314eee8b0d325162acc18c2ce27e64
4
- data.tar.gz: e62d11f579f9fce15bc06ea316aabd2aa8e6bfcc
3
+ metadata.gz: 82162a9cc290a3d97f8db37ee108a82d0a480e29
4
+ data.tar.gz: f1b49390a52450c77dbed2125fec8e491351f44b
5
5
  SHA512:
6
- metadata.gz: ec0d4681372e9d30752a11d4cfd68198de1cb3fd474df1113978e724c739c511ef1d045143250c90aecce54fbdbcf1b41823df3875a8a30e108c69175eda9c6a
7
- data.tar.gz: 0b891af101c561781915c64a023df4de187ea61106c127f354d8f0d9d56f698107b4ef8e2684018f0323252860876134600c39ef7d2622dcd69952e4345c7add
6
+ metadata.gz: 01c17b8cd7dfdb152b8e72da33e0442caa61c6245beb58e345342f6da1921fb250d33ac395d52840a4a6b2d010784e1fa2d791cc1b76d5ceec29680626cbc3be
7
+ data.tar.gz: 1b1a49c8b247330283daf82ed667e04ec436f85ff69d7926b5e1ac850ac61cee290a2663b5d9e79b83fb4c0b2d4b00ab34a5331384489b938fc13b493d749d11
data/.gitattributes CHANGED
@@ -1 +1,2 @@
1
1
  .multirepo.lock merge=ours
2
+ .multirepo.meta merge=ours
data/.multirepo CHANGED
@@ -3,14 +3,15 @@
3
3
  id: e27695e9-e21d-4ad1-81b8-0ed587574c38
4
4
  path: ../git-multirepo-dummy/
5
5
  url: git@github.com:fortinmike/git-multirepo-dummy.git
6
- branch: master
7
6
  - !ruby/object:MultiRepo::ConfigEntry
8
7
  id: dcb567d6-7456-494a-b7b5-adc208a87f2f
9
8
  path: ../git-multirepo-dummy-dep1/
10
9
  url: git@github.com:fortinmike/git-multirepo-dummy-dep1.git
11
- branch: master
12
10
  - !ruby/object:MultiRepo::ConfigEntry
13
11
  id: e0dc3ed7-4b6b-4052-8783-668b405e4941
14
12
  path: ../git-multirepo-dummy-dep2/
15
13
  url: git@github.com:fortinmike/git-multirepo-dummy-dep2.git
16
- branch: master
14
+ - !ruby/object:MultiRepo::ConfigEntry
15
+ id: ad6472a5-7238-447f-a54e-50f50197e21e
16
+ path: ../git-multirepo-migrations/
17
+ url: git@github.com:fortinmike/git-multirepo-migrations.git
data/.multirepo.lock CHANGED
@@ -2,7 +2,7 @@
2
2
  - !ruby/object:MultiRepo::LockEntry
3
3
  name: git-multirepo-dummy
4
4
  id: e27695e9-e21d-4ad1-81b8-0ed587574c38
5
- head: 59dbe6a9670f6a5ec5efa331c5fd5cb0348c811e
5
+ head: 111f680fd0153a35ed97febc48d118c784f0a98f
6
6
  branch: master
7
7
  - !ruby/object:MultiRepo::LockEntry
8
8
  name: git-multirepo-dummy-dep1
@@ -14,3 +14,8 @@
14
14
  id: e0dc3ed7-4b6b-4052-8783-668b405e4941
15
15
  head: 1b8465fcd4f9e5821640bb45ad8c22c960b64517
16
16
  branch: master
17
+ - !ruby/object:MultiRepo::LockEntry
18
+ name: git-multirepo-migrations
19
+ id: ad6472a5-7238-447f-a54e-50f50197e21e
20
+ head: 841223db4851a1de7af8e22205eb7a840cc0ad38
21
+ branch: master
data/.multirepo.meta ADDED
@@ -0,0 +1,2 @@
1
+ --- !ruby/object:MultiRepo::MetaFile
2
+ version: 1.0.0.beta32
data/README.md CHANGED
@@ -120,23 +120,25 @@ Here is a quick rundown of commands available to you in git-multirepo:
120
120
  | add | Track an additional dependency with multirepo. |
121
121
  | branch | Create and/or checkout a new branch for all repos. |
122
122
  | checkout | Checks out the specified commit or branch of the main repo and checks out matching versions of all dependencies. |
123
+ | clean | Performs a 'git clean -df' on the main repo and all dependencies. |
123
124
  | clone | Clones the specified repository in a subfolder, then installs it. |
124
125
  | fetch | Performs a git fetch on all dependencies. |
125
126
  | install | Clones and checks out dependencies as defined in the version-controlled multirepo metadata files and installs git-multirepo's local git hooks. |
126
127
  | open | Opens all dependencies in the current OS's file explorer. |
127
128
  | remove | Removes the specified dependency from multirepo. |
128
- | update | Force-updates the multirepo lock file. |
129
+ | update | Force-updates the multirepo tracking files. |
129
130
  | uninit | Removes all traces of multirepo in the current multirepo repository. |
130
131
 
131
132
  To read more about each command, use the `--help` flag (e.g. `$ multi clone --help`).
132
133
 
133
134
  ## Metadata
134
135
 
135
- git-multirepo stores all of its metadata in two files:
136
+ git-multirepo stores all of its metadata in three files:
136
137
 
137
- | File | Format | Contents |
138
- |------|--------|----------|
139
- | .multirepo | YAML | A collection of your project's dependencies. For each dependency, stores its **local path** relative to the main repo and the **remote URL** your project depends upon.
140
- | .multirepo.lock | YAML | For each dependency, stores the **commit hash** and **branch** on which the dependency was when the main repo was committed. The dependency's **name** is also included but only serves as a reference to make inspecting the lock file easier. |
138
+ | File | Format | Updated | Contents |
139
+ |------|--------|---------|----------|
140
+ | .multirepo | YAML | at initialization | A collection of your project's dependencies. For each dependency, stores its **local path** relative to the main repo and the **remote URL** your project depends upon.
141
+ | .multirepo.lock | YAML | before each commit | For each dependency, stores the **commit hash** and **branch** on which the dependency was when the main repo was committed. The dependency's **name** is also included but only serves as a reference to make inspecting the lock file easier. |
142
+ | .multirepo.meta | YAML | before each commit | Various git-multirepo metadata, such as the **git-multirepo version** that the last commit was performed with. |
141
143
 
142
144
  The information contained in .multirepo and .multirepo.lock allow one-step cloning of a project and all its dependencies, and checking out any prior revision of the main project with appropriate revisions of all of its dependencies, respectively.
data/lib/info.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module MultiRepo
2
2
  NAME = "git-multirepo"
3
- VERSION = "1.0.0.beta31"
3
+ VERSION = "1.0.0.beta32"
4
4
  DESCRIPTION = "Track multiple Git repositories side-by-side."
5
5
  end
@@ -22,7 +22,7 @@ module MultiRepo
22
22
 
23
23
  def run
24
24
  super
25
- validate_in_work_tree
25
+ ensure_in_work_tree
26
26
  ensure_multirepo_enabled
27
27
  ensure_repo_valid
28
28
 
@@ -1,6 +1,6 @@
1
1
  require "multirepo/utility/console"
2
2
  require "multirepo/files/config-file"
3
- require "multirepo/files/lock-file"
3
+ require "multirepo/files/tracking-files"
4
4
 
5
5
  module MultiRepo
6
6
  class BranchCommand < Command
@@ -29,13 +29,13 @@ module MultiRepo
29
29
 
30
30
  def run
31
31
  super
32
- validate_in_work_tree
32
+ ensure_in_work_tree
33
33
  ensure_multirepo_enabled
34
34
 
35
35
  Console.log_step("Branching...")
36
36
 
37
37
  main_repo = Repo.new(".")
38
- repos = ConfigFile.load.map{ |entry| entry.repo }.push(main_repo)
38
+ repos = ConfigFile.load_entries.map{ |entry| entry.repo }.push(main_repo)
39
39
 
40
40
  if !Utils.ensure_working_copies_clean(repos) && !@force
41
41
  raise MultiRepoException, "Can't branch because not all repos are clean"
@@ -49,9 +49,9 @@ module MultiRepo
49
49
  branch.checkout
50
50
  end
51
51
 
52
- Console.log_substep("Updating and committing lock file")
53
- LockFile.update
54
- LockFile.commit("[multirepo] Post-branch lock file update")
52
+ Console.log_substep("Updating and committing tracking files")
53
+ TrackingFiles.update
54
+ TrackingFiles.commit("[multirepo] Post-branch tracking files update")
55
55
 
56
56
  Console.log_step("Done!")
57
57
  rescue MultiRepoException => e
@@ -34,7 +34,7 @@ module MultiRepo
34
34
 
35
35
  def run
36
36
  super
37
- validate_in_work_tree
37
+ ensure_in_work_tree
38
38
  ensure_multirepo_enabled
39
39
 
40
40
  Console.log_step("Checking out #{@ref} and its dependencies...")
@@ -85,15 +85,15 @@ module MultiRepo
85
85
  end
86
86
 
87
87
  def ensure_dependencies_clean_step(main_repo, initial_revision)
88
- unless Utils.ensure_dependencies_clean(ConfigFile.load)
88
+ unless Utils.ensure_dependencies_clean(ConfigFile.load_entries)
89
89
  main_repo.checkout(initial_revision)
90
90
  raise MultiRepoException, "Checkout reverted."
91
91
  end
92
92
  end
93
93
 
94
94
  def dependencies_checkout_step(mode, ref = nil)
95
- config_entries = ConfigFile.load # Post-main-repo checkout config entries might be different than pre-checkout
96
- LockFile.load.each { |lock_entry| perform_dependency_checkout(config_entries, lock_entry, ref, mode) }
95
+ config_entries = ConfigFile.load_entries # Post-main-repo checkout config entries might be different than pre-checkout
96
+ LockFile.load_entries.each { |lock_entry| perform_dependency_checkout(config_entries, lock_entry, ref, mode) }
97
97
  end
98
98
 
99
99
  def proceed_if_merge_commit?(main_repo, ref, mode)
@@ -7,7 +7,7 @@ module MultiRepo
7
7
 
8
8
  def run
9
9
  super
10
- validate_in_work_tree
10
+ ensure_in_work_tree
11
11
  ensure_multirepo_enabled
12
12
 
13
13
  Console.log_step("Fetching dependencies...")
@@ -15,7 +15,7 @@ module MultiRepo
15
15
  Console.log_substep("Cleaning main repo...")
16
16
  clean(".")
17
17
 
18
- ConfigFile.load.each do |entry|
18
+ ConfigFile.load_entries.each do |entry|
19
19
  Console.log_substep("Cleaning #{entry.repo.path} ...")
20
20
  clean(entry.repo.path)
21
21
  end
@@ -29,17 +29,13 @@ module MultiRepo
29
29
  help! "Invalid git executable '#{path}'" unless is_git_exe && file_exists
30
30
  end
31
31
 
32
- def validate_in_work_tree
33
- raise MultiRepoException, "Not a git repository" unless Git.is_inside_git_repo(".")
34
- end
35
-
36
32
  def install_hooks(path)
37
33
  actual_path = path || "."
38
34
  Utils.install_hook("pre-commit", actual_path)
39
35
  end
40
36
 
41
37
  def uninstall_hooks
42
- File.delete(".git/hooks/pre-commit")
38
+ FileUtils.rm_f(".git/hooks/pre-commit")
43
39
  end
44
40
 
45
41
  def update_gitconfig(path)
@@ -54,7 +50,13 @@ module MultiRepo
54
50
  end
55
51
 
56
52
  def multirepo_enabled_dependencies
57
- ConfigFile.load.select { |e| Utils.is_multirepo_enabled(e.repo.path) }
53
+ ConfigFile.load_entries.select { |e| Utils.is_multirepo_enabled(e.repo.path) }
54
+ end
55
+
56
+ def ensure_in_work_tree
57
+ repo = Repo.new(".")
58
+ raise MultiRepoException, "Not a git repository" unless repo.exists?
59
+ raise MultiRepoException, "HEAD is unborn (you must perform at least one commit)" unless repo.head_born?
58
60
  end
59
61
 
60
62
  def ensure_multirepo_enabled
@@ -7,12 +7,12 @@ module MultiRepo
7
7
 
8
8
  def run
9
9
  super
10
- validate_in_work_tree
10
+ ensure_in_work_tree
11
11
  ensure_multirepo_enabled
12
12
 
13
13
  Console.log_step("Fetching dependencies...")
14
14
 
15
- ConfigFile.load.each do |entry|
15
+ ConfigFile.load_entries.each do |entry|
16
16
  Console.log_substep("Fetching from #{entry.repo.remote('origin').url}...")
17
17
  entry.repo.fetch
18
18
  end
@@ -2,6 +2,7 @@ require "multirepo/utility/console"
2
2
  require "multirepo/utility/utils"
3
3
  require "multirepo/files/config-file"
4
4
  require "multirepo/files/lock-file"
5
+ require "multirepo/files/tracking-files"
5
6
  require "multirepo/commands/command"
6
7
 
7
8
  module MultiRepo
@@ -20,9 +21,10 @@ module MultiRepo
20
21
 
21
22
  def run
22
23
  super
23
- validate_in_work_tree
24
+ ensure_in_work_tree
24
25
 
25
26
  if @only_extras
27
+ ensure_multirepo_enabled
26
28
  Console.log_step("Initializing extras...")
27
29
  initialize_extras_step
28
30
  else
@@ -41,30 +43,26 @@ module MultiRepo
41
43
  raise MultiRepoException, "Initialization aborted" unless reinitialize
42
44
  end
43
45
 
44
- Console.log_substep("Creating new multirepo config...")
45
-
46
- add_sibling_repos_step
46
+ unless add_sibling_repos_step
47
+ raise MultiRepoException, "There are no sibling repositories to track as dependencies. Initialization aborted."
48
+ end
49
+
47
50
  initialize_extras_step
48
51
  end
49
52
 
50
53
  def add_sibling_repos_step
51
54
  sibling_repos = Utils.sibling_repos
55
+ return false unless sibling_repos.any?
56
+
57
+ Console.log_substep("Creating new multirepo config...")
52
58
 
53
- if sibling_repos.any?
54
- entries = []
55
- sibling_repos.each do |repo|
56
- origin_desc = repo.remote('origin').url || "[none]"
57
- current_branch = repo.current_branch
58
- if Console.ask_yes_no("Do you want to add '#{repo.path}' as a dependency?\n [origin: '#{origin_desc}', branch: #{current_branch}]")
59
- entries.push(ConfigEntry.new(repo))
60
- Console.log_substep("Added the repository '#{repo.path}' to the .multirepo file")
61
- end
62
- end
63
-
64
- ConfigFile.save(entries)
65
- else
66
- Console.log_info("There are no sibling repositories to add")
67
- end
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
68
66
  end
69
67
 
70
68
  def initialize_extras_step
@@ -79,7 +77,11 @@ module MultiRepo
79
77
  end
80
78
 
81
79
  def update_gitattributes_step
82
- Utils.append_if_missing("./.gitattributes", /^.multirepo.lock .*/, ".multirepo.lock merge=ours")
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
83
85
  Console.log_substep("Updated .gitattributes file")
84
86
  end
85
87
 
@@ -88,6 +90,28 @@ module MultiRepo
88
90
  Console.log_substep("Updated .git/config file")
89
91
  end
90
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
+
91
115
  def check_repo_exists
92
116
  if !Dir.exists?(@repo.path) then raise MultiRepoException, "There is no folder at path '#{@repo.path}'" end
93
117
  if !@repo.exists? then raise MultiRepoException, "'#{@repo.path}' is not a repository" end
@@ -19,7 +19,7 @@ module MultiRepo
19
19
 
20
20
  def run
21
21
  super
22
- validate_in_work_tree
22
+ ensure_in_work_tree
23
23
  ensure_multirepo_tracked
24
24
 
25
25
  if @hooks
@@ -43,7 +43,7 @@ module MultiRepo
43
43
 
44
44
  def install_dependencies_step
45
45
  # Read config entries as-is on disk, without prior checkout
46
- config_entries = ConfigFile.load
46
+ config_entries = ConfigFile.load_entries
47
47
  Console.log_substep("Installing #{config_entries.count} dependencies...");
48
48
 
49
49
  # Clone or fetch all configured dependencies to make sure nothing is missing locally
@@ -10,10 +10,10 @@ module MultiRepo
10
10
 
11
11
  def run
12
12
  super
13
- validate_in_work_tree
13
+ ensure_in_work_tree
14
14
  ensure_multirepo_enabled
15
15
 
16
- ConfigFile.load.each do |entry|
16
+ ConfigFile.load_entries.each do |entry|
17
17
  if OS.osx?
18
18
  `open "#{entry.repo.path}"`
19
19
  elsif OS.windows?
@@ -26,7 +26,7 @@ module MultiRepo
26
26
 
27
27
  def run
28
28
  super
29
- validate_in_work_tree
29
+ ensure_in_work_tree
30
30
  ensure_multirepo_enabled
31
31
 
32
32
  repo = Repo.new(@path)
@@ -7,10 +7,10 @@ module MultiRepo
7
7
 
8
8
  def run
9
9
  super
10
- validate_in_work_tree
10
+ ensure_in_work_tree
11
11
 
12
- File.delete(".multirepo")
13
- File.delete(".multirepo.lock")
12
+ FileUtils.rm_f(".multirepo")
13
+ TrackingFiles.delete
14
14
  uninstall_hooks
15
15
 
16
16
  Console.log_step("All traces of multirepo have been removed from this repository")
@@ -1,14 +1,15 @@
1
1
  require "multirepo/utility/console"
2
+ require "multirepo/files/tracking-files"
2
3
 
3
4
  module MultiRepo
4
5
  class UpdateCommand < Command
5
6
  self.command = "update"
6
- self.summary = "Force-updates the multirepo lock file."
7
+ self.summary = "Force-updates the multirepo tracking files."
7
8
 
8
9
  def self.options
9
10
  [
10
- ['[--force]', 'Update the lock file even if dependencies contain uncommitted changes.'],
11
- ['[--commit]', 'Commit the lock file after updating it.']
11
+ ['[--force]', 'Update the tracking files even if dependencies contain uncommitted changes.'],
12
+ ['[--commit]', 'Commit the tracking files after updating them.']
12
13
  ].concat(super)
13
14
  end
14
15
 
@@ -20,16 +21,16 @@ module MultiRepo
20
21
 
21
22
  def run
22
23
  super
23
- validate_in_work_tree
24
+ ensure_in_work_tree
24
25
  ensure_multirepo_enabled
25
26
 
26
27
  Console.log_step("Updating...")
27
28
 
28
- dependencies_clean = Utils.ensure_dependencies_clean(ConfigFile.load)
29
+ dependencies_clean = Utils.ensure_dependencies_clean(ConfigFile.load_entries)
29
30
  if dependencies_clean
30
- update_lock_file_step("Updated lock file with latest dependency commits")
31
+ update_lock_file_step("Updated tracking files")
31
32
  elsif !dependencies_clean && @force
32
- update_lock_file_step("Force-updated lock file with latest dependency commits (ignoring uncommitted changes)")
33
+ update_lock_file_step("Force-updated tracking files (ignoring uncommitted changes)")
33
34
  else
34
35
  raise MultiRepoException, "Can't update because not all dependencies are clean"
35
36
  end
@@ -40,15 +41,19 @@ module MultiRepo
40
41
  end
41
42
 
42
43
  def update_lock_file_step(log_message)
43
- changed = LockFile.update
44
+ changed = TrackingFiles.update
44
45
 
45
- if changed && @commit
46
- Console.log_substep("Committing updated lock file")
47
- LockFile.commit("[multirepo] Manually updated lock file")
46
+ if changed
47
+ Console.log_substep("Updated tracking files")
48
+ else
49
+ Console.log_substep("Tracking files are already up-to-date")
50
+ end
51
+
52
+ if @commit
53
+ committed = TrackingFiles.commit("[multirepo] Updated tracking files manually")
54
+ Console.log_substep("Committed tracking files") if committed
48
55
  elsif changed
49
56
  Console.log_substep(log_message)
50
- else
51
- Console.log_info("Lock file is already up-to-date")
52
57
  end
53
58
  end
54
59
  end
@@ -6,17 +6,18 @@ require_relative "config-entry"
6
6
  module MultiRepo
7
7
  class ConfigFile
8
8
  FILE = Pathname.new(".multirepo")
9
+ FILENAME = FILE.to_s
9
10
 
10
11
  def self.exists?
11
12
  FILE.exist?
12
13
  end
13
14
 
14
- def self.load
15
+ def self.load_entries
15
16
  Psych.load(FILE.read)
16
17
  end
17
18
 
18
- def self.save(entries)
19
- File.write(FILE.to_s, Psych.dump(entries))
19
+ def self.save_entries(entries)
20
+ File.write(FILENAME, Psych.dump(entries))
20
21
  end
21
22
 
22
23
  def self.entry_exists?(entry)
@@ -2,44 +2,28 @@ require "pathname"
2
2
  require "psych"
3
3
 
4
4
  require "multirepo/git/git"
5
+ require_relative "tracking-file"
5
6
  require_relative "lock-entry"
6
7
  require_relative "config-file"
7
8
 
8
9
  module MultiRepo
9
- class LockFile
10
+ class LockFile < TrackingFile
10
11
  FILE = Pathname.new(".multirepo.lock")
12
+ FILENAME = FILE.to_s
11
13
 
12
14
  def self.exists?
13
15
  FILE.exist?
14
16
  end
15
17
 
16
- def self.load
18
+ def self.load_entries
17
19
  Psych.load(FILE.read)
18
20
  end
19
21
 
20
22
  def self.update
21
- config_entries = ConfigFile.load
23
+ config_entries = ConfigFile.load_entries
22
24
  lock_entries = config_entries.map { |c| LockEntry.new(c) }
23
-
24
- old_content = File.read(FILE.to_s)
25
- new_content = Psych.dump(lock_entries)
26
- File.write(FILE.to_s, new_content)
27
-
28
- return new_content != old_content
29
- end
30
-
31
- def self.stage
32
- Git.run_in_current_dir("add -A #{FILE.to_s}", Runner::Verbosity::OUTPUT_ON_ERROR)
33
- end
34
-
35
- def self.commit(message)
36
- Git.run_in_current_dir("commit -m \"#{message}\" -o -- #{FILE.to_s}", Runner::Verbosity::OUTPUT_ON_ERROR)
37
- end
38
-
39
- def self.validate_components(line, components)
40
- unless components.count == 2
41
- raise MultiRepoException, "Wrong entry format in .multirepo.lock file: #{line}"
42
- end
25
+ content = Psych.dump(lock_entries)
26
+ return update_internal(FILENAME, content)
43
27
  end
44
28
  end
45
29
  end
@@ -0,0 +1,34 @@
1
+ require "pathname"
2
+ require "psych"
3
+
4
+ require "info"
5
+ require "multirepo/git/git"
6
+ require_relative "tracking-file"
7
+ require_relative "lock-entry"
8
+ require_relative "config-file"
9
+
10
+ module MultiRepo
11
+ class MetaFile < TrackingFile
12
+ FILE = Pathname.new(".multirepo.meta")
13
+ FILENAME = FILE.to_s
14
+
15
+ attr_accessor :version
16
+
17
+ def initialize
18
+ @version = MultiRepo::VERSION
19
+ end
20
+
21
+ def encode_with(coder)
22
+ coder["version"] = @version
23
+ end
24
+
25
+ def self.load
26
+ Psych.load(FILE.read)
27
+ end
28
+
29
+ def self.update
30
+ content = Psych.dump(MetaFile.new)
31
+ return update_internal(FILENAME, content)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ module MultiRepo
2
+ class TrackingFile
3
+ def self.update_internal(file, new_content)
4
+ old_content = File.exists?(file) ? File.read(file) : nil
5
+ File.write(file, new_content)
6
+ return new_content != old_content
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,44 @@
1
+ require "multirepo/git/git"
2
+ require_relative "meta-file"
3
+ require_relative "lock-file"
4
+
5
+ module MultiRepo
6
+ class TrackingFiles
7
+ FILE_CLASSES = [MetaFile, LockFile]
8
+
9
+ def self.update
10
+ updated = false
11
+ FILE_CLASSES.each do |file_class|
12
+ updated |= file_class.update
13
+ end
14
+ return updated
15
+ end
16
+
17
+ def self.stage
18
+ Git.run_in_current_dir("add --force -- #{files_pathspec}", Runner::Verbosity::OUTPUT_ON_ERROR)
19
+ end
20
+
21
+ def self.commit(message)
22
+ stage
23
+
24
+ output = Git.run_in_current_dir("ls-files --modified --others -- #{files_pathspec}", Runner::Verbosity::NEVER_OUTPUT)
25
+ files_are_untracked_or_modified = output.strip != ""
26
+
27
+ output = Git.run_in_current_dir("diff --name-only --cached -- #{files_pathspec}", Runner::Verbosity::NEVER_OUTPUT)
28
+ files_are_staged = output.strip != ""
29
+
30
+ must_commit = files_are_untracked_or_modified || files_are_staged
31
+ Git.run_in_current_dir("commit -m \"#{message}\" --only -- #{files_pathspec}", Runner::Verbosity::OUTPUT_ON_ERROR) if must_commit
32
+
33
+ return must_commit
34
+ end
35
+
36
+ def self.delete
37
+ FILE_CLASSES.each { |c| FileUtils.rm_f(c::FILENAME) }
38
+ end
39
+
40
+ def self.files_pathspec
41
+ FILE_CLASSES.map{ |c| c::FILENAME }.join(" ")
42
+ end
43
+ end
44
+ end
@@ -8,11 +8,6 @@ module MultiRepo
8
8
  attr_accessor :last_command_succeeded
9
9
  end
10
10
 
11
- def self.is_inside_git_repo(path)
12
- return false unless Dir.exist?("#{path}/.git")
13
- return Git.run_in_working_dir(path, "rev-parse --is-inside-work-tree", Runner::Verbosity::NEVER_OUTPUT).strip == "true"
14
- end
15
-
16
11
  def self.run_in_current_dir(git_command, verbosity)
17
12
  full_command = "#{git_executable} #{git_command}"
18
13
  run(full_command, verbosity)
@@ -30,7 +25,6 @@ module MultiRepo
30
25
  end
31
26
 
32
27
  def self.run(full_command, verbosity)
33
- Console.log_info(full_command) if Config.instance.verbose
34
28
  result = Runner.run(full_command, verbosity)
35
29
  @last_command_succeeded = Runner.last_command_succeeded
36
30
  return result
@@ -10,7 +10,8 @@ module MultiRepo
10
10
  end
11
11
 
12
12
  def url
13
- Git.run_in_working_dir(@repo.path, "config --get remote.#{@name}.url", Runner::Verbosity::NEVER_OUTPUT).strip
13
+ output = Git.run_in_working_dir(@repo.path, "config --get remote.#{@name}.url", Runner::Verbosity::NEVER_OUTPUT).strip
14
+ return output == "" ? nil : output
14
15
  end
15
16
  end
16
17
  end
@@ -16,7 +16,13 @@ module MultiRepo
16
16
  # Inspection
17
17
 
18
18
  def exists?
19
- Git.is_inside_git_repo(@path)
19
+ return false unless Dir.exist?("#{@path}/.git")
20
+ return Git.run_in_working_dir(@path, "rev-parse --is-inside-work-tree", Runner::Verbosity::NEVER_OUTPUT).strip == "true"
21
+ end
22
+
23
+ def head_born?
24
+ result = Git.run_in_working_dir(@path, "rev-parse HEAD --", Runner::Verbosity::NEVER_OUTPUT).strip
25
+ return !result.start_with?("fatal: bad revision")
20
26
  end
21
27
 
22
28
  def current_branch
@@ -1,5 +1,5 @@
1
1
  require "multirepo/files/config-file"
2
- require "multirepo/files/lock-file"
2
+ require "multirepo/files/tracking-files"
3
3
  require "multirepo/utility/utils"
4
4
  require "multirepo/utility/console"
5
5
 
@@ -10,16 +10,16 @@ module MultiRepo
10
10
 
11
11
  Console.log_step("Performing pre-commit operations...")
12
12
 
13
- dependencies_clean = Utils.ensure_dependencies_clean(ConfigFile.load)
13
+ dependencies_clean = Utils.ensure_dependencies_clean(ConfigFile.load_entries)
14
14
 
15
15
  if !dependencies_clean
16
16
  Console.log_error("You must commit changes to your dependencies before you can commit this repo")
17
17
  exit 1
18
18
  end
19
19
 
20
- LockFile.update
21
- LockFile.stage
22
- Console.log_info("Updated and staged lock file with current HEAD revisions for all dependencies")
20
+ TrackingFiles.update
21
+ TrackingFiles.stage
22
+ Console.log_info("Updated and staged tracking files")
23
23
 
24
24
  exit 0 # Success!
25
25
  rescue StandardError => e
@@ -14,10 +14,12 @@ module MultiRepo
14
14
  end
15
15
 
16
16
  def self.run(cmd, verbosity)
17
+ Console.log_info("Command: #{cmd}") if Config.instance.verbose
18
+
17
19
  lines = []
18
20
  Open3.popen2e(cmd) do |stdin, stdout_and_stderr, thread|
19
21
  stdout_and_stderr.each do |line|
20
- Console.log_info(line.rstrip) if verbosity == Verbosity::ALWAYS_OUTPUT || Config.instance.verbose
22
+ Console.log_info("-------> #{line.rstrip}") if verbosity == Verbosity::ALWAYS_OUTPUT || Config.instance.verbose
21
23
  lines << line
22
24
  end
23
25
  @last_command_succeeded = thread.value.success?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-multirepo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta31
4
+ version: 1.0.0.beta32
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michaël Fortin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-30 00:00:00.000000000 Z
11
+ date: 2015-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -112,6 +112,7 @@ files:
112
112
  - .gitignore
113
113
  - .multirepo
114
114
  - .multirepo.lock
115
+ - .multirepo.meta
115
116
  - .rspec
116
117
  - Gemfile
117
118
  - Gemfile.lock
@@ -142,6 +143,9 @@ files:
142
143
  - lib/multirepo/files/config-file.rb
143
144
  - lib/multirepo/files/lock-entry.rb
144
145
  - lib/multirepo/files/lock-file.rb
146
+ - lib/multirepo/files/meta-file.rb
147
+ - lib/multirepo/files/tracking-file.rb
148
+ - lib/multirepo/files/tracking-files.rb
145
149
  - lib/multirepo/git/branch.rb
146
150
  - lib/multirepo/git/change.rb
147
151
  - lib/multirepo/git/commit.rb