Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
35d3c6df
Commit
35d3c6df
authored
Aug 12, 2015
by
Valery Sizov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '7-13-5-stable-candidate' into '7-13-stable'
7-13-5-stable candidate See merge request !1145
parents
7c3e8bcd
f4f6d60c
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
415 additions
and
289 deletions
+415
-289
CHANGELOG
CHANGELOG
+4
-1
app/controllers/projects/blob_controller.rb
app/controllers/projects/blob_controller.rb
+30
-30
app/models/merge_request.rb
app/models/merge_request.rb
+1
-8
app/models/repository.rb
app/models/repository.rb
+0
-56
app/services/files/base_service.rb
app/services/files/base_service.rb
+5
-75
app/services/files/create_service.rb
app/services/files/create_service.rb
+33
-11
app/services/files/delete_service.rb
app/services/files/delete_service.rb
+30
-3
app/services/files/update_service.rb
app/services/files/update_service.rb
+33
-3
app/services/git_push_service.rb
app/services/git_push_service.rb
+1
-2
app/services/merge_requests/auto_merge_service.rb
app/services/merge_requests/auto_merge_service.rb
+3
-48
app/views/projects/blob/_editor.html.haml
app/views/projects/blob/_editor.html.haml
+2
-2
app/views/projects/blob/new.html.haml
app/views/projects/blob/new.html.haml
+5
-6
lib/api/files.rb
lib/api/files.rb
+24
-26
lib/gitlab/satellite/files/delete_file_action.rb
lib/gitlab/satellite/files/delete_file_action.rb
+50
-0
lib/gitlab/satellite/files/edit_file_action.rb
lib/gitlab/satellite/files/edit_file_action.rb
+68
-0
lib/gitlab/satellite/files/file_action.rb
lib/gitlab/satellite/files/file_action.rb
+25
-0
lib/gitlab/satellite/files/new_file_action.rb
lib/gitlab/satellite/files/new_file_action.rb
+67
-0
spec/models/repository_spec.rb
spec/models/repository_spec.rb
+0
-14
spec/requests/api/files_spec.rb
spec/requests/api/files_spec.rb
+34
-4
No files found.
CHANGELOG
View file @
35d3c6df
Please view this file on the master branch, on stable branches it's out of date.
Please view this file on the master branch, on stable branches it's out of date.
v 7.13.5
- Satellites reverted
v 7.13.4
v 7.13.4
- Allow users to send abuse reports
- Allow users to send abuse reports
...
@@ -142,7 +146,6 @@ v 7.12.0
...
@@ -142,7 +146,6 @@ v 7.12.0
- Add SAML support as an omniauth provider
- Add SAML support as an omniauth provider
- Allow to configure a URL to show after sign out
- Allow to configure a URL to show after sign out
- Add an option to automatically sign-in with an Omniauth provider
- Add an option to automatically sign-in with an Omniauth provider
- Better performance for web editor (switched from satellites to rugged)
- GitLab CI service sends .gitlab-ci.yml in each push call
- GitLab CI service sends .gitlab-ci.yml in each push call
- When remove project - move repository and schedule it removal
- When remove project - move repository and schedule it removal
- Improve group removing logic
- Improve group removing logic
...
...
app/controllers/projects/blob_controller.rb
View file @
35d3c6df
...
@@ -13,20 +13,27 @@ class Projects::BlobController < Projects::ApplicationController
...
@@ -13,20 +13,27 @@ class Projects::BlobController < Projects::ApplicationController
before_action
:commit
,
except:
[
:new
,
:create
]
before_action
:commit
,
except:
[
:new
,
:create
]
before_action
:blob
,
except:
[
:new
,
:create
]
before_action
:blob
,
except:
[
:new
,
:create
]
before_action
:from_merge_request
,
only:
[
:edit
,
:update
]
before_action
:from_merge_request
,
only:
[
:edit
,
:update
]
before_action
:require_branch_head
,
only:
[
:edit
,
:update
]
before_action
:editor_variables
,
except:
[
:show
,
:preview
,
:diff
]
before_action
:after_edit_path
,
only:
[
:edit
,
:update
]
before_action
:after_edit_path
,
only:
[
:edit
,
:update
]
before_action
:require_branch_head
,
only:
[
:edit
,
:update
]
def
new
def
new
commit
unless
@repository
.
empty?
commit
unless
@repository
.
empty?
end
end
def
create
def
create
result
=
Files
::
CreateService
.
new
(
@project
,
current_user
,
@commit_params
).
execute
file_path
=
File
.
join
(
@path
,
File
.
basename
(
params
[
:file_name
]))
result
=
Files
::
CreateService
.
new
(
@project
,
current_user
,
params
.
merge
(
new_branch:
sanitized_new_branch_name
),
@ref
,
file_path
).
execute
if
result
[
:status
]
==
:success
if
result
[
:status
]
==
:success
flash
[
:notice
]
=
"Your changes have been successfully committed"
flash
[
:notice
]
=
"Your changes have been successfully committed"
redirect_to
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
File
.
join
(
@target_branch
,
@file_path
))
ref
=
sanitized_new_branch_name
.
presence
||
@ref
redirect_to
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
File
.
join
(
ref
,
file_path
))
else
else
flash
[
:alert
]
=
result
[
:message
]
flash
[
:alert
]
=
result
[
:message
]
render
:new
render
:new
...
@@ -41,10 +48,22 @@ class Projects::BlobController < Projects::ApplicationController
...
@@ -41,10 +48,22 @@ class Projects::BlobController < Projects::ApplicationController
end
end
def
update
def
update
result
=
Files
::
UpdateService
.
new
(
@project
,
current_user
,
@commit_params
).
execute
result
=
Files
::
UpdateService
.
new
(
@project
,
current_user
,
params
.
merge
(
new_branch:
sanitized_new_branch_name
),
@ref
,
@path
).
execute
if
result
[
:status
]
==
:success
if
result
[
:status
]
==
:success
flash
[
:notice
]
=
"Your changes have been successfully committed"
flash
[
:notice
]
=
"Your changes have been successfully committed"
if
from_merge_request
from_merge_request
.
reload_code
end
redirect_to
after_edit_path
redirect_to
after_edit_path
else
else
flash
[
:alert
]
=
result
[
:message
]
flash
[
:alert
]
=
result
[
:message
]
...
@@ -61,11 +80,12 @@ class Projects::BlobController < Projects::ApplicationController
...
@@ -61,11 +80,12 @@ class Projects::BlobController < Projects::ApplicationController
end
end
def
destroy
def
destroy
result
=
Files
::
DeleteService
.
new
(
@project
,
current_user
,
@commit_params
).
execute
result
=
Files
::
DeleteService
.
new
(
@project
,
current_user
,
params
,
@ref
,
@path
).
execute
if
result
[
:status
]
==
:success
if
result
[
:status
]
==
:success
flash
[
:notice
]
=
"Your changes have been successfully committed"
flash
[
:notice
]
=
"Your changes have been successfully committed"
redirect_to
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
@target_branch
)
redirect_to
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
@ref
)
else
else
flash
[
:alert
]
=
result
[
:message
]
flash
[
:alert
]
=
result
[
:message
]
render
:show
render
:show
...
@@ -115,6 +135,7 @@ class Projects::BlobController < Projects::ApplicationController
...
@@ -115,6 +135,7 @@ class Projects::BlobController < Projects::ApplicationController
@id
=
params
[
:id
]
@id
=
params
[
:id
]
@ref
,
@path
=
extract_ref
(
@id
)
@ref
,
@path
=
extract_ref
(
@id
)
rescue
InvalidPathError
rescue
InvalidPathError
not_found!
not_found!
end
end
...
@@ -124,8 +145,8 @@ class Projects::BlobController < Projects::ApplicationController
...
@@ -124,8 +145,8 @@ class Projects::BlobController < Projects::ApplicationController
if
from_merge_request
if
from_merge_request
diffs_namespace_project_merge_request_path
(
from_merge_request
.
target_project
.
namespace
,
from_merge_request
.
target_project
,
from_merge_request
)
+
diffs_namespace_project_merge_request_path
(
from_merge_request
.
target_project
.
namespace
,
from_merge_request
.
target_project
,
from_merge_request
)
+
"#file-path-
#{
hexdigest
(
@path
)
}
"
"#file-path-
#{
hexdigest
(
@path
)
}
"
elsif
@target_branch
.
present?
elsif
sanitized_new_branch_name
.
present?
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
File
.
join
(
@target_branch
,
@path
))
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
File
.
join
(
sanitized_new_branch_name
,
@path
))
else
else
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
@id
)
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
@id
)
end
end
...
@@ -139,25 +160,4 @@ class Projects::BlobController < Projects::ApplicationController
...
@@ -139,25 +160,4 @@ class Projects::BlobController < Projects::ApplicationController
def
sanitized_new_branch_name
def
sanitized_new_branch_name
@new_branch
||=
sanitize
(
strip_tags
(
params
[
:new_branch
]))
@new_branch
||=
sanitize
(
strip_tags
(
params
[
:new_branch
]))
end
end
def
editor_variables
@current_branch
=
@ref
@target_branch
=
(
sanitized_new_branch_name
||
@ref
)
@file_path
=
if
action_name
.
to_s
==
'create'
File
.
join
(
@path
,
File
.
basename
(
params
[
:file_name
]))
else
@path
end
@commit_params
=
{
file_path:
@file_path
,
current_branch:
@current_branch
,
target_branch:
@target_branch
,
commit_message:
params
[
:commit_message
],
file_content:
params
[
:content
],
file_content_encoding:
params
[
:encoding
]
}
end
end
end
app/models/merge_request.rb
View file @
35d3c6df
...
@@ -205,14 +205,7 @@ class MergeRequest < ActiveRecord::Base
...
@@ -205,14 +205,7 @@ class MergeRequest < ActiveRecord::Base
end
end
def
check_if_can_be_merged
def
check_if_can_be_merged
can_be_merged
=
if
Gitlab
::
Satellite
::
MergeAction
.
new
(
self
.
author
,
self
).
can_be_merged?
if
for_fork?
Gitlab
::
Satellite
::
MergeAction
.
new
(
self
.
author
,
self
).
can_be_merged?
else
project
.
repository
.
can_be_merged?
(
source_branch
,
target_branch
)
end
if
can_be_merged
mark_as_mergeable
mark_as_mergeable
else
else
mark_as_unmergeable
mark_as_unmergeable
...
...
app/models/repository.rb
View file @
35d3c6df
...
@@ -364,62 +364,6 @@ class Repository
...
@@ -364,62 +364,6 @@ class Repository
@root_ref
||=
raw_repository
.
root_ref
@root_ref
||=
raw_repository
.
root_ref
end
end
def
commit_file
(
user
,
path
,
content
,
message
,
ref
)
path
[
0
]
=
''
if
path
[
0
]
==
'/'
committer
=
user_to_comitter
(
user
)
options
=
{}
options
[
:committer
]
=
committer
options
[
:author
]
=
committer
options
[
:commit
]
=
{
message:
message
,
branch:
ref
}
options
[
:file
]
=
{
content:
content
,
path:
path
}
Gitlab
::
Git
::
Blob
.
commit
(
raw_repository
,
options
)
end
def
remove_file
(
user
,
path
,
message
,
ref
)
path
[
0
]
=
''
if
path
[
0
]
==
'/'
committer
=
user_to_comitter
(
user
)
options
=
{}
options
[
:committer
]
=
committer
options
[
:author
]
=
committer
options
[
:commit
]
=
{
message:
message
,
branch:
ref
}
options
[
:file
]
=
{
path:
path
}
Gitlab
::
Git
::
Blob
.
remove
(
raw_repository
,
options
)
end
def
user_to_comitter
(
user
)
{
email:
user
.
email
,
name:
user
.
name
,
time:
Time
.
now
}
end
def
can_be_merged?
(
source_branch
,
target_branch
)
our_commit
=
rugged
.
branches
[
target_branch
].
target
their_commit
=
rugged
.
branches
[
source_branch
].
target
if
our_commit
&&
their_commit
!
rugged
.
merge_commits
(
our_commit
,
their_commit
).
conflicts?
end
end
def
search_files
(
query
,
ref
)
def
search_files
(
query
,
ref
)
offset
=
2
offset
=
2
args
=
%W(git grep -i -n --before-context
#{
offset
}
--after-context
#{
offset
}
#{
query
}
#{
ref
||
root_ref
}
)
args
=
%W(git grep -i -n --before-context
#{
offset
}
--after-context
#{
offset
}
#{
query
}
#{
ref
||
root_ref
}
)
...
...
app/services/files/base_service.rb
View file @
35d3c6df
module
Files
module
Files
class
BaseService
<
::
BaseService
class
BaseService
<
::
BaseService
class
ValidationError
<
StandardError
;
end
attr_reader
:ref
,
:path
def
execute
def
initialize
(
project
,
user
,
params
,
ref
,
path
=
nil
)
@current_branch
=
params
[
:current_branch
]
@project
,
@current_user
,
@params
=
project
,
user
,
params
.
dup
@target_branch
=
params
[
:target_branch
]
@ref
=
ref
@commit_message
=
params
[
:commit_message
]
@path
=
path
@file_path
=
params
[
:file_path
]
@file_content
=
if
params
[
:file_content_encoding
]
==
'base64'
Base64
.
decode64
(
params
[
:file_content
])
else
params
[
:file_content
]
end
# Validate parameters
validate
# Create new branch if it different from current_branch
if
@target_branch
!=
@current_branch
create_target_branch
end
if
sha
=
commit
after_commit
(
sha
,
@target_branch
)
success
else
error
(
"Something went wrong. Your changes were not committed"
)
end
rescue
ValidationError
=>
ex
error
(
ex
.
message
)
end
end
private
private
...
@@ -36,52 +13,5 @@ module Files
...
@@ -36,52 +13,5 @@ module Files
def
repository
def
repository
project
.
repository
project
.
repository
end
end
def
after_commit
(
sha
,
branch
)
commit
=
repository
.
commit
(
sha
)
full_ref
=
"
#{
Gitlab
::
Git
::
BRANCH_REF_PREFIX
}#{
branch
}
"
old_sha
=
commit
.
parent_id
||
Gitlab
::
Git
::
BLANK_SHA
GitPushService
.
new
.
execute
(
project
,
current_user
,
old_sha
,
sha
,
full_ref
)
end
def
current_branch
@current_branch
||=
params
[
:current_branch
]
end
def
target_branch
@target_branch
||=
params
[
:target_branch
]
end
def
raise_error
(
message
)
raise
ValidationError
.
new
(
message
)
end
def
validate
allowed
=
::
Gitlab
::
GitAccess
.
new
(
current_user
,
project
).
can_push_to_branch?
(
@target_branch
)
unless
allowed
raise_error
(
"You are not allowed to push into this branch"
)
end
unless
project
.
empty_repo?
unless
repository
.
branch_names
.
include?
(
@current_branch
)
raise_error
(
"You can only create files if you are on top of a branch"
)
end
if
@current_branch
!=
@target_branch
if
repository
.
branch_names
.
include?
(
@target_branch
)
raise_error
(
"Branch with such name already exists. You need to switch to this branch in order to make changes"
)
end
end
end
end
def
create_target_branch
result
=
CreateBranchService
.
new
(
project
,
current_user
).
execute
(
@target_branch
,
@current_branch
)
unless
result
[
:status
]
==
:success
raise_error
(
"Something went wrong when we tried to create
#{
@target_branch
}
for you"
)
end
end
end
end
end
end
app/services/files/create_service.rb
View file @
35d3c6df
require_relative
"base_service"
require_relative
"base_service"
module
Files
module
Files
class
CreateService
<
Files
::
BaseService
class
CreateService
<
BaseService
def
commit
def
execute
repository
.
commit_file
(
current_user
,
@file_path
,
@file_content
,
@commit_message
,
@target_branch
)
allowed
=
Gitlab
::
GitAccess
.
new
(
current_user
,
project
).
can_push_to_branch?
(
ref
)
end
def
validate
unless
allowed
super
return
error
(
"You are not allowed to create file in this branch"
)
end
file_name
=
File
.
basename
(
@file_path
)
file_name
=
File
.
basename
(
path
)
file_path
=
path
unless
file_name
=~
Gitlab
::
Regex
.
file_name_regex
unless
file_name
=~
Gitlab
::
Regex
.
file_name_regex
r
aise_
error
(
r
eturn
error
(
'Your changes could not be committed, because the file name '
+
'Your changes could not be committed, because the file name '
+
Gitlab
::
Regex
.
file_name_regex_message
Gitlab
::
Regex
.
file_name_regex_message
)
)
end
end
unless
project
.
empty_repo?
if
project
.
empty_repo?
blob
=
repository
.
blob_at_branch
(
@current_branch
,
@file_path
)
# everything is ok because repo does not have a commits yet
else
unless
repository
.
branch_names
.
include?
(
ref
)
return
error
(
"You can only create files if you are on top of a branch"
)
end
blob
=
repository
.
blob_at_branch
(
ref
,
file_path
)
if
blob
if
blob
r
aise_
error
(
"Your changes could not be committed, because file with such name exists"
)
r
eturn
error
(
"Your changes could not be committed, because file with such name exists"
)
end
end
end
end
new_file_action
=
Gitlab
::
Satellite
::
NewFileAction
.
new
(
current_user
,
project
,
ref
,
file_path
)
created_successfully
=
new_file_action
.
commit!
(
params
[
:content
],
params
[
:commit_message
],
params
[
:encoding
],
params
[
:new_branch
]
)
if
created_successfully
success
else
error
(
"Your changes could not be committed, because the file has been changed"
)
end
end
end
end
end
end
end
app/services/files/delete_service.rb
View file @
35d3c6df
require_relative
"base_service"
require_relative
"base_service"
module
Files
module
Files
class
DeleteService
<
Files
::
BaseService
class
DeleteService
<
BaseService
def
commit
def
execute
repository
.
remove_file
(
current_user
,
@file_path
,
@commit_message
,
@target_branch
)
allowed
=
::
Gitlab
::
GitAccess
.
new
(
current_user
,
project
).
can_push_to_branch?
(
ref
)
unless
allowed
return
error
(
"You are not allowed to push into this branch"
)
end
unless
repository
.
branch_names
.
include?
(
ref
)
return
error
(
"You can only create files if you are on top of a branch"
)
end
blob
=
repository
.
blob_at_branch
(
ref
,
path
)
unless
blob
return
error
(
"You can only edit text files"
)
end
delete_file_action
=
Gitlab
::
Satellite
::
DeleteFileAction
.
new
(
current_user
,
project
,
ref
,
path
)
deleted_successfully
=
delete_file_action
.
commit!
(
nil
,
params
[
:commit_message
]
)
if
deleted_successfully
success
else
error
(
"Your changes could not be committed, because the file has been changed"
)
end
end
end
end
end
end
end
app/services/files/update_service.rb
View file @
35d3c6df
require_relative
"base_service"
require_relative
"base_service"
module
Files
module
Files
class
UpdateService
<
Files
::
BaseService
class
UpdateService
<
BaseService
def
commit
def
execute
repository
.
commit_file
(
current_user
,
@file_path
,
@file_content
,
@commit_message
,
@target_branch
)
allowed
=
::
Gitlab
::
GitAccess
.
new
(
current_user
,
project
).
can_push_to_branch?
(
ref
)
unless
allowed
return
error
(
"You are not allowed to push into this branch"
)
end
unless
repository
.
branch_names
.
include?
(
ref
)
return
error
(
"You can only create files if you are on top of a branch"
)
end
blob
=
repository
.
blob_at_branch
(
ref
,
path
)
unless
blob
return
error
(
"You can only edit text files"
)
end
edit_file_action
=
Gitlab
::
Satellite
::
EditFileAction
.
new
(
current_user
,
project
,
ref
,
path
)
edit_file_action
.
commit!
(
params
[
:content
],
params
[
:commit_message
],
params
[
:encoding
],
params
[
:new_branch
]
)
success
rescue
Gitlab
::
Satellite
::
CheckoutFailed
=>
ex
error
(
"Your changes could not be committed because ref '
#{
ref
}
' could not be checked out"
,
400
)
rescue
Gitlab
::
Satellite
::
CommitFailed
=>
ex
error
(
"Your changes could not be committed. Maybe there was nothing to commit?"
,
409
)
rescue
Gitlab
::
Satellite
::
PushFailed
=>
ex
error
(
"Your changes could not be committed. Maybe the file was changed by another process?"
,
409
)
end
end
end
end
end
end
app/services/git_push_service.rb
View file @
35d3c6df
...
@@ -133,8 +133,7 @@ class GitPushService
...
@@ -133,8 +133,7 @@ class GitPushService
end
end
def
is_default_branch?
(
ref
)
def
is_default_branch?
(
ref
)
Gitlab
::
Git
.
branch_ref?
(
ref
)
&&
Gitlab
::
Git
.
branch_ref?
(
ref
)
&&
Gitlab
::
Git
.
ref_name
(
ref
)
==
project
.
default_branch
(
Gitlab
::
Git
.
ref_name
(
ref
)
==
project
.
default_branch
||
project
.
default_branch
.
nil?
)
end
end
def
commit_user
(
commit
)
def
commit_user
(
commit
)
...
...
app/services/merge_requests/auto_merge_service.rb
View file @
35d3c6df
...
@@ -5,20 +5,17 @@ module MergeRequests
...
@@ -5,20 +5,17 @@ module MergeRequests
# mark merge request as merged and execute all hooks and notifications
# mark merge request as merged and execute all hooks and notifications
# Called when you do merge via GitLab UI
# Called when you do merge via GitLab UI
class
AutoMergeService
<
BaseMergeService
class
AutoMergeService
<
BaseMergeService
attr_reader
:merge_request
,
:commit_message
def
execute
(
merge_request
,
commit_message
)
def
execute
(
merge_request
,
commit_message
)
@commit_message
=
commit_message
@merge_request
=
merge_request
merge_request
.
lock_mr
merge_request
.
lock_mr
if
merge!
if
Gitlab
::
Satellite
::
MergeAction
.
new
(
current_user
,
merge_request
).
merge!
(
commit_message
)
merge_request
.
merge
merge_request
.
merge
create_merge_event
(
merge_request
,
current_user
)
create_merge_event
(
merge_request
,
current_user
)
create_note
(
merge_request
)
create_note
(
merge_request
)
notification_service
.
merge_mr
(
merge_request
,
current_user
)
notification_service
.
merge_mr
(
merge_request
,
current_user
)
execute_hooks
(
merge_request
,
'merge'
)
execute_hooks
(
merge_request
,
'merge'
)
true
true
else
else
merge_request
.
unlock_mr
merge_request
.
unlock_mr
...
@@ -29,47 +26,5 @@ module MergeRequests
...
@@ -29,47 +26,5 @@ module MergeRequests
merge_request
.
mark_as_unmergeable
merge_request
.
mark_as_unmergeable
false
false
end
end
def
merge!
if
merge_request
.
for_fork?
Gitlab
::
Satellite
::
MergeAction
.
new
(
current_user
,
merge_request
).
merge!
(
commit_message
)
else
# Merge local branches using rugged instead of satellites
if
sha
=
commit
after_commit
(
sha
,
merge_request
.
target_branch
)
if
merge_request
.
remove_source_branch?
DeleteBranchService
.
new
(
merge_request
.
source_project
,
current_user
).
execute
(
merge_request
.
source_branch
)
end
true
else
false
end
end
end
def
commit
committer
=
repository
.
user_to_comitter
(
current_user
)
options
=
{
message:
commit_message
,
author:
committer
,
committer:
committer
}
repository
.
merge
(
merge_request
.
source_branch
,
merge_request
.
target_branch
,
options
)
end
def
after_commit
(
sha
,
branch
)
commit
=
repository
.
commit
(
sha
)
full_ref
=
"
#{
Gitlab
::
Git
::
BRANCH_REF_PREFIX
}#{
branch
}
"
old_sha
=
commit
.
parent_id
||
Gitlab
::
Git
::
BLANK_SHA
GitPushService
.
new
.
execute
(
project
,
current_user
,
old_sha
,
sha
,
full_ref
)
end
def
repository
project
.
repository
end
end
end
end
end
app/views/projects/blob/_editor.html.haml
View file @
35d3c6df
...
@@ -12,8 +12,8 @@
...
@@ -12,8 +12,8 @@
\/
\/
=
text_field_tag
'file_name'
,
params
[
:file_name
],
placeholder:
"File name"
,
=
text_field_tag
'file_name'
,
params
[
:file_name
],
placeholder:
"File name"
,
required:
true
,
class:
'form-control new-file-name'
required:
true
,
class:
'form-control new-file-name'
.pull-right
.pull-right
=
select_tag
:encoding
,
options_for_select
([
"base64"
,
"text"
],
"text"
),
class:
'form-control'
=
select_tag
:encoding
,
options_for_select
([
"base64"
,
"text"
],
"text"
),
class:
'form-control'
.file-content.code
.file-content.code
%pre
.js-edit-mode-pane
#editor
%pre
.js-edit-mode-pane
#editor
...
...
app/views/projects/blob/new.html.haml
View file @
35d3c6df
...
@@ -6,12 +6,11 @@
...
@@ -6,12 +6,11 @@
=
render
'shared/commit_message_container'
,
params:
params
,
=
render
'shared/commit_message_container'
,
params:
params
,
placeholder:
'Add new file'
placeholder:
'Add new file'
-
unless
@project
.
empty_repo?
.form-group.branch
.form-group.branch
=
label_tag
'branch'
,
class:
'control-label'
do
=
label_tag
'branch'
,
class:
'control-label'
do
Branch
Branch
.col-sm-10
.col-sm-10
=
text_field_tag
'new_branch'
,
@ref
,
class:
"form-control"
=
text_field_tag
'new_branch'
,
@ref
,
class:
"form-control"
=
hidden_field_tag
'content'
,
''
,
id:
'file-content'
=
hidden_field_tag
'content'
,
''
,
id:
'file-content'
=
render
'projects/commit_button'
,
ref:
@ref
,
=
render
'projects/commit_button'
,
ref:
@ref
,
...
...
lib/api/files.rb
View file @
35d3c6df
...
@@ -3,26 +3,6 @@ module API
...
@@ -3,26 +3,6 @@ module API
class
Files
<
Grape
::
API
class
Files
<
Grape
::
API
before
{
authenticate!
}
before
{
authenticate!
}
helpers
do
def
commit_params
(
attrs
)
{
file_path:
attrs
[
:file_path
],
current_branch:
attrs
[
:branch_name
],
target_branch:
attrs
[
:branch_name
],
commit_message:
attrs
[
:commit_message
],
file_content:
attrs
[
:content
],
file_content_encoding:
attrs
[
:encoding
]
}
end
def
commit_response
(
attrs
)
{
file_path:
attrs
[
:file_path
],
branch_name:
attrs
[
:branch_name
],
}
end
end
resource
:projects
do
resource
:projects
do
# Get file from repository
# Get file from repository
# File content is Base64 encoded
# File content is Base64 encoded
...
@@ -93,11 +73,17 @@ module API
...
@@ -93,11 +73,17 @@ module API
required_attributes!
[
:file_path
,
:branch_name
,
:content
,
:commit_message
]
required_attributes!
[
:file_path
,
:branch_name
,
:content
,
:commit_message
]
attrs
=
attributes_for_keys
[
:file_path
,
:branch_name
,
:content
,
:commit_message
,
:encoding
]
attrs
=
attributes_for_keys
[
:file_path
,
:branch_name
,
:content
,
:commit_message
,
:encoding
]
result
=
::
Files
::
CreateService
.
new
(
user_project
,
current_user
,
commit_params
(
attrs
)).
execute
branch_name
=
attrs
.
delete
(
:branch_name
)
file_path
=
attrs
.
delete
(
:file_path
)
result
=
::
Files
::
CreateService
.
new
(
user_project
,
current_user
,
attrs
,
branch_name
,
file_path
).
execute
if
result
[
:status
]
==
:success
if
result
[
:status
]
==
:success
status
(
201
)
status
(
201
)
commit_response
(
attrs
)
{
file_path:
file_path
,
branch_name:
branch_name
}
else
else
render_api_error!
(
result
[
:message
],
400
)
render_api_error!
(
result
[
:message
],
400
)
end
end
...
@@ -119,11 +105,17 @@ module API
...
@@ -119,11 +105,17 @@ module API
required_attributes!
[
:file_path
,
:branch_name
,
:content
,
:commit_message
]
required_attributes!
[
:file_path
,
:branch_name
,
:content
,
:commit_message
]
attrs
=
attributes_for_keys
[
:file_path
,
:branch_name
,
:content
,
:commit_message
,
:encoding
]
attrs
=
attributes_for_keys
[
:file_path
,
:branch_name
,
:content
,
:commit_message
,
:encoding
]
result
=
::
Files
::
UpdateService
.
new
(
user_project
,
current_user
,
commit_params
(
attrs
)).
execute
branch_name
=
attrs
.
delete
(
:branch_name
)
file_path
=
attrs
.
delete
(
:file_path
)
result
=
::
Files
::
UpdateService
.
new
(
user_project
,
current_user
,
attrs
,
branch_name
,
file_path
).
execute
if
result
[
:status
]
==
:success
if
result
[
:status
]
==
:success
status
(
200
)
status
(
200
)
commit_response
(
attrs
)
{
file_path:
file_path
,
branch_name:
branch_name
}
else
else
http_status
=
result
[
:http_status
]
||
400
http_status
=
result
[
:http_status
]
||
400
render_api_error!
(
result
[
:message
],
http_status
)
render_api_error!
(
result
[
:message
],
http_status
)
...
@@ -146,11 +138,17 @@ module API
...
@@ -146,11 +138,17 @@ module API
required_attributes!
[
:file_path
,
:branch_name
,
:commit_message
]
required_attributes!
[
:file_path
,
:branch_name
,
:commit_message
]
attrs
=
attributes_for_keys
[
:file_path
,
:branch_name
,
:commit_message
]
attrs
=
attributes_for_keys
[
:file_path
,
:branch_name
,
:commit_message
]
result
=
::
Files
::
DeleteService
.
new
(
user_project
,
current_user
,
commit_params
(
attrs
)).
execute
branch_name
=
attrs
.
delete
(
:branch_name
)
file_path
=
attrs
.
delete
(
:file_path
)
result
=
::
Files
::
DeleteService
.
new
(
user_project
,
current_user
,
attrs
,
branch_name
,
file_path
).
execute
if
result
[
:status
]
==
:success
if
result
[
:status
]
==
:success
status
(
200
)
status
(
200
)
commit_response
(
attrs
)
{
file_path:
file_path
,
branch_name:
branch_name
}
else
else
render_api_error!
(
result
[
:message
],
400
)
render_api_error!
(
result
[
:message
],
400
)
end
end
...
...
lib/gitlab/satellite/files/delete_file_action.rb
0 → 100644
View file @
35d3c6df
require_relative
'file_action'
module
Gitlab
module
Satellite
class
DeleteFileAction
<
FileAction
# Deletes file and creates a new commit for it
#
# Returns false if committing the change fails
# Returns false if pushing from the satellite to bare repo failed or was rejected
# Returns true otherwise
def
commit!
(
content
,
commit_message
)
in_locked_and_timed_satellite
do
|
repo
|
prepare_satellite!
(
repo
)
# create target branch in satellite at the corresponding commit from bare repo
repo
.
git
.
checkout
({
raise:
true
,
timeout:
true
,
b:
true
},
ref
,
"origin/
#{
ref
}
"
)
# update the file in the satellite's working dir
file_path_in_satellite
=
File
.
join
(
repo
.
working_dir
,
file_path
)
# Prevent relative links
unless
safe_path?
(
file_path_in_satellite
)
Gitlab
::
GitLogger
.
error
(
"FileAction: Relative path not allowed"
)
return
false
end
File
.
delete
(
file_path_in_satellite
)
# add removed file
repo
.
remove
(
file_path_in_satellite
)
# commit the changes
# will raise CommandFailed when commit fails
repo
.
git
.
commit
(
raise:
true
,
timeout:
true
,
a:
true
,
m:
commit_message
)
# push commit back to bare repo
# will raise CommandFailed when push fails
repo
.
git
.
push
({
raise:
true
,
timeout:
true
},
:origin
,
ref
)
# everything worked
true
end
rescue
Grit
::
Git
::
CommandFailed
=>
ex
Gitlab
::
GitLogger
.
error
(
ex
.
message
)
false
end
end
end
end
lib/gitlab/satellite/files/edit_file_action.rb
0 → 100644
View file @
35d3c6df
require_relative
'file_action'
module
Gitlab
module
Satellite
# GitLab server-side file update and commit
class
EditFileAction
<
FileAction
# Updates the files content and creates a new commit for it
#
# Returns false if the ref has been updated while editing the file
# Returns false if committing the change fails
# Returns false if pushing from the satellite to bare repo failed or was rejected
# Returns true otherwise
def
commit!
(
content
,
commit_message
,
encoding
,
new_branch
=
nil
)
in_locked_and_timed_satellite
do
|
repo
|
prepare_satellite!
(
repo
)
# create target branch in satellite at the corresponding commit from bare repo
begin
repo
.
git
.
checkout
({
raise:
true
,
timeout:
true
,
b:
true
},
ref
,
"origin/
#{
ref
}
"
)
rescue
Grit
::
Git
::
CommandFailed
=>
ex
log_and_raise
(
CheckoutFailed
,
ex
.
message
)
end
# update the file in the satellite's working dir
file_path_in_satellite
=
File
.
join
(
repo
.
working_dir
,
file_path
)
# Prevent relative links
unless
safe_path?
(
file_path_in_satellite
)
Gitlab
::
GitLogger
.
error
(
"FileAction: Relative path not allowed"
)
return
false
end
# Write file
write_file
(
file_path_in_satellite
,
content
,
encoding
)
# commit the changes
# will raise CommandFailed when commit fails
begin
repo
.
git
.
commit
(
raise:
true
,
timeout:
true
,
a:
true
,
m:
commit_message
)
rescue
Grit
::
Git
::
CommandFailed
=>
ex
log_and_raise
(
CommitFailed
,
ex
.
message
)
end
target_branch
=
new_branch
.
present?
?
"
#{
ref
}
:
#{
new_branch
}
"
:
ref
# push commit back to bare repo
# will raise CommandFailed when push fails
begin
repo
.
git
.
push
({
raise:
true
,
timeout:
true
},
:origin
,
target_branch
)
rescue
Grit
::
Git
::
CommandFailed
=>
ex
log_and_raise
(
PushFailed
,
ex
.
message
)
end
# everything worked
true
end
end
private
def
log_and_raise
(
errorClass
,
message
)
Gitlab
::
GitLogger
.
error
(
message
)
raise
(
errorClass
,
message
)
end
end
end
end
lib/gitlab/satellite/files/file_action.rb
0 → 100644
View file @
35d3c6df
module
Gitlab
module
Satellite
class
FileAction
<
Action
attr_accessor
:file_path
,
:ref
def
initialize
(
user
,
project
,
ref
,
file_path
)
super
user
,
project
@file_path
=
file_path
@ref
=
ref
end
def
safe_path?
(
path
)
File
.
absolute_path
(
path
)
==
path
end
def
write_file
(
abs_file_path
,
content
,
file_encoding
=
'text'
)
if
file_encoding
==
'base64'
File
.
open
(
abs_file_path
,
'wb'
)
{
|
f
|
f
.
write
(
Base64
.
decode64
(
content
))
}
else
File
.
open
(
abs_file_path
,
'w'
)
{
|
f
|
f
.
write
(
content
)
}
end
end
end
end
end
lib/gitlab/satellite/files/new_file_action.rb
0 → 100644
View file @
35d3c6df
require_relative
'file_action'
module
Gitlab
module
Satellite
class
NewFileAction
<
FileAction
# Updates the files content and creates a new commit for it
#
# Returns false if the ref has been updated while editing the file
# Returns false if committing the change fails
# Returns false if pushing from the satellite to bare repo failed or was rejected
# Returns true otherwise
def
commit!
(
content
,
commit_message
,
encoding
,
new_branch
=
nil
)
in_locked_and_timed_satellite
do
|
repo
|
prepare_satellite!
(
repo
)
# create target branch in satellite at the corresponding commit from bare repo
current_ref
=
if
@project
.
empty_repo?
# skip this step if we want to add first file to empty repo
Satellite
::
PARKING_BRANCH
else
repo
.
git
.
checkout
({
raise:
true
,
timeout:
true
,
b:
true
},
ref
,
"origin/
#{
ref
}
"
)
ref
end
file_path_in_satellite
=
File
.
join
(
repo
.
working_dir
,
file_path
)
dir_name_in_satellite
=
File
.
dirname
(
file_path_in_satellite
)
# Prevent relative links
unless
safe_path?
(
file_path_in_satellite
)
Gitlab
::
GitLogger
.
error
(
"FileAction: Relative path not allowed"
)
return
false
end
# Create dir if not exists
FileUtils
.
mkdir_p
(
dir_name_in_satellite
)
# Write file
write_file
(
file_path_in_satellite
,
content
,
encoding
)
# add new file
repo
.
add
(
file_path_in_satellite
)
# commit the changes
# will raise CommandFailed when commit fails
repo
.
git
.
commit
(
raise:
true
,
timeout:
true
,
a:
true
,
m:
commit_message
)
target_branch
=
if
new_branch
.
present?
&&
!
@project
.
empty_repo?
"
#{
ref
}
:
#{
new_branch
}
"
else
"
#{
current_ref
}
:
#{
ref
}
"
end
# push commit back to bare repo
# will raise CommandFailed when push fails
repo
.
git
.
push
({
raise:
true
,
timeout:
true
},
:origin
,
target_branch
)
# everything worked
true
end
rescue
Grit
::
Git
::
CommandFailed
=>
ex
Gitlab
::
GitLogger
.
error
(
ex
.
message
)
false
end
end
end
end
spec/models/repository_spec.rb
View file @
35d3c6df
...
@@ -34,20 +34,6 @@ describe Repository do
...
@@ -34,20 +34,6 @@ describe Repository do
end
end
end
end
describe
:can_be_merged?
do
context
'mergeable branches'
do
subject
{
repository
.
can_be_merged?
(
'feature'
,
'master'
)
}
it
{
is_expected
.
to
be_truthy
}
end
context
'non-mergeable branches'
do
subject
{
repository
.
can_be_merged?
(
'feature_conflict'
,
'feature'
)
}
it
{
is_expected
.
to
be_falsey
}
end
end
describe
"search_files"
do
describe
"search_files"
do
let
(
:results
)
{
repository
.
search_files
(
'feature'
,
'master'
)
}
let
(
:results
)
{
repository
.
search_files
(
'feature'
,
'master'
)
}
subject
{
results
}
subject
{
results
}
...
...
spec/requests/api/files_spec.rb
View file @
35d3c6df
...
@@ -49,6 +49,8 @@ describe API::API, api: true do
...
@@ -49,6 +49,8 @@ describe API::API, api: true do
end
end
it
"should create a new file in project repo"
do
it
"should create a new file in project repo"
do
expect_any_instance_of
(
Gitlab
::
Satellite
::
NewFileAction
).
to
receive
(
:commit!
).
and_return
(
true
)
post
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
post
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
expect
(
response
.
status
).
to
eq
(
201
)
expect
(
response
.
status
).
to
eq
(
201
)
expect
(
json_response
[
'file_path'
]).
to
eq
(
'newfile.rb'
)
expect
(
json_response
[
'file_path'
]).
to
eq
(
'newfile.rb'
)
...
@@ -59,9 +61,8 @@ describe API::API, api: true do
...
@@ -59,9 +61,8 @@ describe API::API, api: true do
expect
(
response
.
status
).
to
eq
(
400
)
expect
(
response
.
status
).
to
eq
(
400
)
end
end
it
"should return a 400 if editor fails to create file"
do
it
"should return a 400 if satellite fails to create file"
do
allow_any_instance_of
(
Repository
).
to
receive
(
:commit_file
).
expect_any_instance_of
(
Gitlab
::
Satellite
::
NewFileAction
).
to
receive
(
:commit!
).
and_return
(
false
)
and_return
(
false
)
post
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
post
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
expect
(
response
.
status
).
to
eq
(
400
)
expect
(
response
.
status
).
to
eq
(
400
)
...
@@ -79,6 +80,8 @@ describe API::API, api: true do
...
@@ -79,6 +80,8 @@ describe API::API, api: true do
end
end
it
"should update existing file in project repo"
do
it
"should update existing file in project repo"
do
expect_any_instance_of
(
Gitlab
::
Satellite
::
EditFileAction
).
to
receive
(
:commit!
).
and_return
(
true
)
put
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
put
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
json_response
[
'file_path'
]).
to
eq
(
file_path
)
expect
(
json_response
[
'file_path'
]).
to
eq
(
file_path
)
...
@@ -88,6 +91,32 @@ describe API::API, api: true do
...
@@ -88,6 +91,32 @@ describe API::API, api: true do
put
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
)
put
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
)
expect
(
response
.
status
).
to
eq
(
400
)
expect
(
response
.
status
).
to
eq
(
400
)
end
end
it
'should return a 400 if the checkout fails'
do
expect_any_instance_of
(
Gitlab
::
Satellite
::
EditFileAction
).
to
receive
(
:commit!
).
and_raise
(
Gitlab
::
Satellite
::
CheckoutFailed
)
put
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
expect
(
response
.
status
).
to
eq
(
400
)
ref
=
valid_params
[
:branch_name
]
expect
(
response
.
body
).
to
match
(
"ref '
#{
ref
}
' could not be checked out"
)
end
it
'should return a 409 if the file was not modified'
do
expect_any_instance_of
(
Gitlab
::
Satellite
::
EditFileAction
).
to
receive
(
:commit!
).
and_raise
(
Gitlab
::
Satellite
::
CommitFailed
)
put
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
expect
(
response
.
status
).
to
eq
(
409
)
expect
(
response
.
body
).
to
match
(
"Maybe there was nothing to commit?"
)
end
it
'should return a 409 if the push fails'
do
expect_any_instance_of
(
Gitlab
::
Satellite
::
EditFileAction
).
to
receive
(
:commit!
).
and_raise
(
Gitlab
::
Satellite
::
PushFailed
)
put
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
expect
(
response
.
status
).
to
eq
(
409
)
expect
(
response
.
body
).
to
match
(
"Maybe the file was changed by another process?"
)
end
end
end
describe
"DELETE /projects/:id/repository/files"
do
describe
"DELETE /projects/:id/repository/files"
do
...
@@ -100,6 +129,7 @@ describe API::API, api: true do
...
@@ -100,6 +129,7 @@ describe API::API, api: true do
end
end
it
"should delete existing file in project repo"
do
it
"should delete existing file in project repo"
do
expect_any_instance_of
(
Gitlab
::
Satellite
::
DeleteFileAction
).
to
receive
(
:commit!
).
and_return
(
true
)
delete
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
delete
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
json_response
[
'file_path'
]).
to
eq
(
file_path
)
expect
(
json_response
[
'file_path'
]).
to
eq
(
file_path
)
...
@@ -111,7 +141,7 @@ describe API::API, api: true do
...
@@ -111,7 +141,7 @@ describe API::API, api: true do
end
end
it
"should return a 400 if satellite fails to create file"
do
it
"should return a 400 if satellite fails to create file"
do
allow_any_instance_of
(
Repository
).
to
receive
(
:remove_file
).
and_return
(
false
)
expect_any_instance_of
(
Gitlab
::
Satellite
::
DeleteFileAction
).
to
receive
(
:commit!
).
and_return
(
false
)
delete
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
delete
api
(
"/projects/
#{
project
.
id
}
/repository/files"
,
user
),
valid_params
expect
(
response
.
status
).
to
eq
(
400
)
expect
(
response
.
status
).
to
eq
(
400
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment