git-glimmer 1.7.0

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.
@@ -0,0 +1,83 @@
1
+ module Git
2
+
3
+ class Base
4
+
5
+ module Factory
6
+
7
+ # returns a Git::Branch object for branch_name
8
+ def branch(branch_name = 'master')
9
+ Git::Branch.new(self, branch_name)
10
+ end
11
+
12
+ # returns a Git::Branches object of all the Git::Branch
13
+ # objects for this repo
14
+ def branches
15
+ Git::Branches.new(self)
16
+ end
17
+
18
+ def commit_tree(tree = nil, opts = {})
19
+ Git::Object::Commit.new(self, self.lib.commit_tree(tree, opts))
20
+ end
21
+
22
+ # returns a Git::Diff object
23
+ def diff(objectish = 'HEAD', obj2 = nil)
24
+ Git::Diff.new(self, objectish, obj2)
25
+ end
26
+
27
+ def gblob(objectish)
28
+ Git::Object.new(self, objectish, 'blob')
29
+ end
30
+
31
+ def gcommit(objectish)
32
+ Git::Object.new(self, objectish, 'commit')
33
+ end
34
+
35
+ def gtree(objectish)
36
+ Git::Object.new(self, objectish, 'tree')
37
+ end
38
+
39
+ # returns a Git::Log object with count commits
40
+ def log(count = 30)
41
+ Git::Log.new(self, count)
42
+ end
43
+
44
+ # returns a Git::Object of the appropriate type
45
+ # you can also call @git.gtree('tree'), but that's
46
+ # just for readability. If you call @git.gtree('HEAD') it will
47
+ # still return a Git::Object::Commit object.
48
+ #
49
+ # @git.object calls a factory method that will run a rev-parse
50
+ # on the objectish and determine the type of the object and return
51
+ # an appropriate object for that type
52
+ def object(objectish)
53
+ Git::Object.new(self, objectish)
54
+ end
55
+
56
+ # returns a Git::Remote object
57
+ def remote(remote_name = 'origin')
58
+ Git::Remote.new(self, remote_name)
59
+ end
60
+
61
+ # returns a Git::Status object
62
+ def status
63
+ Git::Status.new(self)
64
+ end
65
+
66
+ # returns a Git::Tag object
67
+ def tag(tag_name)
68
+ Git::Object.new(self, tag_name, 'tag', true)
69
+ end
70
+
71
+ # Find as good common ancestors as possible for a merge
72
+ # example: g.merge_base('master', 'some_branch', 'some_sha', octopus: true)
73
+ # returns Array<Git::Object::Commit>
74
+ def merge_base(*args)
75
+ shas = self.lib.merge_base(*args)
76
+ shas.map { |sha| gcommit(sha) }
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+
83
+ end
@@ -0,0 +1,126 @@
1
+ require 'git/path'
2
+
3
+ module Git
4
+
5
+ class Branch < Path
6
+
7
+ attr_accessor :full, :remote, :name
8
+
9
+ def initialize(base, name)
10
+ @full = name
11
+ @base = base
12
+ @gcommit = nil
13
+ @stashes = nil
14
+ @remote, @name = parse_name(name)
15
+ end
16
+
17
+ def gcommit
18
+ @gcommit ||= @base.gcommit(@full)
19
+ @gcommit
20
+ end
21
+
22
+ def stashes
23
+ @stashes ||= Git::Stashes.new(@base)
24
+ end
25
+
26
+ def checkout
27
+ check_if_create
28
+ @base.checkout(@full)
29
+ end
30
+
31
+ def archive(file, opts = {})
32
+ @base.lib.archive(@full, file, opts)
33
+ end
34
+
35
+ # g.branch('new_branch').in_branch do
36
+ # # create new file
37
+ # # do other stuff
38
+ # return true # auto commits and switches back
39
+ # end
40
+ def in_branch(message = 'in branch work')
41
+ old_current = @base.lib.branch_current
42
+ checkout
43
+ if yield
44
+ @base.commit_all(message)
45
+ else
46
+ @base.reset_hard
47
+ end
48
+ @base.checkout(old_current)
49
+ end
50
+
51
+ def create
52
+ check_if_create
53
+ end
54
+
55
+ def delete
56
+ @base.lib.branch_delete(@name)
57
+ end
58
+
59
+ def current
60
+ determine_current
61
+ end
62
+
63
+ def contains?(commit)
64
+ !@base.lib.branch_contains(commit, self.name).empty?
65
+ end
66
+
67
+ def merge(branch = nil, message = nil)
68
+ if branch
69
+ in_branch do
70
+ @base.merge(branch, message)
71
+ false
72
+ end
73
+ # merge a branch into this one
74
+ else
75
+ # merge this branch into the current one
76
+ @base.merge(@name)
77
+ end
78
+ end
79
+
80
+ def update_ref(commit)
81
+ @base.lib.update_ref(@full, commit)
82
+ end
83
+
84
+ def to_a
85
+ [@full]
86
+ end
87
+
88
+ def to_s
89
+ @full
90
+ end
91
+
92
+ private
93
+
94
+ def check_if_create
95
+ @base.lib.branch_new(@name) rescue nil
96
+ end
97
+
98
+ def determine_current
99
+ @base.lib.branch_current == @name
100
+ end
101
+
102
+ # Given a full branch name return an Array containing the remote and branch names.
103
+ #
104
+ # Removes 'remotes' from the beggining of the name (if present).
105
+ # Takes the second part (splittign by '/') as the remote name.
106
+ # Takes the rest as the repo name (can also hold one or more '/').
107
+ #
108
+ # Example:
109
+ # parse_name('master') #=> [nil, 'master']
110
+ # parse_name('origin/master') #=> ['origin', 'master']
111
+ # parse_name('remotes/origin/master') #=> ['origin', 'master']
112
+ # parse_name('origin/master/v2') #=> ['origin', 'master/v2']
113
+ #
114
+ # param [String] name branch full name.
115
+ # return [<Git::Remote,NilClass,String>] an Array containing the remote and branch names.
116
+ def parse_name(name)
117
+ if name.match(/^(?:remotes)?\/([^\/]+)\/(.+)/)
118
+ return [Git::Remote.new(@base, $1), $2]
119
+ end
120
+
121
+ return [nil, name]
122
+ end
123
+
124
+ end
125
+
126
+ end
@@ -0,0 +1,71 @@
1
+ module Git
2
+
3
+ # object that holds all the available branches
4
+ class Branches
5
+
6
+ include Enumerable
7
+
8
+ def initialize(base)
9
+ @branches = {}
10
+
11
+ @base = base
12
+
13
+ @base.lib.branches_all.each do |b|
14
+ @branches[b[0]] = Git::Branch.new(@base, b[0])
15
+ end
16
+ end
17
+
18
+ def local
19
+ self.select { |b| !b.remote }
20
+ end
21
+
22
+ def remote
23
+ self.select { |b| b.remote }
24
+ end
25
+
26
+ # array like methods
27
+
28
+ def size
29
+ @branches.size
30
+ end
31
+
32
+ def each(&block)
33
+ @branches.values.each(&block)
34
+ end
35
+
36
+ # Returns the target branch
37
+ #
38
+ # Example:
39
+ # Given (git branch -a):
40
+ # master
41
+ # remotes/working/master
42
+ #
43
+ # g.branches['master'].full #=> 'master'
44
+ # g.branches['working/master'].full => 'remotes/working/master'
45
+ # g.branches['remotes/working/master'].full => 'remotes/working/master'
46
+ #
47
+ # @param [#to_s] branch_name the target branch name.
48
+ # @return [Git::Branch] the target branch.
49
+ def [](branch_name)
50
+ @branches.values.inject(@branches) do |branches, branch|
51
+ branches[branch.full] ||= branch
52
+
53
+ # This is how Git (version 1.7.9.5) works.
54
+ # Lets you ignore the 'remotes' if its at the beginning of the branch full name (even if is not a real remote branch).
55
+ branches[branch.full.sub('remotes/', '')] ||= branch if branch.full =~ /^remotes\/.+/
56
+
57
+ branches
58
+ end[branch_name.to_s]
59
+ end
60
+
61
+ def to_s
62
+ out = ''
63
+ @branches.each do |k, b|
64
+ out << (b.current ? '* ' : ' ') << b.to_s << "\n"
65
+ end
66
+ out
67
+ end
68
+
69
+ end
70
+
71
+ end
@@ -0,0 +1,22 @@
1
+ module Git
2
+
3
+ class Config
4
+
5
+ attr_writer :binary_path, :git_ssh
6
+
7
+ def initialize
8
+ @binary_path = nil
9
+ @git_ssh = nil
10
+ end
11
+
12
+ def binary_path
13
+ @binary_path || ENV['GIT_PATH'] && File.join(ENV['GIT_PATH'], 'git') || 'git'
14
+ end
15
+
16
+ def git_ssh
17
+ @git_ssh || ENV['GIT_SSH']
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,154 @@
1
+ module Git
2
+
3
+ # object that holds the last X commits on given branch
4
+ class Diff
5
+ include Enumerable
6
+
7
+ def initialize(base, from = nil, to = nil)
8
+ @base = base
9
+ @from = from && from.to_s
10
+ @to = to && to.to_s
11
+
12
+ @path = nil
13
+ @full_diff = nil
14
+ @full_diff_files = nil
15
+ @stats = nil
16
+ end
17
+ attr_reader :from, :to
18
+
19
+ def name_status
20
+ cache_name_status
21
+ end
22
+
23
+ def path(path)
24
+ @path = path
25
+ return self
26
+ end
27
+
28
+ def size
29
+ cache_stats
30
+ @stats[:total][:files]
31
+ end
32
+
33
+ def lines
34
+ cache_stats
35
+ @stats[:total][:lines]
36
+ end
37
+
38
+ def deletions
39
+ cache_stats
40
+ @stats[:total][:deletions]
41
+ end
42
+
43
+ def insertions
44
+ cache_stats
45
+ @stats[:total][:insertions]
46
+ end
47
+
48
+ def stats
49
+ cache_stats
50
+ @stats
51
+ end
52
+
53
+ # if file is provided and is writable, it will write the patch into the file
54
+ def patch(file = nil)
55
+ cache_full
56
+ @full_diff
57
+ end
58
+ alias_method :to_s, :patch
59
+
60
+ # enumerable methods
61
+
62
+ def [](key)
63
+ process_full
64
+ @full_diff_files.assoc(key)[1]
65
+ end
66
+
67
+ def each(&block) # :yields: each Git::DiffFile in turn
68
+ process_full
69
+ @full_diff_files.map { |file| file[1] }.each(&block)
70
+ end
71
+
72
+ class DiffFile
73
+ attr_accessor :patch, :path, :mode, :src, :dst, :type
74
+ @base = nil
75
+
76
+ def initialize(base, hash)
77
+ @base = base
78
+ @patch = hash[:patch]
79
+ @path = hash[:path]
80
+ @mode = hash[:mode]
81
+ @src = hash[:src]
82
+ @dst = hash[:dst]
83
+ @type = hash[:type]
84
+ @binary = hash[:binary]
85
+ end
86
+
87
+ def binary?
88
+ !!@binary
89
+ end
90
+
91
+ def blob(type = :dst)
92
+ if type == :src
93
+ @base.object(@src) if @src != '0000000'
94
+ else
95
+ @base.object(@dst) if @dst != '0000000'
96
+ end
97
+ end
98
+ end
99
+
100
+ private
101
+
102
+ def cache_full
103
+ @full_diff ||= @base.lib.diff_full(@from, @to, {:path_limiter => @path})
104
+ end
105
+
106
+ def process_full
107
+ return if @full_diff_files
108
+ cache_full
109
+ @full_diff_files = process_full_diff
110
+ end
111
+
112
+ def cache_stats
113
+ @stats ||= @base.lib.diff_stats(@from, @to, {:path_limiter => @path})
114
+ end
115
+
116
+ def cache_name_status
117
+ @name_status ||= @base.lib.diff_name_status(@from, @to, {:path => @path})
118
+ end
119
+
120
+ # break up @diff_full
121
+ def process_full_diff
122
+ defaults = {
123
+ :mode => '',
124
+ :src => '',
125
+ :dst => '',
126
+ :type => 'modified'
127
+ }
128
+ final = {}
129
+ current_file = nil
130
+ @full_diff.split("\n").each do |line|
131
+ if m = /^diff --git a\/(.*?) b\/(.*?)/.match(line)
132
+ current_file = m[1]
133
+ final[current_file] = defaults.merge({:patch => line, :path => current_file})
134
+ else
135
+ if m = /^index (.......)\.\.(.......)( ......)*/.match(line)
136
+ final[current_file][:src] = m[1]
137
+ final[current_file][:dst] = m[2]
138
+ final[current_file][:mode] = m[3].strip if m[3]
139
+ end
140
+ if m = /^([[:alpha:]]*?) file mode (......)/.match(line)
141
+ final[current_file][:type] = m[1]
142
+ final[current_file][:mode] = m[2]
143
+ end
144
+ if m = /^Binary files /.match(line)
145
+ final[current_file][:binary] = true
146
+ end
147
+ final[current_file][:patch] << "\n" + line
148
+ end
149
+ end
150
+ final.map { |e| [e[0], DiffFile.new(@base, e[1])] }
151
+ end
152
+
153
+ end
154
+ end