Class: ReaPack::Index::Git

Inherits:
Object
  • Object
show all
Defined in:
lib/reapack/index/git.rb

Defined Under Namespace

Classes: Commit, Diff

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Git

Returns a new instance of Git.



3
4
5
6
7
8
9
10
# File 'lib/reapack/index/git.rb', line 3

def initialize(path)
  @repo = Rugged::Repository.discover path.encode(Encoding::UTF_8)

  if @repo.bare?
    raise ReaPack::Index::Error,
      'reapack-index cannot be run in a repository without a work tree'
  end
end

Instance Method Details

#commitsObject



21
22
23
# File 'lib/reapack/index/git.rb', line 21

def commits
  @commits ||= commits_since nil
end

#commits_since(sha) ⇒ Object



25
26
27
28
29
30
31
32
33
34
# File 'lib/reapack/index/git.rb', line 25

def commits_since(sha)
  return [] if empty?

  walker = Rugged::Walker.new @repo
  walker.sorting Rugged::SORT_TOPO | Rugged::SORT_REVERSE
  walker.hide sha if fetch_commit sha
  walker.push @repo.head.target_id

  walker.map {|c| Commit.new c, @repo }
end

#create_commit(message, files) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/reapack/index/git.rb', line 88

def create_commit(message, files)
  old_index = @repo.index
  target = empty? ? nil : @repo.head.target

  if target
    old_index.read_tree target.tree
  else
    old_index.clear
  end

  new_index = @repo.index
  files.each {|f|
    if File.exist? f
      new_index.add relative_path(f)
    else
      new_index.remove relative_path(f)
    end
  }

  hash = Rugged::Commit.create @repo,
    tree: new_index.write_tree(@repo),
    message: message,
    parents: [target].compact,
    update_ref: 'HEAD'

  old_index.write

  # force-reload the repository
  @repo = Rugged::Repository.discover path

  commit = get_commit hash
  @commits << commit if @commits
  commit
end

#empty?Boolean

Returns:

  • (Boolean)


12
13
14
15
# File 'lib/reapack/index/git.rb', line 12

def empty?
  # head_unborn = orphan branch – FIXME: add test for this case
  @repo.empty? || @repo.head_unborn?
end

#get_commit(sha) ⇒ Object



36
37
38
39
# File 'lib/reapack/index/git.rb', line 36

def get_commit(sha)
  c = fetch_commit sha
  Commit.new c, @repo if c
end

#guess_url_templateObject



66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/reapack/index/git.rb', line 66

def guess_url_template
  remote = @repo.remotes['origin']
  return unless remote

  uri = Gitable::URI.parse remote.url
  return unless uri.path =~ /\A\/?(?<user>[^\/]+)\/(?<repo>[^\/]+)(\.git|\/)?\Z/

  tpl = uri.to_web_uri
  tpl.path = tpl.path.chomp '/'
  tpl.path += '/raw/$commit/$path'

  tpl.to_s
end

#last_commitObject



41
42
43
44
# File 'lib/reapack/index/git.rb', line 41

def last_commit
  c = @repo.last_commit
  Commit.new c, @repo if c
end

#last_commit_for(file) ⇒ Object



46
47
48
49
50
# File 'lib/reapack/index/git.rb', line 46

def last_commit_for(file)
  commits.reverse_each.find {|c|
    c.each_diff.any? {|d| d.file == file }
  }
end

#last_commits_for(pattern) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/reapack/index/git.rb', line 52

def last_commits_for(pattern)
  dir = pattern.empty? ? '' : pattern + '/'
  out = Hash.new
  last_commit.filelist.each {|file|
    path = File.split(file).first + '/'
    next unless path.start_with?(dir) || file == pattern

    commit = last_commit_for(file)
    out[commit] ||= Array.new
    out[commit] << file
  }
  out
end

#pathObject



17
18
19
# File 'lib/reapack/index/git.rb', line 17

def path
  @path ||= File.expand_path @repo.workdir
end

#relative_path(path) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/reapack/index/git.rb', line 80

def relative_path(path)
  root = Pathname.new self.path
  file = Pathname.new File.expand_path(path)

  rel = file.relative_path_from(root).to_s
  rel == '.' ? '' : rel
end