rhomobile-grit 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/grit/ref.rb ADDED
@@ -0,0 +1,78 @@
1
+ module Grit
2
+
3
+ class Ref
4
+
5
+ class << self
6
+
7
+ # Find all Refs
8
+ # +repo+ is the Repo
9
+ # +options+ is a Hash of options
10
+ #
11
+ # Returns Grit::Ref[] (baked)
12
+ def find_all(repo, options = {})
13
+ refs = repo.git.refs(options, prefix)
14
+ refs.split("\n").map do |ref|
15
+ name, id = *ref.split(' ')
16
+ commit = Commit.create(repo, :id => id)
17
+ self.new(name, commit)
18
+ end
19
+ end
20
+
21
+ protected
22
+
23
+ def prefix
24
+ "refs/#{name.to_s.gsub(/^.*::/, '').downcase}s"
25
+ end
26
+
27
+ end
28
+
29
+ attr_reader :name
30
+ attr_reader :commit
31
+
32
+ # Instantiate a new Head
33
+ # +name+ is the name of the head
34
+ # +commit+ is the Commit that the head points to
35
+ #
36
+ # Returns Grit::Head (baked)
37
+ def initialize(name, commit)
38
+ @name = name
39
+ @commit = commit
40
+ end
41
+
42
+ # Pretty object inspection
43
+ def inspect
44
+ %Q{#<#{self.class.name} "#{@name}">}
45
+ end
46
+ end # Ref
47
+
48
+ # A Head is a named reference to a Commit. Every Head instance contains a name
49
+ # and a Commit object.
50
+ #
51
+ # r = Grit::Repo.new("/path/to/repo")
52
+ # h = r.heads.first
53
+ # h.name # => "master"
54
+ # h.commit # => #<Grit::Commit "1c09f116cbc2cb4100fb6935bb162daa4723f455">
55
+ # h.commit.id # => "1c09f116cbc2cb4100fb6935bb162daa4723f455"
56
+ class Head < Ref
57
+
58
+ # Get the HEAD revision of the repo.
59
+ # +repo+ is the Repo
60
+ # +options+ is a Hash of options
61
+ #
62
+ # Returns Grit::Head (baked)
63
+ def self.current(repo, options = {})
64
+ head = repo.git.fs_read('HEAD').chomp
65
+ if /ref: refs\/heads\/(.*)/.match(head)
66
+ id = repo.git.rev_parse(options, 'HEAD')
67
+ commit = Commit.create(repo, :id => id)
68
+ self.new($1, commit)
69
+ end
70
+ end
71
+
72
+ end # Head
73
+
74
+ class Remote < Ref; end
75
+
76
+ class Note < Ref; end
77
+
78
+ end # Grit
data/lib/grit/repo.rb ADDED
@@ -0,0 +1,651 @@
1
+ module Grit
2
+
3
+ class Repo
4
+ DAEMON_EXPORT_FILE = 'git-daemon-export-ok'
5
+ BATCH_PARSERS = {
6
+ 'commit' => ::Grit::Commit
7
+ }
8
+
9
+ # Public: The String path of the Git repo.
10
+ attr_accessor :path
11
+
12
+ # Public: The String path to the working directory of the repo, or nil if
13
+ # there is no working directory.
14
+ attr_accessor :working_dir
15
+
16
+ # Public: The Boolean of whether or not the repo is bare.
17
+ attr_reader :bare
18
+
19
+ # Public: The Grit::Git command line interface object.
20
+ attr_accessor :git
21
+
22
+ # Public: Create a new Repo instance.
23
+ #
24
+ # path - The String path to either the root git directory or the bare
25
+ # git repo. Bare repos are expected to end with ".git".
26
+ # options - A Hash of options (default: {}):
27
+ # :is_bare - Boolean whether to consider the repo as bare even
28
+ # if the repo name does not end with ".git".
29
+ #
30
+ # Examples
31
+ #
32
+ # r = Repo.new("/Users/tom/dev/normal")
33
+ # r = Repo.new("/Users/tom/public/bare.git")
34
+ # r = Repo.new("/Users/tom/public/bare", {:is_bare => true})
35
+ #
36
+ # Returns a newly initialized Grit::Repo.
37
+ # Raises Grit::InvalidGitRepositoryError if the path exists but is not
38
+ # a Git repository.
39
+ # Raises Grit::NoSuchPathError if the path does not exist.
40
+ def initialize(path, options = {})
41
+ epath = File.expand_path(path)
42
+
43
+ if File.exist?(File.join(epath, '.git'))
44
+ self.working_dir = epath
45
+ self.path = File.join(epath, '.git')
46
+ @bare = false
47
+ elsif File.exist?(epath) && (epath =~ /\.git$/ || options[:is_bare])
48
+ self.path = epath
49
+ @bare = true
50
+ elsif File.exist?(epath)
51
+ raise InvalidGitRepositoryError.new(epath)
52
+ else
53
+ raise NoSuchPathError.new(epath)
54
+ end
55
+
56
+ self.git = Git.new(self.path)
57
+ end
58
+
59
+ # Public: Initialize a git repository (create it on the filesystem). By
60
+ # default, the newly created repository will contain a working directory.
61
+ # If you would like to create a bare repo, use Grit::Repo.init_bare.
62
+ #
63
+ # path - The String full path to the repo. Traditionally ends with
64
+ # "/<name>.git".
65
+ # git_options - A Hash of additional options to the git init command
66
+ # (default: {}).
67
+ # repo_options - A Hash of additional options to the Grit::Repo.new call
68
+ # (default: {}).
69
+ #
70
+ # Examples
71
+ #
72
+ # Grit::Repo.init('/var/git/myrepo.git')
73
+ #
74
+ # Returns the newly created Grit::Repo.
75
+ def self.init(path, git_options = {}, repo_options = {})
76
+ git_options = {:base => false}.merge(git_options)
77
+ git = Git.new(path)
78
+ git.fs_mkdir('..')
79
+ git.init(git_options, path)
80
+ self.new(path, repo_options)
81
+ end
82
+
83
+ # Public: Initialize a bare git repository (create it on the filesystem).
84
+ #
85
+ # path - The String full path to the repo. Traditionally ends with
86
+ # "/<name>.git".
87
+ # git_options - A Hash of additional options to the git init command
88
+ # (default: {}).
89
+ # repo_options - A Hash of additional options to the Grit::Repo.new call
90
+ # (default: {}).
91
+ #
92
+ # Examples
93
+ #
94
+ # Grit::Repo.init_bare('/var/git/myrepo.git')
95
+ #
96
+ # Returns the newly created Grit::Repo.
97
+ def self.init_bare(path, git_options = {}, repo_options = {})
98
+ git_options = {:bare => true}.merge(git_options)
99
+ git = Git.new(path)
100
+ git.fs_mkdir('..')
101
+ git.init(git_options)
102
+ repo_options = {:is_bare => true}.merge(repo_options)
103
+ self.new(path, repo_options)
104
+ end
105
+
106
+ # Public: Initialize a bare Git repository (create it on the filesystem)
107
+ # or, if the repo already exists, simply return it.
108
+ #
109
+ # path - The String full path to the repo. Traditionally ends with
110
+ # "/<name>.git".
111
+ # git_options - A Hash of additional options to the git init command
112
+ # (default: {}).
113
+ # repo_options - A Hash of additional options to the Grit::Repo.new call
114
+ # (default: {}).
115
+ #
116
+ # Returns the new or existing Grit::Repo.
117
+ def self.init_bare_or_open(path, git_options = {}, repo_options = {})
118
+ git = Git.new(path)
119
+
120
+ unless git.exist?
121
+ git.fs_mkdir(path)
122
+ git.init(git_options)
123
+ end
124
+
125
+ self.new(path, repo_options)
126
+ end
127
+
128
+ # Public: Create a bare fork of this repository.
129
+ #
130
+ # path - The String full path of where to create the new fork.
131
+ # Traditionally ends with "/<name>.git".
132
+ # options - The Hash of additional options to the git clone command.
133
+ # These options will be merged on top of the default Hash:
134
+ # {:bare => true, :shared => true}.
135
+ #
136
+ # Returns the newly forked Grit::Repo.
137
+ def fork_bare(path, options = {})
138
+ default_options = {:bare => true, :shared => true}
139
+ real_options = default_options.merge(options)
140
+ Git.new(path).fs_mkdir('..')
141
+ self.git.clone(real_options, self.path, path)
142
+ Repo.new(path)
143
+ end
144
+
145
+ # Public: Fork a bare git repository from another repo.
146
+ #
147
+ # path - The String full path of the repo from which to fork..
148
+ # Traditionally ends with "/<name>.git".
149
+ # options - The Hash of additional options to the git clone command.
150
+ # These options will be merged on top of the default Hash:
151
+ # {:bare => true, :shared => true}.
152
+ #
153
+ # Returns the newly forked Grit::Repo.
154
+ def fork_bare_from(path, options = {})
155
+ default_options = {:bare => true, :shared => true}
156
+ real_options = default_options.merge(options)
157
+ Git.new(self.path).fs_mkdir('..')
158
+ self.git.clone(real_options, path, self.path)
159
+ Repo.new(self.path)
160
+ end
161
+
162
+ # Public: Return the full Git objects from the given SHAs. Only Commit
163
+ # objects are parsed for now.
164
+ #
165
+ # *shas - Array of String SHAs.
166
+ #
167
+ # Returns an Array of Grit objects (Grit::Commit).
168
+ def batch(*shas)
169
+ shas.flatten!
170
+ text = git.native(:cat_file, {:batch => true, :input => (shas * "\n")})
171
+ parse_batch(text)
172
+ end
173
+
174
+ # Parses `git cat-file --batch` output, returning an array of Grit objects.
175
+ #
176
+ # text - Raw String output.
177
+ #
178
+ # Returns an Array of Grit objects (Grit::Commit).
179
+ def parse_batch(text)
180
+ io = StringIO.new(text)
181
+ objects = []
182
+ while line = io.gets
183
+ sha, type, size = line.split(" ", 3)
184
+ parser = BATCH_PARSERS[type]
185
+ if type == 'missing' || !parser
186
+ objects << nil
187
+ next
188
+ end
189
+
190
+ object = io.read(size.to_i + 1)
191
+ objects << parser.parse_batch(self, sha, size, object)
192
+ end
193
+ objects
194
+ end
195
+
196
+ # The project's description. Taken verbatim from GIT_REPO/description
197
+ #
198
+ # Returns String
199
+ def description
200
+ self.git.fs_read('description').chomp
201
+ end
202
+
203
+ def blame(file, commit = nil)
204
+ Blame.new(self, file, commit)
205
+ end
206
+
207
+ # An array of Head objects representing the branch heads in
208
+ # this repo
209
+ #
210
+ # Returns Grit::Head[] (baked)
211
+ def heads
212
+ Head.find_all(self)
213
+ end
214
+
215
+ alias_method :branches, :heads
216
+
217
+ def get_head(head_name)
218
+ heads.find { |h| h.name == head_name }
219
+ end
220
+
221
+ def is_head?(head_name)
222
+ get_head(head_name)
223
+ end
224
+
225
+ # Object reprsenting the current repo head.
226
+ #
227
+ # Returns Grit::Head (baked)
228
+ def head
229
+ Head.current(self)
230
+ end
231
+
232
+
233
+ # Commits current index
234
+ #
235
+ # Returns true/false if commit worked
236
+ def commit_index(message)
237
+ self.git.commit({}, '-m', message)
238
+ end
239
+
240
+ # Commits all tracked and modified files
241
+ #
242
+ # Returns true/false if commit worked
243
+ def commit_all(message)
244
+ self.git.commit({}, '-a', '-m', message)
245
+ end
246
+
247
+ # Adds files to the index
248
+ def add(*files)
249
+ self.git.add({}, *files.flatten)
250
+ end
251
+
252
+ # Remove files from the index
253
+ def remove(*files)
254
+ self.git.rm({}, *files.flatten)
255
+ end
256
+
257
+
258
+ def blame_tree(commit, path = nil)
259
+ commit_array = self.git.blame_tree(commit, path)
260
+
261
+ final_array = {}
262
+ commit_array.each do |file, sha|
263
+ final_array[file] = commit(sha)
264
+ end
265
+ final_array
266
+ end
267
+
268
+ def status
269
+ Status.new(self)
270
+ end
271
+
272
+
273
+ # An array of Tag objects that are available in this repo
274
+ #
275
+ # Returns Grit::Tag[] (baked)
276
+ def tags
277
+ Tag.find_all(self)
278
+ end
279
+
280
+ # Finds the most recent annotated tag name that is reachable from a commit.
281
+ #
282
+ # @repo.recent_tag_name('master')
283
+ # # => "v1.0-0-abcdef"
284
+ #
285
+ # committish - optional commit SHA, branch, or tag name.
286
+ # options - optional hash of options to pass to git.
287
+ # Default: {:always => true}
288
+ # :tags => true # use lightweight tags too.
289
+ # :abbrev => Integer # number of hex digits to form the unique
290
+ # name. Defaults to 7.
291
+ # :long => true # always output tag + commit sha
292
+ # # see `git describe` docs for more options.
293
+ #
294
+ # Returns the String tag name, or just the commit if no tag is
295
+ # found. If there have been updates since the tag was made, a
296
+ # suffix is added with the number of commits since the tag, and
297
+ # the abbreviated object name of the most recent commit.
298
+ # Returns nil if the committish value is not found.
299
+ def recent_tag_name(committish = nil, options = {})
300
+ value = git.describe({:always => true}.update(options), committish.to_s).to_s.strip
301
+ value.size.zero? ? nil : value
302
+ end
303
+
304
+ # An array of Remote objects representing the remote branches in
305
+ # this repo
306
+ #
307
+ # Returns Grit::Remote[] (baked)
308
+ def remotes
309
+ Remote.find_all(self)
310
+ end
311
+
312
+ def remote_list
313
+ self.git.list_remotes
314
+ end
315
+
316
+ def remote_add(name, url)
317
+ self.git.remote({}, 'add', name, url)
318
+ end
319
+
320
+ def remote_fetch(name)
321
+ self.git.fetch({}, name)
322
+ end
323
+
324
+ # takes an array of remote names and last pushed dates
325
+ # fetches from all of the remotes where the local fetch
326
+ # date is earlier than the passed date, then records the
327
+ # last fetched date
328
+ #
329
+ # { 'origin' => date,
330
+ # 'peter => date,
331
+ # }
332
+ def remotes_fetch_needed(remotes)
333
+ remotes.each do |remote, date|
334
+ # TODO: check against date
335
+ self.remote_fetch(remote)
336
+ end
337
+ end
338
+
339
+
340
+ # An array of Ref objects representing the refs in
341
+ # this repo
342
+ #
343
+ # Returns Grit::Ref[] (baked)
344
+ def refs
345
+ [ Head.find_all(self), Tag.find_all(self), Remote.find_all(self) ].flatten
346
+ end
347
+
348
+ def commit_stats(start = 'master', max_count = 10, skip = 0)
349
+ options = {:max_count => max_count,
350
+ :skip => skip}
351
+
352
+ CommitStats.find_all(self, start, options)
353
+ end
354
+
355
+ # An array of Commit objects representing the history of a given ref/commit
356
+ # +start+ is the branch/commit name (default 'master')
357
+ # +max_count+ is the maximum number of commits to return (default 10, use +false+ for all)
358
+ # +skip+ is the number of commits to skip (default 0)
359
+ #
360
+ # Returns Grit::Commit[] (baked)
361
+ def commits(start = 'master', max_count = 10, skip = 0)
362
+ options = {:max_count => max_count,
363
+ :skip => skip}
364
+
365
+ Commit.find_all(self, start, options)
366
+ end
367
+
368
+ # The Commits objects that are reachable via +to+ but not via +from+
369
+ # Commits are returned in chronological order.
370
+ # +from+ is the branch/commit name of the younger item
371
+ # +to+ is the branch/commit name of the older item
372
+ #
373
+ # Returns Grit::Commit[] (baked)
374
+ def commits_between(from, to)
375
+ Commit.find_all(self, "#{from}..#{to}").reverse
376
+ end
377
+
378
+ # The Commits objects that are newer than the specified date.
379
+ # Commits are returned in chronological order.
380
+ # +start+ is the branch/commit name (default 'master')
381
+ # +since+ is a string represeting a date/time
382
+ # +extra_options+ is a hash of extra options
383
+ #
384
+ # Returns Grit::Commit[] (baked)
385
+ def commits_since(start = 'master', since = '1970-01-01', extra_options = {})
386
+ options = {:since => since}.merge(extra_options)
387
+
388
+ Commit.find_all(self, start, options)
389
+ end
390
+
391
+ # The number of commits reachable by the given branch/commit
392
+ # +start+ is the branch/commit name (default 'master')
393
+ #
394
+ # Returns Integer
395
+ def commit_count(start = 'master')
396
+ Commit.count(self, start)
397
+ end
398
+
399
+ # The Commit object for the specified id
400
+ # +id+ is the SHA1 identifier of the commit
401
+ #
402
+ # Returns Grit::Commit (baked)
403
+ def commit(id)
404
+ options = {:max_count => 1}
405
+
406
+ Commit.find_all(self, id, options).first
407
+ end
408
+
409
+ # Returns a list of commits that is in +other_repo+ but not in self
410
+ #
411
+ # Returns Grit::Commit[]
412
+ def commit_deltas_from(other_repo, ref = "master", other_ref = "master")
413
+ # TODO: we should be able to figure out the branch point, rather than
414
+ # rev-list'ing the whole thing
415
+ repo_refs = self.git.rev_list({}, ref).strip.split("\n")
416
+ other_repo_refs = other_repo.git.rev_list({}, other_ref).strip.split("\n")
417
+
418
+ (other_repo_refs - repo_refs).map do |ref|
419
+ Commit.find_all(other_repo, ref, {:max_count => 1}).first
420
+ end
421
+ end
422
+
423
+ def objects(refs)
424
+ refs = refs.split(/\s+/) if refs.respond_to?(:to_str)
425
+ self.git.rev_list({:objects => true, :timeout => false}, *refs).
426
+ split("\n").map { |a| a[0, 40] }
427
+ end
428
+
429
+ def commit_objects(refs)
430
+ refs = refs.split(/\s+/) if refs.respond_to?(:to_str)
431
+ self.git.rev_list({:timeout => false}, *refs).split("\n").map { |a| a[0, 40] }
432
+ end
433
+
434
+ def objects_between(ref1, ref2 = nil)
435
+ if ref2
436
+ refs = "#{ref2}..#{ref1}"
437
+ else
438
+ refs = ref1
439
+ end
440
+ self.objects(refs)
441
+ end
442
+
443
+ def diff_objects(commit_sha, parents = true)
444
+ revs = []
445
+ Grit.no_quote = true
446
+ if parents
447
+ # PARENTS:
448
+ revs = self.git.diff_tree({:timeout => false, :r => true, :t => true, :m => true}, commit_sha).
449
+ strip.split("\n").map{ |a| r = a.split(' '); r[3] if r[1] != '160000' }
450
+ else
451
+ # NO PARENTS:
452
+ revs = self.git.native(:ls_tree, {:timeout => false, :r => true, :t => true}, commit_sha).
453
+ split("\n").map{ |a| a.split("\t").first.split(' ')[2] }
454
+ end
455
+ revs << self.commit(commit_sha).tree.id
456
+ Grit.no_quote = false
457
+ return revs.uniq.compact
458
+ end
459
+
460
+ # The Tree object for the given treeish reference
461
+ # +treeish+ is the reference (default 'master')
462
+ # +paths+ is an optional Array of directory paths to restrict the tree (deafult [])
463
+ #
464
+ # Examples
465
+ # repo.tree('master', ['lib/'])
466
+ #
467
+ # Returns Grit::Tree (baked)
468
+ def tree(treeish = 'master', paths = [])
469
+ Tree.construct(self, treeish, paths)
470
+ end
471
+
472
+ # The Blob object for the given id
473
+ # +id+ is the SHA1 id of the blob
474
+ #
475
+ # Returns Grit::Blob (unbaked)
476
+ def blob(id)
477
+ Blob.create(self, :id => id)
478
+ end
479
+
480
+ # The commit log for a treeish
481
+ #
482
+ # Returns Grit::Commit[]
483
+ def log(commit = 'master', path = nil, options = {})
484
+ default_options = {:pretty => "raw"}
485
+ actual_options = default_options.merge(options)
486
+ arg = path ? [commit, '--', path] : [commit]
487
+ commits = self.git.log(actual_options, *arg)
488
+ Commit.list_from_string(self, commits)
489
+ end
490
+
491
+ # The diff from commit +a+ to commit +b+, optionally restricted to the given file(s)
492
+ # +a+ is the base commit
493
+ # +b+ is the other commit
494
+ # +paths+ is an optional list of file paths on which to restrict the diff
495
+ def diff(a, b, *paths)
496
+ diff = self.git.native('diff', {}, a, b, '--', *paths)
497
+
498
+ if diff =~ /diff --git a/
499
+ diff = diff.sub(/.*?(diff --git a)/m, '\1')
500
+ else
501
+ diff = ''
502
+ end
503
+ Diff.list_from_string(self, diff)
504
+ end
505
+
506
+ # The commit diff for the given commit
507
+ # +commit+ is the commit name/id
508
+ #
509
+ # Returns Grit::Diff[]
510
+ def commit_diff(commit)
511
+ Commit.diff(self, commit)
512
+ end
513
+
514
+ # Archive the given treeish
515
+ # +treeish+ is the treeish name/id (default 'master')
516
+ # +prefix+ is the optional prefix
517
+ #
518
+ # Examples
519
+ # repo.archive_tar
520
+ # # => <String containing tar archive>
521
+ #
522
+ # repo.archive_tar('a87ff14')
523
+ # # => <String containing tar archive for commit a87ff14>
524
+ #
525
+ # repo.archive_tar('master', 'myproject/')
526
+ # # => <String containing tar archive and prefixed with 'myproject/'>
527
+ #
528
+ # Returns String (containing tar archive)
529
+ def archive_tar(treeish = 'master', prefix = nil)
530
+ options = {}
531
+ options[:prefix] = prefix if prefix
532
+ self.git.archive(options, treeish)
533
+ end
534
+
535
+ # Archive and gzip the given treeish
536
+ # +treeish+ is the treeish name/id (default 'master')
537
+ # +prefix+ is the optional prefix
538
+ #
539
+ # Examples
540
+ # repo.archive_tar_gz
541
+ # # => <String containing tar.gz archive>
542
+ #
543
+ # repo.archive_tar_gz('a87ff14')
544
+ # # => <String containing tar.gz archive for commit a87ff14>
545
+ #
546
+ # repo.archive_tar_gz('master', 'myproject/')
547
+ # # => <String containing tar.gz archive and prefixed with 'myproject/'>
548
+ #
549
+ # Returns String (containing tar.gz archive)
550
+ def archive_tar_gz(treeish = 'master', prefix = nil)
551
+ options = {}
552
+ options[:prefix] = prefix if prefix
553
+ self.git.archive(options, treeish, "| gzip -n")
554
+ end
555
+
556
+ # Write an archive directly to a file
557
+ # +treeish+ is the treeish name/id (default 'master')
558
+ # +prefix+ is the optional prefix (default nil)
559
+ # +filename+ is the name of the file (default 'archive.tar.gz')
560
+ # +format+ is the optional format (default nil)
561
+ # +pipe+ is the command to run the output through (default 'gzip')
562
+ #
563
+ # Returns nothing
564
+ def archive_to_file(treeish = 'master', prefix = nil, filename = 'archive.tar.gz', format = nil, pipe = "gzip")
565
+ options = {}
566
+ options[:prefix] = prefix if prefix
567
+ options[:format] = format if format
568
+ self.git.archive(options, treeish, "| #{pipe} > #{filename}")
569
+ end
570
+
571
+ # Enable git-daemon serving of this repository by writing the
572
+ # git-daemon-export-ok file to its git directory
573
+ #
574
+ # Returns nothing
575
+ def enable_daemon_serve
576
+ self.git.fs_write(DAEMON_EXPORT_FILE, '')
577
+ end
578
+
579
+ # Disable git-daemon serving of this repository by ensuring there is no
580
+ # git-daemon-export-ok file in its git directory
581
+ #
582
+ # Returns nothing
583
+ def disable_daemon_serve
584
+ self.git.fs_delete(DAEMON_EXPORT_FILE)
585
+ end
586
+
587
+ def gc_auto
588
+ self.git.gc({:auto => true})
589
+ end
590
+
591
+ # The list of alternates for this repo
592
+ #
593
+ # Returns Array[String] (pathnames of alternates)
594
+ def alternates
595
+ alternates_path = "objects/info/alternates"
596
+ self.git.fs_read(alternates_path).strip.split("\n")
597
+ rescue Errno::ENOENT
598
+ []
599
+ end
600
+
601
+ # Sets the alternates
602
+ # +alts+ is the Array of String paths representing the alternates
603
+ #
604
+ # Returns nothing
605
+ def alternates=(alts)
606
+ alts.each do |alt|
607
+ unless File.exist?(alt)
608
+ raise "Could not set alternates. Alternate path #{alt} must exist"
609
+ end
610
+ end
611
+
612
+ if alts.empty?
613
+ self.git.fs_write('objects/info/alternates', '')
614
+ else
615
+ self.git.fs_write('objects/info/alternates', alts.join("\n"))
616
+ end
617
+ end
618
+
619
+ def config
620
+ @config ||= Config.new(self)
621
+ end
622
+
623
+ def index
624
+ Index.new(self)
625
+ end
626
+
627
+ def update_ref(head, commit_sha)
628
+ return nil if !commit_sha || (commit_sha.size != 40)
629
+ self.git.fs_write("refs/heads/#{head}", commit_sha)
630
+ commit_sha
631
+ end
632
+
633
+ # Rename the current repository directory.
634
+ # +name+ is the new name
635
+ #
636
+ # Returns nothing
637
+ def rename(name)
638
+ if @bare
639
+ self.git.fs_move('/', "../#{name}")
640
+ else
641
+ self.git.fs_move('/', "../../#{name}")
642
+ end
643
+ end
644
+
645
+ # Pretty object inspection
646
+ def inspect
647
+ %Q{#<Grit::Repo "#{@path}">}
648
+ end
649
+ end # Repo
650
+
651
+ end # Grit