git_lib 1.2.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,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Git
4
+ VERSION = '1.2.0'
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './git/git.rb'
4
+ require_relative './git/git_branch.rb'
5
+ require_relative './git/git_conflict.rb'
6
+ require_relative './git/git_commit.rb'
7
+ require_relative './git/git_error.rb'
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require_relative '../../../lib/git/git_branch.rb'
5
+
6
+ describe 'Git::GitBranch' do
7
+ it 'can be created' do
8
+ last_modified_date = Time.current
9
+ branch = Git::GitBranch.new('repository_name', 'name', last_modified_date, 'author_name', 'author@email.com')
10
+
11
+ expect(branch.repository_name).to eq('repository_name')
12
+ expect(branch.name).to eq('name')
13
+ expect(branch.last_modified_date).to eq(last_modified_date)
14
+ expect(branch.author_name).to eq('author_name')
15
+ expect(branch.author_email).to eq('author@email.com')
16
+ end
17
+
18
+ it 'implements regexp operator' do
19
+ branch = Git::GitBranch.new('repository_name', 'verylongname', Time.current, 'author_name', 'author@email.com')
20
+
21
+ expect(branch =~ /.*long.*/).to be_truthy
22
+ expect(branch =~ /nomatch/).to be_falsey
23
+ end
24
+
25
+ it 'implements equality operator' do
26
+ last_modified_date = Time.current
27
+ branch_a = Git::GitBranch.new('repository_name', 'name', last_modified_date, 'author_name', 'author@email.com')
28
+
29
+ branch_b = Git::GitBranch.new('repository_name', 'name', last_modified_date, 'author_name', 'author@email.com')
30
+ expect(branch_a).to eq(branch_b)
31
+
32
+ branch_c = Git::GitBranch.new('different', 'name', last_modified_date, 'author_name', 'author@email.com')
33
+ expect(branch_a).not_to eq(branch_c)
34
+
35
+ branch_d = Git::GitBranch.new('repository_name', 'different', last_modified_date, 'author_name', 'author@email.com')
36
+ expect(branch_a).not_to eq(branch_d)
37
+
38
+ branch_e = Git::GitBranch.new('repository_name', 'name', Time.current, 'author_name', 'author@email.com')
39
+ expect(branch_a).not_to eq(branch_e)
40
+
41
+ branch_f = Git::GitBranch.new('repository_name', 'name', last_modified_date, 'different', 'author@email.com')
42
+ expect(branch_a).not_to eq(branch_f)
43
+
44
+ branch_g = Git::GitBranch.new('repository_name', 'name', last_modified_date, 'author_name', 'different@email.com')
45
+ expect(branch_a).not_to eq(branch_g)
46
+ end
47
+
48
+ it 'returns its name when converted to string' do
49
+ branch = Git::GitBranch.new('repository_name', 'name', Time.current, 'author_name', 'author@email.com')
50
+ expect(branch.to_s).to eq('name')
51
+ end
52
+
53
+ it 'parses branch name from ref' do
54
+ expect(Git::GitBranch.name_from_ref('refs/heads/branch_name')).to eq('branch_name')
55
+ expect(Git::GitBranch.name_from_ref('branch_name')).to eq('branch_name')
56
+ end
57
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require_relative '../../../lib/git/git_conflict.rb'
5
+
6
+ describe 'Git::GitConflict' do
7
+ it 'can be created' do
8
+ conflict = Git::GitConflict.new('repository_name', 'branch_a', 'branch_b', ['file1', 'file2'])
9
+
10
+ expect(conflict.repository_name).to eq('repository_name')
11
+ expect(conflict.branch_a).to eq('branch_a')
12
+ expect(conflict.branch_b).to eq('branch_b')
13
+ expect(conflict.conflicting_files).to eq(['file1', 'file2'])
14
+ end
15
+
16
+ it 'cannot be created without conflicting files' do
17
+ expect { Git::GitConflict.new('repository_name', 'branch_a', 'branch_b', nil) }.to \
18
+ raise_exception(ArgumentError, 'Must specify conflicting file list')
19
+ expect { Git::GitConflict.new('repository_name', 'branch_a', 'branch_b', []) }.to \
20
+ raise_exception(ArgumentError, 'Must specify conflicting file list')
21
+ end
22
+
23
+ it 'implements equality operator' do
24
+ conflict_a = Git::GitConflict.new('repository_name', 'branch_a', 'branch_b', ['file1', 'file2'])
25
+
26
+ conflict_b = Git::GitConflict.new('repository_name', 'branch_a', 'branch_b', ['file1', 'file2'])
27
+ expect(conflict_a).to eq(conflict_b)
28
+
29
+ conflict_c = Git::GitConflict.new('different', 'branch_a', 'branch_b', ['file1', 'file2'])
30
+ expect(conflict_a).not_to eq(conflict_c)
31
+
32
+ conflict_d = Git::GitConflict.new('repository_name', 'different', 'branch_b', ['file1', 'file2'])
33
+ expect(conflict_a).not_to eq(conflict_d)
34
+
35
+ conflict_e = Git::GitConflict.new('repository_name', 'branch_a', 'different', ['file1', 'file2'])
36
+ expect(conflict_a).not_to eq(conflict_e)
37
+
38
+ conflict_f = Git::GitConflict.new('repository_name', 'branch_a', 'branch_b', ['different', 'file2'])
39
+ expect(conflict_a).not_to eq(conflict_f)
40
+ end
41
+
42
+ it 'can determine if it contains the specified branch' do
43
+ conflict = Git::GitConflict.new('repository_name', 'branch_a', 'branch_b', ['file1', 'file2'])
44
+
45
+ expect(conflict.contains_branch('branch_a')).to be_truthy
46
+ expect(conflict.contains_branch('branch_b')).to be_truthy
47
+
48
+ expect(conflict.contains_branch('branch_c')).to be_falsey
49
+ end
50
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require_relative '../../../lib/git/git_error.rb'
5
+
6
+ describe 'Git::GitError' do
7
+ it 'can be raised' do
8
+ expect { raise Git::GitError.new('command', 200, 'error_message') }.to \
9
+ raise_exception(Git::GitError, "Git command command failed with exit code 200. Message:\nerror_message")
10
+ end
11
+
12
+ it 'can be printed' do
13
+ begin
14
+ raise Git::GitError.new('command', 200, 'error_message')
15
+ rescue Git::GitError => e
16
+ expect(e.message).to eq("Git command command failed with exit code 200. Message:\nerror_message")
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,436 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require_relative '../../../lib/git/git.rb'
5
+
6
+ # rubocop:disable Metrics/LineLength
7
+ describe 'Git::Git' do
8
+ include FakeFS::SpecHelpers
9
+
10
+ def create_mock_open_status(status)
11
+ status_object = double
12
+ allow(status_object).to receive(:success?) { status == 1 }
13
+ allow(status_object).to receive(:to_s) { status.to_s }
14
+ status_object
15
+ end
16
+
17
+ def mock_execute(stdout_andstderr_str, status, execution_count: 1, expected_command: anything)
18
+ # mock the call and repsonse to execute the git command
19
+ expect(Open3).to receive(:capture2e).exactly(execution_count).times do |*args|
20
+ if !expected_command.is_a?(RSpec::Mocks::ArgumentMatchers::AnyArgMatcher) && !expected_command.nil?
21
+ # remove the options hash, we are not going to verify it's contents
22
+ args.reject! { |arg| arg.is_a?(Hash) }
23
+
24
+ # confirm we got the args we expected
25
+ expect(args).to eq(expected_command.split(/ /))
26
+ end
27
+ [stdout_andstderr_str, create_mock_open_status(status)]
28
+ end
29
+ end
30
+
31
+ it 'can be created' do
32
+ git = Git::Git.new('repository_name')
33
+
34
+ expect(git.repository_url).to eq('git@github.com:repository_name.git')
35
+ expect(git.repository_path).to eq('/tmp/git/repository_name')
36
+ end
37
+
38
+ it 'can be created with a different cache path' do
39
+ git = Git::Git.new('repository_name', git_cache_path: './mycache')
40
+
41
+ expect(git.repository_url).to eq('git@github.com:repository_name.git')
42
+ expect(git.repository_path).to eq('./mycache/repository_name')
43
+ end
44
+
45
+ context 'with a git repository' do
46
+ before do
47
+ @git = Git::Git.new('repository_name')
48
+ end
49
+
50
+ it 'can execute a command' do
51
+ mock_execute('sample output', 1)
52
+ expect(@git.execute('sample command')).to eq('sample output')
53
+ end
54
+
55
+ it 'raises GitError when a command fails' do
56
+ mock_execute('sample output', 0)
57
+ expect { @git.execute('sample command') }.to raise_exception(Git::GitError)
58
+ end
59
+
60
+ describe 'clone_repository' do
61
+ it 'can clone into a new directory' do
62
+ response = \
63
+ "Cloning into '#{@git.repository_name}'..." \
64
+ 'remote: Counting objects: 1080, done.' \
65
+ 'remote: Compressing objects: 100% (83/83), done.' \
66
+ 'remote: Total 1080 (delta 34), reused 0 (delta 0), pack-reused 994' \
67
+ 'Receiving objects: 100% (1080/1080), 146.75 KiB | 0 bytes/s, done.' \
68
+ 'Resolving deltas: 100% (641/641), done.' \
69
+ 'Checking connectivity... done.'
70
+ mock_execute(response, 1)
71
+ @git.clone_repository('default_branch')
72
+ end
73
+
74
+ it 'can update a previously cloned repository' do
75
+ expect(@git).to receive(:reset).exactly(1).times
76
+ expect(@git).to receive(:checkout_branch)
77
+ mock_execute('Success', 1, execution_count: 3)
78
+ FileUtils.mkpath(@git.repository_path)
79
+ @git.clone_repository('default_branch')
80
+ end
81
+ end
82
+
83
+ describe 'push' do
84
+ it 'can push a branch' do
85
+ response = \
86
+ 'Counting objects: 20, done.' \
87
+ 'Delta compression using up to 8 threads.' \
88
+ 'Compressing objects: 100% (18/18), done.' \
89
+ 'Writing objects: 100% (20/20), 2.47 KiB | 0 bytes/s, done.' \
90
+ 'Total 20 (delta 11), reused 0 (delta 0)' \
91
+ "To #{@git.repository_url}" \
92
+ '19087ab..9cdd9db master -> master'
93
+ mock_execute(response, 1)
94
+ expect(@git.push).to eq(true)
95
+ end
96
+
97
+ it 'can push a branch using dry run' do
98
+ response = \
99
+ "To #{@git.repository_url}" \
100
+ '19087ab..9cdd9db master -> master'
101
+ mock_execute(response, 1, expected_command: '/usr/bin/git push --dry-run origin')
102
+ expect(@git.push(dry_run: true)).to eq(true)
103
+ end
104
+
105
+ it 'can detect if a push results in a no-op' do
106
+ mock_execute("Everything up-to-date\n", 1)
107
+ expect(@git.push).to eq(false)
108
+ end
109
+ end
110
+
111
+ describe 'checkout_branch' do
112
+ it 'can checkout a branch' do
113
+ expect(@git).to receive(:reset).exactly(2).times
114
+ mock_execute('Success', 1)
115
+ @git.checkout_branch('branch_name')
116
+ end
117
+
118
+ it 'escapes backticks in branch names' do
119
+ expect(@git).to receive(:reset).exactly(2).times
120
+ mock_execute('sample output', 1, expected_command: '/usr/bin/git checkout branch_\\`name')
121
+ @git.checkout_branch('branch_`name')
122
+ end
123
+ end
124
+
125
+ describe 'reset' do
126
+ it 'can reset a branch to HEAD of origin' do
127
+ expect(@git).to receive(:current_branch_name).and_return('master')
128
+ mock_execute("HEAD is now at beb5e09 Merge branch 'master'", 1)
129
+ @git.reset
130
+ end
131
+
132
+ it 'escapes backticks in branch names' do
133
+ expect(@git).to receive(:current_branch_name).and_return('branch_`name')
134
+ mock_execute('sample output', 1, expected_command: '/usr/bin/git reset --hard origin/branch_\\`name')
135
+ @git.reset
136
+ end
137
+ end
138
+
139
+ describe 'get_branch_list' do
140
+ it 'can parse a branch list' do
141
+ mock_execute(
142
+ "origin/test_1~2015-10-19 17:58:24 -0700~Nicholas Ellis~<nellis@invoca.com>\norigin/test_build~2015-10-19 15:03:22 -0700~Bob Smith~<bob@invoca.com>\norigin/test_build_b~2015-10-19 16:52:40 -0700~Nicholas Ellis~<nellis@invoca.com>",
143
+ 1
144
+ )
145
+
146
+ branch_list = []
147
+ branch_list << Git::GitBranch.new(
148
+ 'repository_name',
149
+ 'test_1',
150
+ DateTime.iso8601('2015-10-19T17:58:24-0700'),
151
+ 'Nicholas Ellis',
152
+ 'nellis@invoca.com'
153
+ )
154
+ branch_list << Git::GitBranch.new(
155
+ 'repository_name',
156
+ 'test_build',
157
+ DateTime.iso8601('2015-10-19T15:03:22-0700'),
158
+ 'Bob Smith',
159
+ 'bob@invoca.com'
160
+ )
161
+ branch_list << Git::GitBranch.new(
162
+ 'repository_name',
163
+ 'test_build_b',
164
+ DateTime.iso8601('2015-10-19T16:52:40-0700'),
165
+ 'Nicholas Ellis',
166
+ 'nellis@invoca.com'
167
+ )
168
+
169
+ expect(@git.branch_list).to eq(branch_list)
170
+ end
171
+ end
172
+
173
+ describe 'merge_branches' do
174
+ it 'returns false, with conflicts, if merge is not clean' do
175
+ expect(@git).to receive(:current_branch_name).and_return('91/eb/WEB-1723_Ringswitch_DB_Conn_Loss')
176
+ mock_execute(
177
+ "From github.com:/Invoca/web\n" \
178
+ " * branch 85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size -> FETCH_HEAD\n" \
179
+ "warning: Cannot merge binary files: test/fixtures/whitepages.sql (HEAD vs. fedc8e0cfa136d5e1f84005ab6d82235122b0006)\n" \
180
+ "Auto-merging test/workers/adwords_detail_worker_test.rb\n" \
181
+ "CONFLICT (content): Merge conflict in test/workers/adwords_detail_worker_test.rb\n" \
182
+ "CONFLICT (modify/delete): pegasus/backdraft/pegasus_dashboard/spec/views/call_cost_tile_spec.js deleted in fedc8e0cfa136d5e1f84005ab6d82235122b0006 and modified in HEAD. Version HEAD of pegasus/backdraft/pegasus_dashboard/spec/views/call_cost_tile_spec.js left in tree.\n" \
183
+ " Auto-merging pegasus/backdraft/dist/pegasus_dashboard.js\n" \
184
+ "Automatic merge failed; fix conflicts and then commit the result.\n",
185
+ 0
186
+ )
187
+
188
+ conflict = Git::GitConflict.new(
189
+ 'repository_name',
190
+ '91/eb/WEB-1723_Ringswitch_DB_Conn_Loss',
191
+ '85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size',
192
+ ['test/workers/adwords_detail_worker_test.rb', 'pegasus/backdraft/pegasus_dashboard/spec/views/call_cost_tile_spec.js']
193
+ )
194
+ expect(
195
+ @git.merge_branches(
196
+ '91/eb/WEB-1723_Ringswitch_DB_Conn_Loss',
197
+ '85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size'
198
+ )
199
+ ).to eq([false, conflict])
200
+ end
201
+
202
+ it 'aborts unsuccessful merge if requested' do
203
+ expect(@git).to receive(:current_branch_name).and_return('91/eb/WEB-1723_Ringswitch_DB_Conn_Loss')
204
+ mock_execute(
205
+ "From github.com:/Invoca/web\n" \
206
+ " * branch 85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size -> FETCH_HEAD\n" \
207
+ "warning: Cannot merge binary files: test/fixtures/whitepages.sql (HEAD vs. fedc8e0cfa136d5e1f84005ab6d82235122b0006)\n" \
208
+ "Auto-merging test/workers/adwords_detail_worker_test.rb\n" \
209
+ "CONFLICT (content): Merge conflict in test/workers/adwords_detail_worker_test.rb\n" \
210
+ "CONFLICT (modify/delete): pegasus/backdraft/pegasus_dashboard/spec/views/call_cost_tile_spec.js deleted in fedc8e0cfa136d5e1f84005ab6d82235122b0006 and modified in HEAD. Version HEAD of pegasus/backdraft/pegasus_dashboard/spec/views/call_cost_tile_spec.js left in tree.\n" \
211
+ " Auto-merging pegasus/backdraft/dist/pegasus_dashboard.js\n" \
212
+ 'Automatic merge failed; fix conflicts and then commit the result.',
213
+ 0
214
+ )
215
+ expect(@git).to receive(:reset)
216
+
217
+ conflict = Git::GitConflict.new(
218
+ 'repository_name',
219
+ '91/eb/WEB-1723_Ringswitch_DB_Conn_Loss',
220
+ '85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size',
221
+ [
222
+ 'test/workers/adwords_detail_worker_test.rb',
223
+ 'pegasus/backdraft/pegasus_dashboard/spec/views/call_cost_tile_spec.js'
224
+ ]
225
+ )
226
+ expect(
227
+ @git.merge_branches(
228
+ '91/eb/WEB-1723_Ringswitch_DB_Conn_Loss',
229
+ '85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size',
230
+ keep_changes: false
231
+ )
232
+ ).to eq([false, conflict])
233
+ end
234
+
235
+ it 'aborts successful merge if requested' do
236
+ expect(@git).to receive(:current_branch_name).and_return('91/eb/WEB-1723_Ringswitch_DB_Conn_Loss')
237
+ mock_execute(
238
+ "From github.com:/Invoca/web\n" \
239
+ " * branch 85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size -> FETCH_HEAD\n" \
240
+ "Auto-merging test/workers/adwords_detail_worker_test.rb\n" \
241
+ " Auto-merging pegasus/backdraft/dist/pegasus_dashboard.js\n",
242
+ 1
243
+ )
244
+ expect(@git).to receive(:reset)
245
+
246
+ expect(
247
+ @git.merge_branches(
248
+ '91/eb/WEB-1723_Ringswitch_DB_Conn_Loss',
249
+ '85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size',
250
+ keep_changes: false
251
+ )
252
+ ).to eq([true, nil])
253
+ end
254
+
255
+ it 'returns true, with no conflicts, if merge is clean' do
256
+ expect(@git).to receive(:current_branch_name).and_return('91/eb/WEB-1723_Ringswitch_DB_Conn_Loss')
257
+ mock_execute(
258
+ "From github.com:/Invoca/web\n" \
259
+ " * branch 85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size -> FETCH_HEAD\n" \
260
+ "Auto-merging test/workers/adwords_detail_worker_test.rb\n" \
261
+ " Auto-merging pegasus/backdraft/dist/pegasus_dashboard.js\n",
262
+ 1
263
+ )
264
+
265
+ expect(
266
+ @git.merge_branches(
267
+ '91/eb/WEB-1723_Ringswitch_DB_Conn_Loss',
268
+ '85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size'
269
+ )
270
+ ).to eq([true, nil])
271
+ end
272
+
273
+ it 'returns false, with no conflicts, if nothing is merged' do
274
+ expect(@git).to receive(:current_branch_name).and_return('91/eb/WEB-1723_Ringswitch_DB_Conn_Loss')
275
+ mock_execute(
276
+ "From github.com:mikeweaver/git-conflict-detector\n" \
277
+ " * branch master -> FETCH_HEAD\n" \
278
+ "Already up-to-date.\n",
279
+ 1
280
+ )
281
+ expect(
282
+ @git.merge_branches(
283
+ '91/eb/WEB-1723_Ringswitch_DB_Conn_Loss',
284
+ '85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size'
285
+ )
286
+ ).to eq([false, nil])
287
+ end
288
+
289
+ it 'checks out branch if needed' do
290
+ expect(@git).to receive(:current_branch_name).and_return('not_the_right_branch')
291
+ expect(@git).to receive(:checkout_branch)
292
+ mock_execute(
293
+ "From github.com:mikeweaver/git-conflict-detector\n" \
294
+ " * branch master -> FETCH_HEAD\n" \
295
+ "Already up-to-date.\n",
296
+ 1
297
+ )
298
+ expect(
299
+ @git.merge_branches(
300
+ '91/eb/WEB-1723_Ringswitch_DB_Conn_Loss',
301
+ '85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size'
302
+ )
303
+ ).to eq([false, nil])
304
+ end
305
+
306
+ it 'merges a tag, if requested' do
307
+ expect(@git).to receive(:current_branch_name).and_return('91/eb/WEB-1723_Ringswitch_DB_Conn_Loss')
308
+ mock_execute(
309
+ "From github.com:/Invoca/web\n" \
310
+ " * branch 85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size -> FETCH_HEAD\n" \
311
+ "Auto-merging test/workers/adwords_detail_worker_test.rb\n" \
312
+ " Auto-merging pegasus/backdraft/dist/pegasus_dashboard.js\n",
313
+ 1
314
+ )
315
+
316
+ expect(
317
+ @git.merge_branches(
318
+ '91/eb/WEB-1723_Ringswitch_DB_Conn_Loss',
319
+ '85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size',
320
+ source_tag_name: 'tag_name'
321
+ )
322
+ ).to eq([true, nil])
323
+ end
324
+
325
+ it 'escapes backticks and spaces in branch names but not commit messages' do
326
+ expect(@git).to receive(:current_branch_name).and_return('target`name')
327
+ mock_execute(
328
+ "From github.com:/Invoca/web\n" \
329
+ " * branch 85/t/trello_adwords_dashboard_tiles_auto_adjust_font_size -> FETCH_HEAD\n" \
330
+ "Auto-merging test/workers/adwords_detail_worker_test.rb\n",
331
+ 1,
332
+ expected_command: '/usr/bin/git merge --no-edit -m "commit `message" origin/source\\`name\ space'
333
+ )
334
+
335
+ @git.merge_branches(
336
+ 'target`name',
337
+ 'source`name space',
338
+ commit_message: 'commit `message'
339
+ )
340
+ end
341
+ end
342
+
343
+ describe 'lookup_tag' do
344
+ it 'can lookup a tag' do
345
+ mock_execute("tag-exists\n", 1)
346
+ expect(@git.lookup_tag('tag-e*')).to eq('tag-exists')
347
+ end
348
+
349
+ it 'raises when the tag cannot be found' do
350
+ mock_execute('fatal: No names found, cannot describe anything.', 0)
351
+ expect { @git.lookup_tag('does-not-exist') }.to raise_exception(Git::GitError)
352
+ end
353
+ end
354
+
355
+ describe 'file_diff_branch_with_ancestor' do
356
+ it 'can diff the branch' do
357
+ mock_execute("file1.txt\nfile2.txt\n", 1)
358
+ expect(@git.file_diff_branch_with_ancestor('branch', 'ancestor_branch')).to eq(['file1.txt', 'file2.txt'])
359
+ end
360
+
361
+ it 'can handle an up to date branch' do
362
+ mock_execute('', 1)
363
+ expect(@git.file_diff_branch_with_ancestor('branch', 'ancestor_branch')).to eq([])
364
+ end
365
+
366
+ it 'escapes backticks in branch names' do
367
+ mock_execute(
368
+ "file1.txt\nfile2.txt\n",
369
+ 1,
370
+ expected_command: '/usr/bin/git diff --name-only $(git merge-base origin/ancestor\\`_branch origin/branch\\`name)..origin/branch\\`name'
371
+ )
372
+ @git.file_diff_branch_with_ancestor('branch`name', 'ancestor`_branch')
373
+ end
374
+ end
375
+
376
+ describe 'commit_diff_refs' do
377
+ it 'can diff a branch' do
378
+ mocked_output = ["efd778098239838c165ffab2f12ad293f32824c8\tAuthor 1\tauthor1@email.com\t2016-07-14T10:09:45-07:00\tMerge branch 'production'\n",
379
+ "667f3e5347c48c04663209682642fd8d6d93fde2\tAuthor 2\tauthor2@email.com\t2016-07-14T16:46:35-07:00\tMerge pull request #5584 from Owner/repo/dimension_repair\n"].join
380
+ expected_array = [Git::GitCommit.new('efd778098239838c165ffab2f12ad293f32824c8', "Merge branch 'production'", nil, 'Author 1', 'author1@email.com'),
381
+ Git::GitCommit.new('667f3e5347c48c04663209682642fd8d6d93fde2', 'Merge pull request #5584 from Owner/repo/dimension_repair', nil, 'Author 2', 'author2@email.com')]
382
+ mock_execute(
383
+ mocked_output,
384
+ 1,
385
+ expected_command: "/usr/bin/git log --format=%H\t%an\t%ae\t%aI\t%s --no-color origin/ancestor_branch..origin/branch"
386
+ )
387
+ expect(@git.commit_diff_refs('branch', 'ancestor_branch')).to eq(expected_array)
388
+ end
389
+
390
+ it 'can handle a comparison with no changes' do
391
+ mock_execute('', 1)
392
+ expect(@git.commit_diff_refs('branch', 'ancestor_branch')).to eq([])
393
+ end
394
+
395
+ it 'can fetch before doing the comparison' do
396
+ mock_execute('', 1)
397
+ expect(@git).to receive(:fetch_all)
398
+ expect(@git.commit_diff_refs('branch', 'ancestor_branch', fetch: true)).to eq([])
399
+ end
400
+
401
+ it 'can diff a sha with a branch' do
402
+ mock_execute(
403
+ '',
404
+ 1,
405
+ expected_command: "/usr/bin/git log --format=%H\t%an\t%ae\t%aI\t%s --no-color origin/ancestor_branch..e2a7e607745d63da4d7f8486e0619e91a410f796"
406
+ )
407
+ @git.commit_diff_refs('e2a7e607745d63da4d7f8486e0619e91a410f796', 'ancestor_branch')
408
+ end
409
+
410
+ it 'can diff a sha with a sha' do
411
+ mock_execute(
412
+ '',
413
+ 1,
414
+ expected_command: "/usr/bin/git log --format=%H\t%an\t%ae\t%aI\t%s --no-color c5e8de4eb36a2d1b9f66543966ede9ce9cc28a89..e2a7e607745d63da4d7f8486e0619e91a410f796"
415
+ )
416
+ @git.commit_diff_refs('e2a7e607745d63da4d7f8486e0619e91a410f796', 'c5e8de4eb36a2d1b9f66543966ede9ce9cc28a89')
417
+ end
418
+
419
+ it 'escapes backticks in ref names' do
420
+ mock_execute(
421
+ '',
422
+ 1,
423
+ expected_command: "/usr/bin/git log --format=%H\t%an\t%ae\t%aI\t%s --no-color origin/ancestor\\`_branch..origin/branch\\`name"
424
+ )
425
+ @git.commit_diff_refs('branch`name', 'ancestor`_branch')
426
+ end
427
+ end
428
+
429
+ describe 'get_current_branch_name' do
430
+ it 'can get the branch name' do
431
+ mock_execute("path/branch\n", 1)
432
+ expect(@git.current_branch_name).to eq('path/branch')
433
+ end
434
+ end
435
+ end
436
+ end