Module: GitDump::Repo::Git
- Included in:
- Rugged
- Defined in:
- lib/git_dump/repo/git.rb
Overview
Interface to git using system calls and pipes
Defined Under Namespace
Modules: ClassMethods Classes: InitException
Constant Summary collapse
- TAG_ENTRIES_FIELDS =
%w[ %(objecttype)%00 %(objectname)%00 %(refname)%00 %(authordate:rfc2822)%(*authordate:rfc2822)%00 %(committerdate:rfc2822)%(*committerdate:rfc2822)%00 %(contents)%00 %(*contents)%00 ].freeze
Class Method Summary collapse
Instance Method Summary collapse
-
#blob_pipe(sha, &block) ⇒ Object
Return pipe with contents of blob identified by sha.
-
#blob_read(sha, io = nil) ⇒ Object
Return contents of blob identified by sha If io is specified, then content will be written to io.
-
#blob_unpack(sha, path, mode) ⇒ Object
Write contents of blob to file at path and set its mode.
-
#commit(tree_sha, options = {}) ⇒ Object
Create commit for tree_sha, return sha options: :time => author date (by default now) :message => commit message (by default empty).
-
#data_sha(content) ⇒ Object
Add blob for content to repository, return sha.
-
#fetch(url, id, options = {}) ⇒ Object
Receive tag with name id from repo at url Use :progress => true to show progress.
-
#gc(options = {}) ⇒ Object
Run garbage collection Use :auto => true to run only if GC is required Use :aggressive => true to run GC more aggressively.
-
#path_sha(path) ⇒ Object
Add blob for content at path to repository, return sha.
-
#push(url, id, options = {}) ⇒ Object
Send tag with name id to repo at url Use :progress => true to show progress.
-
#remove_tag(id) ⇒ Object
Remove tag with name id.
-
#size(sha) ⇒ Object
Return size of object identified by sha.
-
#tag(commit_sha, name_parts, options = {}) ⇒ Object
Create tag for commit_sha with name constructed from name_parts, return name.
-
#tag_entries ⇒ Object
Return list of entries per tag ref Each entry is a hash with following keys: :sha => tag or commit sha :name => ref name.
-
#tree_entries(sha) ⇒ Object
Read tree at sha returning list of entries Each entry is a hash like one for treeify.
-
#treeify(entries) ⇒ Object
Add blob for entries to repository, return sha Each entry is a hash with following keys: :type => :blob or :tree :name => name string :sha => sha of content :mode => last three octets of mode.
Class Method Details
.included(base) ⇒ Object
13 14 15 |
# File 'lib/git_dump/repo/git.rb', line 13 def self.included(base) base.extend(ClassMethods) end |
Instance Method Details
#blob_pipe(sha, &block) ⇒ Object
Return pipe with contents of blob identified by sha
120 121 122 |
# File 'lib/git_dump/repo/git.rb', line 120 def blob_pipe(sha, &block) git('cat-file', 'blob', sha).popen('rb', &block) end |
#blob_read(sha, io = nil) ⇒ Object
Return contents of blob identified by sha If io is specified, then content will be written to io
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/git_dump/repo/git.rb', line 126 def blob_read(sha, io = nil) @blob_read_pipe ||= git(*%w[cat-file --batch]).popen('rb+') @blob_read_pipe.puts(sha) size = @blob_read_pipe.gets.split(' ')[2].to_i result = if io while size > 0 chunk = [size, 4096].min io.write(@blob_read_pipe.read(chunk)) size -= chunk end io else @blob_read_pipe.read(size) end @blob_read_pipe.gets result end |
#blob_unpack(sha, path, mode) ⇒ Object
Write contents of blob to file at path and set its mode
145 146 147 148 149 150 151 152 153 154 |
# File 'lib/git_dump/repo/git.rb', line 145 def blob_unpack(sha, path, mode) Tempfile.open('git_dump', File.dirname(path)) do |temp| temp.binmode blob_read(sha, temp) temp.close File.chmod(mode, temp.path) File.rename(temp.path, path) end end |
#commit(tree_sha, options = {}) ⇒ Object
Create commit for tree_sha, return sha options:
:time => date (by default now)
:message => commit (by default empty)
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/git_dump/repo/git.rb', line 73 def commit(tree_sha, = {}) env = git_env({ :author_date => [:time], :author_name => [:name], :author_email => [:email], :committer_name => [:name], :committer_email => [:email], }) args = %w[commit-tree] args << '-F' << '-' if [:message] args << tree_sha << {:env => env, :no_stdin => ![:message]} git(*args).pipe([:message]).chomp end |
#data_sha(content) ⇒ Object
Add blob for content to repository, return sha
31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/git_dump/repo/git.rb', line 31 def data_sha(content) @data_sha_command ||= git(*%w[hash-object -w --no-filters --stdin]) @data_sha_command.popen('rb+') do |f| if content.respond_to?(:read) f.write(content.read(4096)) until content.eof? else f.write(content) end f.close_write f.read.chomp end end |
#fetch(url, id, options = {}) ⇒ Object
Receive tag with name id from repo at url Use :progress => true to show progress
208 209 210 |
# File 'lib/git_dump/repo/git.rb', line 208 def fetch(url, id, = {}) transfer(:fetch, url, id, ) end |
#gc(options = {}) ⇒ Object
Run garbage collection Use :auto => true to run only if GC is required Use :aggressive => true to run GC more aggressively
221 222 223 224 225 226 |
# File 'lib/git_dump/repo/git.rb', line 221 def gc( = {}) args = %w[gc --quiet] args << '--auto' if [:auto] args << '--aggressive' if [:aggressive] git(*args).run end |
#path_sha(path) ⇒ Object
Add blob for content at path to repository, return sha
45 46 47 48 49 50 |
# File 'lib/git_dump/repo/git.rb', line 45 def path_sha(path) @path_sha_pipe ||= git(*%w[hash-object -w --no-filters --stdin-paths]).popen('r+') @path_sha_pipe.puts(path) @path_sha_pipe.gets.chomp end |
#push(url, id, options = {}) ⇒ Object
Send tag with name id to repo at url Use :progress => true to show progress
214 215 216 |
# File 'lib/git_dump/repo/git.rb', line 214 def push(url, id, = {}) transfer(:push, url, id, ) end |
#remove_tag(id) ⇒ Object
Remove tag with name id
200 201 202 203 204 |
# File 'lib/git_dump/repo/git.rb', line 200 def remove_tag(id) args = %W[tag --delete #{id}] args << {:no_stdout => true} git(*args).run end |
#size(sha) ⇒ Object
Return size of object identified by sha
113 114 115 116 117 |
# File 'lib/git_dump/repo/git.rb', line 113 def size(sha) @size_pipe ||= git(*%w[cat-file --batch-check]).popen('r+') @size_pipe.puts(sha) @size_pipe.gets.split(' ')[2].to_i end |
#tag(commit_sha, name_parts, options = {}) ⇒ Object
Create tag for commit_sha with name constructed from name_parts, return name. name_parts can be an array or a string separated by / options:
:time => tagger date
:message => tag (by default empty)
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/git_dump/repo/git.rb', line 94 def tag(commit_sha, name_parts, = {}) name = tag_name_from_parts(name_parts) env = git_env({ :committer_date => [:time], :committer_name => [:name], :committer_email => [:email], }) args = %w[tag] args << '-F' << '-' << '--cleanup=verbatim' if [:message] args << name << commit_sha << {:env => env} git(*args).pipe([:message]) name end |
#tag_entries ⇒ Object
Return list of entries per tag ref Each entry is a hash with following keys:
:sha => tag or commit sha
:name => ref name
186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/git_dump/repo/git.rb', line 186 def tag_entries ref_fields(TAG_ENTRIES_FIELDS, 'refs/tags').map do |values| { :sha => values[1], :name => values[2].sub(%r{\Arefs/tags/}, ''), :author_time => Time.rfc2822(values[3]), :commit_time => Time.rfc2822(values[4]), :tag_message => values[0] == 'tag' ? values[5] : nil, :commit_message => values[0] == 'tag' ? values[6] : values[5], } end end |
#tree_entries(sha) ⇒ Object
Read tree at sha returning list of entries Each entry is a hash like one for treeify
158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/git_dump/repo/git.rb', line 158 def tree_entries(sha) git('ls-tree', sha).stripped_lines.map do |line| m = /^(\d{6}) (blob|tree) ([0-9a-f]{40})\t(.*)$/.match(line) fail "Unexpected: #{line}" unless m { :mode => m[1].to_i(8), :type => m[2].to_sym, :sha => m[3], :name => m[4], } end end |
#treeify(entries) ⇒ Object
Add blob for entries to repository, return sha Each entry is a hash with following keys:
:type => :blob or :tree
:name => name string
:sha => sha of content
:mode => last three octets of mode
58 59 60 61 62 63 64 65 66 67 |
# File 'lib/git_dump/repo/git.rb', line 58 def treeify(entries) @treefier ||= git('mktree', '--batch').popen('r+') entries.map do |entry| values = normalize_entry(entry).values_at(:mode, :type, :sha, :name) line = format("%06o %s %s\t%s", *values) @treefier.puts line end @treefier.puts @treefier.gets.chomp end |