git-ng 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,75 @@
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
+ end
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,122 @@
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 merge(branch = nil, message = nil)
64
+ if branch
65
+ in_branch do
66
+ @base.merge(branch, message)
67
+ false
68
+ end
69
+ # merge a branch into this one
70
+ else
71
+ # merge this branch into the current one
72
+ @base.merge(@name)
73
+ end
74
+ end
75
+
76
+ def update_ref(commit)
77
+ @base.lib.update_ref(@full, commit)
78
+ end
79
+
80
+ def to_a
81
+ [@full]
82
+ end
83
+
84
+ def to_s
85
+ @full
86
+ end
87
+
88
+ private
89
+
90
+ def check_if_create
91
+ @base.lib.branch_new(@name) rescue nil
92
+ end
93
+
94
+ def determine_current
95
+ @base.lib.branch_current == @name
96
+ end
97
+
98
+ # Given a full branch name return an Array containing the remote and branch names.
99
+ #
100
+ # Removes 'remotes' from the beggining of the name (if present).
101
+ # Takes the second part (splittign by '/') as the remote name.
102
+ # Takes the rest as the repo name (can also hold one or more '/').
103
+ #
104
+ # Example:
105
+ # parse_name('master') #=> [nil, 'master']
106
+ # parse_name('origin/master') #=> ['origin', 'master']
107
+ # parse_name('remotes/origin/master') #=> ['origin', 'master']
108
+ # parse_name('origin/master/v2') #=> ['origin', 'master/v2']
109
+ #
110
+ # param [String] name branch full name.
111
+ # return [<Git::Remote,NilClass,String>] an Array containing the remote and branch names.
112
+ def parse_name(name)
113
+ if name.match(/^(?:remotes)?\/([^\/]+)\/(.+)/)
114
+ return [Git::Remote.new(@base, $1), $2]
115
+ end
116
+
117
+ return [nil, name]
118
+ end
119
+
120
+ end
121
+
122
+ 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 || '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,158 @@
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_utf8_encoded = @full_diff.encode("UTF-8", "binary", {
131
+ :invalid => :replace,
132
+ :undef => :replace
133
+ })
134
+ full_diff_utf8_encoded.split("\n").each do |line|
135
+ if m = /^diff --git a\/(.*?) b\/(.*?)/.match(line)
136
+ current_file = m[1]
137
+ final[current_file] = defaults.merge({:patch => line, :path => current_file})
138
+ else
139
+ if m = /^index (.......)\.\.(.......)( ......)*/.match(line)
140
+ final[current_file][:src] = m[1]
141
+ final[current_file][:dst] = m[2]
142
+ final[current_file][:mode] = m[3].strip if m[3]
143
+ end
144
+ if m = /^([[:alpha:]]*?) file mode (......)/.match(line)
145
+ final[current_file][:type] = m[1]
146
+ final[current_file][:mode] = m[2]
147
+ end
148
+ if m = /^Binary files /.match(line)
149
+ final[current_file][:binary] = true
150
+ end
151
+ final[current_file][:patch] << "\n" + line
152
+ end
153
+ end
154
+ final.map { |e| [e[0], DiffFile.new(@base, e[1])] }
155
+ end
156
+
157
+ end
158
+ end