Skip to content

Commit 90bb8bc

Browse files
committed
Merge pull request #7 from HalfVoxel/master
S3 Improvements, fixes for large numbers of tracked files and support for --short status output
2 parents f5e1f17 + e9ba443 commit 90bb8bc

File tree

11 files changed

+317
-174
lines changed

11 files changed

+317
-174
lines changed

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,15 @@ or in `clone/.git/config` (for per-repo settings).
3636
```ini
3737
[git-media]
3838
transport = <scp|local|s3|atmos|webdav>
39+
autodownload = <true|false>
3940

4041
# settings for scp transport
4142
scpuser = <user>
4243
scphost = <host>
4344
scppath = <path_on_remote_server>
4445

4546
# settings for local transport
46-
path = <local_filesystem_path>
47+
localpath = <local_filesystem_path>
4748

4849
# settings for s3 transport
4950
s3bucket = <name_of_bucket>
@@ -63,7 +64,6 @@ or in `clone/.git/config` (for per-repo settings).
6364
webdavverifyserver = <Net::Dav.verify_server setting, true by default>
6465
webdavbinarytransfer = <Net::Dav.new :curl option value, false by default>
6566

66-
6767
```
6868

6969

@@ -89,8 +89,11 @@ you need to explicitly tell git that some media files has changed:
8989

9090

9191
## Config Settings
92+
93+
If autodownload is set to true, required files will automatically be
94+
downloaded when checking out or pulling. Default is false
9295

93-
$ git config --global media.auto-download false
96+
$ git config --global media.autodownload true
9497

9598

9699
## Installing

lib/git-media.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ def self.get_pull_transport
123123
module Application
124124
def self.run!
125125

126+
if !system('git rev-parse')
127+
return
128+
end
129+
126130
cmd = ARGV.shift # get the subcommand
127131
cmd_opts = case cmd
128132
when "filter-clean" # parse delete options
@@ -139,16 +143,20 @@ def self.run!
139143
GitMedia::Sync.run!
140144
when 'status'
141145
require 'git-media/status'
142-
Trollop::options do
146+
opts = Trollop::options do
143147
opt :force, "Force status"
148+
opt :short, "Short status"
144149
end
145-
GitMedia::Status.run!
150+
GitMedia::Status.run!(opts)
146151
else
147152
print <<EOF
148153
usage: git media sync|status|clear
149154
150155
sync Sync files with remote server
156+
151157
status Show files that are waiting to be uploaded and file size
158+
--short: Displays a shorter status message
159+
152160
clear Upload and delete the local cache of media files
153161
154162
EOF

lib/git-media/clear.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ def self.run!
99
end
1010

1111
def self.clear_local_cache
12-
# find files in media buffer and upload them
12+
# find files in media buffer and delete all pushed files
1313
all_cache = Dir.chdir(GitMedia.get_media_buffer) { Dir.glob('*') }
1414
unpushed_files = @push.get_unpushed(all_cache)
1515
pushed_files = all_cache - unpushed_files
1616
pushed_files.each do |sha|
17-
puts "removing " + sha[0, 8]
17+
puts "Removing " + sha[0, 8]
1818
File.unlink(File.join(GitMedia.get_media_buffer, sha))
1919
end
2020
end

lib/git-media/filter-clean.rb

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,60 @@ module GitMedia
66
module FilterClean
77

88
def self.run!
9-
# determine and initialize our media buffer directory
10-
media_buffer = GitMedia.get_media_buffer
11-
12-
hashfunc = Digest::SHA1.new
13-
start = Time.now
14-
15-
# TODO: read first 41 bytes and see if this is a stub
169

17-
# read in buffered chunks of the data
18-
# calculating the SHA and copying to a tempfile
19-
tempfile = Tempfile.new('media')
20-
while data = STDIN.read(4096)
21-
hashfunc.update(data)
22-
tempfile.write(data)
23-
end
24-
tempfile.close
10+
# Read first 42 bytes
11+
# If the file is only 41 bytes long (as in the case of a stub)
12+
# it will only return a string with a length of 41
13+
data = STDIN.read(42)
2514

26-
# calculate and print the SHA of the data
27-
STDOUT.print hx = hashfunc.hexdigest
2815
STDOUT.binmode
29-
STDOUT.write("\n")
3016

31-
# move the tempfile to our media buffer area
32-
media_file = File.join(media_buffer, hx)
33-
FileUtils.mv(tempfile.path, media_file)
17+
if data != nil && data.length == 41 && data.match(/^[0-9a-fA-F]+\n$/)
18+
19+
# Exactly 41 bytes long and matches the hex string regex
20+
# This is most likely a stub
21+
# TODO: Maybe add some additional marker in the files like
22+
# "[hex string]:git-media"
23+
# to really be able to say that a file is a stub
24+
25+
STDOUT.write (data)
26+
STDERR.puts("Skipping unexpanded stub : " + data[0, 8])
27+
28+
else
29+
30+
# determine and initialize our media buffer directory
31+
media_buffer = GitMedia.get_media_buffer
32+
33+
hashfunc = Digest::SHA1.new
34+
start = Time.now
3435

35-
elapsed = Time.now - start
36-
STDERR.puts('Saving media : ' + hx + ' : ' + elapsed.to_s)
36+
# read in buffered chunks of the data
37+
# calculating the SHA and copying to a tempfile
38+
tempfile = Tempfile.new('media', :binmode => true)
39+
40+
# Write the first 42 bytes
41+
if data != nil
42+
hashfunc.update(data)
43+
tempfile.write(data)
44+
end
45+
46+
while data = STDIN.read(4096)
47+
hashfunc.update(data)
48+
tempfile.write(data)
49+
end
50+
tempfile.close
51+
52+
# calculate and print the SHA of the data
53+
STDOUT.print hx = hashfunc.hexdigest
54+
STDOUT.write("\n")
55+
56+
# move the tempfile to our media buffer area
57+
media_file = File.join(media_buffer, hx)
58+
FileUtils.mv(tempfile.path, media_file)
59+
60+
elapsed = Time.now - start
61+
STDERR.puts('Saving media : ' + hx + ' : ' + elapsed.to_s)
62+
end
3763
end
3864

3965
end

lib/git-media/filter-smudge.rb

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,65 @@
11
module GitMedia
22
module FilterSmudge
33

4+
def self.print_stream(stream)
5+
while data = stream.read(4096) do
6+
print data
7+
end
8+
end
9+
410
def self.run!
511
media_buffer = GitMedia.get_media_buffer
6-
can_download = false # TODO: read this from config and implement
712

813
# read checksum size
9-
sha = STDIN.readline(64).strip # read no more than 64 bytes
14+
orig = STDIN.readline(64)
15+
sha = orig.strip # read no more than 64 bytes
1016
if STDIN.eof? && sha.length == 40 && sha.match(/^[0-9a-fA-F]+$/) != nil
1117
# this is a media file
1218
media_file = File.join(media_buffer, sha.chomp)
1319
if File.exists?(media_file)
14-
STDERR.puts('recovering media : ' + sha)
15-
File.open(media_file, 'r') do |f|
16-
while data = f.read(4096) do
17-
print data
18-
end
20+
STDERR.puts('Recovering media : ' + sha)
21+
File.open(media_file, 'rb') do |f|
22+
print_stream(f)
1923
end
2024
else
21-
# TODO: download file if not in the media buffer area
22-
if !can_download
23-
STDERR.puts('media missing, saving placeholder : ' + sha)
24-
puts sha
25+
# Read key from config
26+
auto_download = `git config git-media.autodownload`.chomp.downcase == "true"
27+
28+
if auto_download
29+
30+
pull = GitMedia.get_pull_transport
31+
32+
cache_file = GitMedia.media_path(sha)
33+
if !File.exist?(cache_file)
34+
STDERR.puts ("Downloading : " + sha[0,8])
35+
# Download the file from backend storage
36+
# We have no idea what the final file will be (therefore nil)
37+
pull.pull(nil, sha)
38+
end
39+
40+
STDERR.puts ("Expanding : " + sha[0,8])
41+
42+
if File.exist?(cache_file)
43+
File.open(media_file, 'rb') do |f|
44+
print_stream(f)
45+
end
46+
else
47+
STDERR.puts ("Could not get media, saving placeholder : " + sha)
48+
puts orig
49+
end
50+
51+
else
52+
STDERR.puts('Media missing, saving placeholder : ' + sha)
53+
# Print orig and not sha to preserve eventual newlines at end of file
54+
# To avoid git thinking the file has changed
55+
puts orig
2556
end
2657
end
2758
else
2859
# if it is not a 40 character long hash, just output
2960
STDERR.puts('Unknown git-media file format')
30-
print sha
31-
while data = STDIN.read(4096)
32-
print data
33-
end
61+
print orig
62+
print_stream(STDIN)
3463
end
3564
end
3665

lib/git-media/status.rb

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
module GitMedia
55
module Status
66

7-
def self.run!
7+
def self.run!(opts)
88
@push = GitMedia.get_push_transport
99
r = self.find_references
10-
self.print_references(r)
10+
self.print_references(r, opts[:short])
1111
r = self.local_cache_status
12-
self.print_cache_status(r)
12+
self.print_cache_status(r, opts[:short])
1313
end
1414

1515
# find tree entries that are likely media references
@@ -19,7 +19,9 @@ def self.find_references
1919
files = files.map { |f| s = f.split("\t"); [s[0].split(' ').last, s[1]] }
2020
files = files.select { |f| f[0] == '41' } # it's the right size
2121
files.each do |tree_size, fname|
22-
if size = File.size?(fname)
22+
if File.exists?(fname)
23+
size = File.size(fname)
24+
2325
# Windows newlines can offset file size by 1
2426
if size == tree_size.to_i or size == tree_size.to_i + 1
2527
# TODO: read in the data and verify that it's a sha + newline
@@ -39,49 +41,70 @@ def self.find_references
3941
references
4042
end
4143

42-
def self.print_references(refs)
44+
def self.print_references(refs, short=false)
45+
4346
if refs[:to_expand].size > 0
4447
puts "== Unexpanded Media =="
45-
refs[:to_expand].each do |file, sha|
46-
puts " " + sha[0, 8] + " " + file
48+
if short
49+
puts "Count: " + refs[:to_expand].size.to_s
50+
else
51+
refs[:to_expand].each do |file, sha|
52+
puts " " + sha[0, 8] + " " + file
53+
end
54+
puts
4755
end
48-
puts
4956
end
5057
if refs[:expanded].size > 0
5158
puts "== Expanded Media =="
52-
refs[:expanded].each do |file|
53-
size = File.size(file)
54-
puts " " + "(#{self.to_human(size)})".ljust(8) + " #{file}"
59+
if short
60+
puts "Count: " + refs[:expanded].size.to_s
61+
else
62+
refs[:expanded].each do |file|
63+
size = File.size(file)
64+
puts " " + "(#{self.to_human(size)})".ljust(8) + " #{file}"
65+
end
66+
puts
5567
end
56-
puts
5768
end
5869
if refs[:deleted].size > 0
5970
puts "== Deleted Media =="
60-
refs[:deleted].each do |file|
61-
puts " " + " #{file}"
71+
if short
72+
puts "Count: " + refs[:deleted].size.to_s
73+
else
74+
refs[:deleted].each do |file|
75+
puts " " + " #{file}"
76+
end
77+
puts
6278
end
63-
puts
6479
end
6580
end
6681

67-
def self.print_cache_status(refs)
82+
def self.print_cache_status(refs, short)
6883
if refs[:unpushed].size > 0
6984
puts "== Unpushed Media =="
70-
refs[:unpushed].each do |sha|
71-
cache_file = GitMedia.media_path(sha)
72-
size = File.size(cache_file)
73-
puts " " + "(#{self.to_human(size)})".ljust(8) + ' ' + sha[0, 8]
85+
if short
86+
puts "Count: " + refs[:unpushed].size.to_s
87+
else
88+
refs[:unpushed].each do |sha|
89+
cache_file = GitMedia.media_path(sha)
90+
size = File.size(cache_file)
91+
puts " " + "(#{self.to_human(size)})".ljust(8) + ' ' + sha[0, 8]
92+
end
93+
puts
7494
end
75-
puts
7695
end
7796
if refs[:pushed].size > 0
7897
puts "== Already Pushed Media =="
79-
refs[:pushed].each do |sha|
80-
cache_file = GitMedia.media_path(sha)
81-
size = File.size(cache_file)
82-
puts " " + "(#{self.to_human(size)})".ljust(8) + ' ' + sha[0, 8]
98+
if short
99+
puts "Count: " + refs[:pushed].size.to_s
100+
else
101+
refs[:pushed].each do |sha|
102+
cache_file = GitMedia.media_path(sha)
103+
size = File.size(cache_file)
104+
puts " " + "(#{self.to_human(size)})".ljust(8) + ' ' + sha[0, 8]
105+
end
106+
puts
83107
end
84-
puts
85108
end
86109
end
87110

0 commit comments

Comments
 (0)