View | Details | Raw Unified | Return to bug 215787 | Differences between
and this patch

Collapse All | Expand All

(-)www/gitlab/Makefile (-2 / +2 lines)
Lines 4-10 Link Here
4
PORTNAME=	gitlab
4
PORTNAME=	gitlab
5
PORTVERSION=	8.11.11
5
PORTVERSION=	8.11.11
6
DISTVERSIONPREFIX=	v
6
DISTVERSIONPREFIX=	v
7
PORTREVISION=	6
7
PORTREVISION=	7
8
CATEGORIES=	www devel
8
CATEGORIES=	www devel
9
9
10
MAINTAINER=	tz@FreeBSD.org
10
MAINTAINER=	tz@FreeBSD.org
Lines 133-139 Link Here
133
	rubygem-gon>=6.1.0:www/rubygem-gon \
133
	rubygem-gon>=6.1.0:www/rubygem-gon \
134
	rubygem-jquery-atwho-rails-rails4>=1.3.2:www/rubygem-jquery-atwho-rails-rails4 \
134
	rubygem-jquery-atwho-rails-rails4>=1.3.2:www/rubygem-jquery-atwho-rails-rails4 \
135
	rubygem-jquery-rails4>=4.1.0:www/rubygem-jquery-rails4 \
135
	rubygem-jquery-rails4>=4.1.0:www/rubygem-jquery-rails4 \
136
	rubygem-jquery-ui-rails-rails4>=5.0.0:www/rubygem-jquery-ui-rails-rails4 \
136
	rubygem-jquery-ui-rails5-rails4>=5.0.0:www/rubygem-jquery-ui-rails5-rails4 \
137
	rubygem-request_store>=1.3.0:devel/rubygem-request_store \
137
	rubygem-request_store>=1.3.0:devel/rubygem-request_store \
138
	rubygem-select2-rails>=3.5.9:www/rubygem-select2-rails \
138
	rubygem-select2-rails>=3.5.9:www/rubygem-select2-rails \
139
	rubygem-virtus>=1.0.1:devel/rubygem-virtus \
139
	rubygem-virtus>=1.0.1:devel/rubygem-virtus \
(-)www/gitlab/files/patch-6130 (+210 lines)
Line 0 Link Here
1
diff --git a/app/models/repository.rb b/app/models/repository.rb
2
index f891e83..b064425 100644
3
--- app/models/repository.rb
4
+++ app/models/repository.rb
5
@@ -149,7 +149,7 @@ class Repository
6
     return false unless target
7
 
8
     GitHooksService.new.execute(user, path_to_repo, oldrev, target, ref) do
9
-      rugged.branches.create(branch_name, target)
10
+      update_ref!(ref, target, oldrev)
11
     end
12
 
13
     after_create_branch
14
@@ -181,7 +181,7 @@ class Repository
15
     ref    = Gitlab::Git::BRANCH_REF_PREFIX + branch_name
16
 
17
     GitHooksService.new.execute(user, path_to_repo, oldrev, newrev, ref) do
18
-      rugged.branches.delete(branch_name)
19
+      update_ref!(ref, newrev, oldrev)
20
     end
21
 
22
     after_remove_branch
23
@@ -215,6 +215,21 @@ class Repository
24
     rugged.references.exist?(ref)
25
   end
26
 
27
+  def update_ref!(name, newrev, oldrev)
28
+    # We use 'git update-ref' because libgit2/rugged currently does not
29
+    # offer 'compare and swap' ref updates. Without compare-and-swap we can
30
+    # (and have!) accidentally reset the ref to an earlier state, clobbering
31
+    # commits. See also https://github.com/libgit2/libgit2/issues/1534.
32
+    command = %w[git update-ref --stdin -z]
33
+    output, status = Gitlab::Popen.popen(command, path_to_repo) do |stdin|
34
+      stdin.write("update #{name}\x00#{newrev}\x00#{oldrev}\x00")
35
+    end
36
+
37
+    return if status.zero?
38
+
39
+    raise CommitError.new("error updating ref #{name} #{oldrev}->#{newrev}\n#{output}")
40
+  end
41
+
42
   # Makes sure a commit is kept around when Git garbage collection runs.
43
   # Git GC will delete commits from the repository that are no longer in any
44
   # branches or tags, but we want to keep some of these commits around, for
45
@@ -1014,15 +1029,10 @@ class Repository
46
   def commit_with_hooks(current_user, branch)
47
     update_autocrlf_option
48
 
49
-    oldrev = Gitlab::Git::BLANK_SHA
50
     ref = Gitlab::Git::BRANCH_REF_PREFIX + branch
51
     target_branch = find_branch(branch)
52
     was_empty = empty?
53
 
54
-    if !was_empty && target_branch
55
-      oldrev = target_branch.target.id
56
-    end
57
-
58
     # Make commit
59
     newrev = yield(ref)
60
 
61
@@ -1030,24 +1040,15 @@ class Repository
62
       raise CommitError.new('Failed to create commit')
63
     end
64
 
65
+    oldrev = rugged.lookup(newrev).parent_ids.first || Gitlab::Git::BLANK_SHA
66
+
67
     GitHooksService.new.execute(current_user, path_to_repo, oldrev, newrev, ref) do
68
+      update_ref!(ref, newrev, oldrev)
69
+      
70
       if was_empty || !target_branch
71
-        # Create branch
72
-        rugged.references.create(ref, newrev)
73
-
74
         # If repo was empty expire cache
75
         after_create if was_empty
76
         after_create_branch
77
-      else
78
-        # Update head
79
-        current_head = find_branch(branch).target.id
80
-
81
-        # Make sure target branch was not changed during pre-receive hook
82
-        if current_head == oldrev
83
-          rugged.references.update(ref, newrev)
84
-        else
85
-          raise CommitError.new('Commit was rejected because branch received new push')
86
-        end
87
       end
88
     end
89
 
90
diff --git a/lib/gitlab/popen.rb b/lib/gitlab/popen.rb
91
index ca23cce..a0fd411 100644
92
--- lib/gitlab/popen.rb
93
+++ lib/gitlab/popen.rb
94
@@ -21,9 +21,9 @@ module Gitlab
95
       @cmd_output = ""
96
       @cmd_status = 0
97
       Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
98
-        # We are not using stdin so we should close it, in case the command we
99
-        # are running waits for input.
100
+        yield(stdin) if block_given?
101
         stdin.close
102
+
103
         @cmd_output << stdout.read
104
         @cmd_output << stderr.read
105
         @cmd_status = wait_thr.value.exitstatus
106
diff --git a/spec/lib/gitlab/popen_spec.rb b/spec/lib/gitlab/popen_spec.rb
107
index e8b2364..4ae216d 100644
108
--- spec/lib/gitlab/popen_spec.rb
109
+++ spec/lib/gitlab/popen_spec.rb
110
@@ -40,4 +40,13 @@ describe 'Gitlab::Popen', lib: true, no_db: true do
111
     it { expect(@status).to be_zero }
112
     it { expect(@output).to include('spec') }
113
   end
114
+
115
+  context 'use stdin' do
116
+    before do
117
+      @output, @status = @klass.new.popen(%w[cat]) { |stdin| stdin.write 'hello' }
118
+    end
119
+  
120
+    it { expect(@status).to be_zero }
121
+    it { expect(@output).to eq('hello') }
122
+  end
123
 end
124
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
125
index 812c72c..afc7dc5 100644
126
--- spec/models/repository_spec.rb
127
+++ spec/models/repository_spec.rb
128
@@ -443,31 +443,32 @@ describe Repository, models: true do
129
 
130
   describe '#commit_with_hooks' do
131
     let(:old_rev) { '0b4bc9a49b562e85de7cc9e834518ea6828729b9' } # git rev-parse feature
132
+    let(:new_rev) { 'a74ae73c1ccde9b974a70e82b901588071dc142a' } # commit whose parent is old_rev
133
 
134
     context 'when pre hooks were successful' do
135
       before do
136
         expect_any_instance_of(GitHooksService).to receive(:execute).
137
-          with(user, repository.path_to_repo, old_rev, sample_commit.id, 'refs/heads/feature').
138
+          with(user, repository.path_to_repo, old_rev, new_rev, 'refs/heads/feature').
139
           and_yield.and_return(true)
140
       end
141
 
142
       it 'runs without errors' do
143
         expect do
144
-          repository.commit_with_hooks(user, 'feature') { sample_commit.id }
145
+          repository.commit_with_hooks(user, 'feature') { new_rev }
146
         end.not_to raise_error
147
       end
148
 
149
       it 'ensures the autocrlf Git option is set to :input' do
150
         expect(repository).to receive(:update_autocrlf_option)
151
 
152
-        repository.commit_with_hooks(user, 'feature') { sample_commit.id }
153
+        repository.commit_with_hooks(user, 'feature') { new_rev }
154
       end
155
 
156
       context "when the branch wasn't empty" do
157
         it 'updates the head' do
158
           expect(repository.find_branch('feature').target.id).to eq(old_rev)
159
-          repository.commit_with_hooks(user, 'feature') { sample_commit.id }
160
-          expect(repository.find_branch('feature').target.id).to eq(sample_commit.id)
161
+          repository.commit_with_hooks(user, 'feature') { new_rev }
162
+          expect(repository.find_branch('feature').target.id).to eq(new_rev)
163
         end
164
       end
165
     end
166
@@ -477,7 +478,7 @@ describe Repository, models: true do
167
         allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([false, ''])
168
 
169
         expect do
170
-          repository.commit_with_hooks(user, 'feature') { sample_commit.id }
171
+          repository.commit_with_hooks(user, 'feature') { new_rev }
172
         end.to raise_error(GitHooksService::PreReceiveError)
173
       end
174
     end
175
@@ -485,6 +486,7 @@ describe Repository, models: true do
176
     context 'when target branch is different from source branch' do
177
       before do
178
         allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([true, ''])
179
+        allow(repository).to receive(:update_ref!)
180
       end
181
 
182
       it 'expires branch cache' do
183
@@ -495,7 +497,7 @@ describe Repository, models: true do
184
         expect(repository).to     receive(:expire_has_visible_content_cache)
185
         expect(repository).to     receive(:expire_branch_count_cache)
186
 
187
-        repository.commit_with_hooks(user, 'new-feature') { sample_commit.id }
188
+        repository.commit_with_hooks(user, 'new-feature') { new_rev }
189
       end
190
     end
191
 
192
@@ -1268,4 +1270,18 @@ describe Repository, models: true do
193
       File.delete(path)
194
     end
195
   end
196
+
197
+  describe '#update_ref!' do
198
+    it 'can create a ref' do
199
+      repository.update_ref!('refs/heads/foobar', 'refs/heads/master', Gitlab::Git::BLANK_SHA)
200
+
201
+      expect(repository.find_branch('foobar')).not_to be_nil
202
+    end
203
+
204
+    it 'raises CommitError when the ref update fails' do
205
+      expect do
206
+        repository.update_ref!('refs/heads/master', 'refs/heads/master', Gitlab::Git::BLANK_SHA)
207
+      end.to raise_error(Repository::CommitError)
208
+    end
209
+  end
210
 end
(-)www/gitlab/files/patch-Gemfile (-16 / +56 lines)
Lines 1-5 Link Here
1
--- Gemfile.orig	2016-11-09 05:10:18 UTC
1
--- Gemfile.orig	2017-01-04 21:07:00.413929000 -0500
2
+++ Gemfile
2
+++ Gemfile	2017-01-04 21:06:45.052347000 -0500
3
@@ -1,6 +1,6 @@
3
@@ -1,6 +1,6 @@
4
 source 'https://rubygems.org'
4
 source 'https://rubygems.org'
5
 
5
 
Lines 27-38 Link Here
27
 
27
 
28
 # Authentication libraries
28
 # Authentication libraries
29
 gem 'devise',                 '~> 4.0'
29
 gem 'devise',                 '~> 4.0'
30
@@ -30,12 +29,11 @@ gem 'omniauth-facebook',      '~> 3.0.0'
30
@@ -26,20 +25,19 @@ gem 'omniauth-auth0',         '~> 1.4.1'
31
 gem 'omniauth-azure-oauth2',  '~> 0.0.6'
32
 gem 'omniauth-bitbucket',     '~> 0.0.2'
33
 gem 'omniauth-cas3',          '~> 1.1.2'
34
-gem 'omniauth-facebook',      '~> 3.0.0'
35
+gem 'omniauth-facebook',      '>= 3.0.0'
31
 gem 'omniauth-github',        '~> 1.1.1'
36
 gem 'omniauth-github',        '~> 1.1.1'
32
 gem 'omniauth-gitlab',        '~> 1.0.0'
37
 gem 'omniauth-gitlab',        '~> 1.0.0'
33
 gem 'omniauth-google-oauth2', '~> 0.4.1'
38
 gem 'omniauth-google-oauth2', '~> 0.4.1'
34
-gem 'omniauth-kerberos',      '~> 0.3.0', group: :kerberos
39
-gem 'omniauth-kerberos',      '~> 0.3.0', group: :kerberos
35
 gem 'omniauth-saml',          '~> 1.6.0'
40
-gem 'omniauth-saml',          '~> 1.6.0'
41
+gem 'omniauth-saml',          '>= 1.6.0'
36
 gem 'omniauth-shibboleth',    '~> 1.2.0'
42
 gem 'omniauth-shibboleth',    '~> 1.2.0'
37
 gem 'omniauth-twitter',       '~> 1.2.0'
43
 gem 'omniauth-twitter',       '~> 1.2.0'
38
 gem 'omniauth_crowd',         '~> 2.2.0'
44
 gem 'omniauth_crowd',         '~> 2.2.0'
Lines 41-47 Link Here
41
 gem 'jwt'
47
 gem 'jwt'
42
 
48
 
43
 # Spam and anti-bot protection
49
 # Spam and anti-bot protection
44
@@ -66,11 +64,11 @@ gem 'gollum-lib', '~> 4.2', require: fal
50
-gem 'recaptcha', '~> 3.0', require: 'recaptcha/rails'
51
+gem 'recaptcha', '>= 3.0', require: 'recaptcha/rails'
52
 gem 'akismet', '~> 2.0'
53
 
54
 # Two-factor authentication
55
@@ -66,21 +64,21 @@ gem 'gollum-lib', '~> 4.2', require: fal
45
 gem 'gollum-rugged_adapter', '~> 0.4.2', require: false
56
 gem 'gollum-rugged_adapter', '~> 0.4.2', require: false
46
 
57
 
47
 # Language detection
58
 # Language detection
Lines 56-64 Link Here
56
 gem 'rack-cors',    '~> 0.4.0', require: 'rack/cors'
67
 gem 'rack-cors',    '~> 0.4.0', require: 'rack/cors'
57
 
68
 
58
 # Pagination
69
 # Pagination
59
@@ -80,7 +78,7 @@ gem 'kaminari', '~> 0.17.0'
70
 gem 'kaminari', '~> 0.17.0'
60
 gem 'hamlit', '~> 2.6.1'
61
 
71
 
72
 # HAML
73
-gem 'hamlit', '~> 2.6.1'
74
+gem 'hamlit', '>= 2.6.1'
75
 
62
 # Files attachments
76
 # Files attachments
63
-gem 'carrierwave', '~> 0.10.0'
77
-gem 'carrierwave', '~> 0.10.0'
64
+gem 'carrierwave', '>= 0.10.0'
78
+gem 'carrierwave', '>= 0.10.0'
Lines 65-73 Link Here
65
 
79
 
66
 # Drag and Drop UI
80
 # Drag and Drop UI
67
 gem 'dropzonejs-rails', '~> 0.7.1'
81
 gem 'dropzonejs-rails', '~> 0.7.1'
68
@@ -109,10 +107,10 @@ gem 'task_list',     '~> 1.0.2', require
82
@@ -107,25 +105,25 @@ gem 'seed-fu', '~> 2.3.5'
83
 gem 'html-pipeline', '~> 1.11.0'
84
 gem 'task_list',     '~> 1.0.2', require: 'task_list/railtie'
69
 gem 'github-markup', '~> 1.4'
85
 gem 'github-markup', '~> 1.4'
70
 gem 'redcarpet',     '~> 3.3.3'
86
-gem 'redcarpet',     '~> 3.3.3'
87
+gem 'redcarpet',     '>= 3.3.3'
71
 gem 'RedCloth',      '~> 4.3.2'
88
 gem 'RedCloth',      '~> 4.3.2'
72
-gem 'rdoc',          '~>3.6'
89
-gem 'rdoc',          '~>3.6'
73
+gem 'rdoc',          '>= 3.6'
90
+gem 'rdoc',          '>= 3.6'
Lines 78-85 Link Here
78
 gem 'asciidoctor',   '~> 1.5.2'
95
 gem 'asciidoctor',   '~> 1.5.2'
79
 gem 'rouge',         '~> 2.0'
96
 gem 'rouge',         '~> 2.0'
80
 
97
 
81
@@ -121,11 +119,11 @@ gem 'rouge',         '~> 2.0'
98
 # See https://groups.google.com/forum/#!topic/ruby-security-ann/aSbgDiwb24s
82
 gem 'nokogiri', '~> 1.6.7', '>= 1.6.7.2'
99
 # and https://groups.google.com/forum/#!topic/ruby-security-ann/Dy7YiKb_pMM
100
-gem 'nokogiri', '~> 1.6.7', '>= 1.6.7.2'
101
+gem 'nokogiri', '>= 1.6.7.2'
83
 
102
 
84
 # Diffs
103
 # Diffs
85
-gem 'diffy', '~> 3.0.3'
104
-gem 'diffy', '~> 3.0.3'
Lines 135-141 Link Here
135
 
154
 
136
 # Ace editor
155
 # Ace editor
137
 gem 'ace-rails-ap', '~> 4.1.0'
156
 gem 'ace-rails-ap', '~> 4.1.0'
138
@@ -215,22 +213,22 @@ gem 'chronic_duration', '~> 0.10.6'
157
@@ -215,125 +213,42 @@ gem 'chronic_duration', '~> 0.10.6'
139
 
158
 
140
 gem 'sass-rails', '~> 5.0.0'
159
 gem 'sass-rails', '~> 5.0.0'
141
 gem 'coffee-rails', '~> 4.1.0'
160
 gem 'coffee-rails', '~> 4.1.0'
Lines 147-153 Link Here
147
-gem 'addressable',        '~> 2.3.8'
166
-gem 'addressable',        '~> 2.3.8'
148
+gem 'addressable',        '>= 2.3.8'
167
+gem 'addressable',        '>= 2.3.8'
149
 gem 'bootstrap-sass',     '~> 3.3.0'
168
 gem 'bootstrap-sass',     '~> 3.3.0'
150
 gem 'font-awesome-rails', '~> 4.6.1'
169
-gem 'font-awesome-rails', '~> 4.6.1'
170
+gem 'font-awesome-rails', '>= 4.6.1'
151
 gem 'gemojione',          '~> 3.0'
171
 gem 'gemojione',          '~> 3.0'
152
 gem 'gon',                '~> 6.1.0'
172
 gem 'gon',                '~> 6.1.0'
153
 gem 'jquery-atwho-rails', '~> 1.3.2'
173
 gem 'jquery-atwho-rails', '~> 1.3.2'
Lines 163-169 Link Here
163
 gem 'base32',             '~> 0.3.0'
183
 gem 'base32',             '~> 0.3.0'
164
 
184
 
165
 # Sentry integration
185
 # Sentry integration
166
@@ -238,89 +236,6 @@ gem 'sentry-raven', '~> 2.0.0'
186
-gem 'sentry-raven', '~> 2.0.0'
187
+gem 'sentry-raven', '>= 2.0.0'
167
 
188
 
168
 gem 'premailer-rails', '~> 1.9.0'
189
 gem 'premailer-rails', '~> 1.9.0'
169
 
190
 
Lines 253-261 Link Here
253
 group :production do
274
 group :production do
254
   gem 'gitlab_meta', '7.0'
275
   gem 'gitlab_meta', '7.0'
255
 end
276
 end
256
@@ -349,5 +264,7 @@ gem 'paranoia', '~> 2.0'
257
 gem 'health_check', '~> 2.1.0'
258
 
277
 
278
 gem 'newrelic_rpm', '~> 3.16'
279
 
280
-gem 'octokit', '~> 4.3.0'
281
+gem 'octokit', '>= 4.3.0'
282
 
283
 gem 'mail_room', '~> 0.8'
284
 
285
 gem 'email_reply_parser', '~> 0.5.8'
286
 
287
-gem 'ruby-prof', '~> 0.15.9'
288
+gem 'ruby-prof', '>= 0.15.9'
289
 
290
 ## CI
291
 gem 'activerecord-session_store', '~> 1.0.0'
292
@@ -346,8 +261,10 @@ gem 'oauth2', '~> 1.2.0'
293
 gem 'paranoia', '~> 2.0'
294
 
295
 # Health check
296
-gem 'health_check', '~> 2.1.0'
297
+gem 'health_check', '>= 2.1.0'
298
 
259
 # System information
299
 # System information
260
-gem 'vmstat', '~> 2.2'
300
-gem 'vmstat', '~> 2.2'
261
+gem 'vmstat', '>= 2.1.1'
301
+gem 'vmstat', '>= 2.1.1'

Return to bug 215787