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
9f9ef5be
Commit
9f9ef5be
authored
Feb 13, 2017
by
Douwe Maan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Consistently create, update, and delete files, taking CRLF settings into account
parent
6cbf3079
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
376 additions
and
606 deletions
+376
-606
app/models/repository.rb
app/models/repository.rb
+28
-100
app/services/files/multi_service.rb
app/services/files/multi_service.rb
+11
-3
db/fixtures/development/17_cycle_analytics.rb
db/fixtures/development/17_cycle_analytics.rb
+1
-9
lib/api/commits.rb
lib/api/commits.rb
+0
-7
lib/gitlab/git/blob.rb
lib/gitlab/git/blob.rb
+0
-157
lib/gitlab/git/index.rb
lib/gitlab/git/index.rb
+124
-0
lib/gitlab/git/repository.rb
lib/gitlab/git/repository.rb
+0
-51
spec/lib/gitlab/git/blob_spec.rb
spec/lib/gitlab/git/blob_spec.rb
+0
-185
spec/lib/gitlab/git/index_spec.rb
spec/lib/gitlab/git/index_spec.rb
+210
-0
spec/lib/gitlab/git/repository_spec.rb
spec/lib/gitlab/git/repository_spec.rb
+0
-75
spec/models/repository_spec.rb
spec/models/repository_spec.rb
+1
-1
spec/requests/api/commits_spec.rb
spec/requests/api/commits_spec.rb
+0
-10
spec/support/cycle_analytics_helpers.rb
spec/support/cycle_analytics_helpers.rb
+1
-8
No files found.
app/models/repository.rb
View file @
9f9ef5be
...
...
@@ -768,24 +768,28 @@ class Repository
message
:,
branch_name
:,
author_email:
nil
,
author_name:
nil
,
start_branch_name:
nil
,
start_project:
project
)
check_tree_entry_for_dir
(
branch_name
,
path
)
if
start_branch_name
start_project
.
repository
.
check_tree_entry_for_dir
(
start_branch_name
,
path
)
entry
=
tree_entry_at
(
start_branch_name
||
branch_name
,
path
)
if
entry
if
entry
[
:type
]
==
:blob
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
"Directory already exists as a file"
)
else
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
"Directory already exists"
)
end
end
commit_file
(
user
,
"
#{
path
}
/.gitkeep"
,
''
,
multi_action
(
user:
user
,
message:
message
,
branch_name:
branch_name
,
update:
false
,
author_email:
author_email
,
author_name:
author_name
,
start_branch_name:
start_branch_name
,
start_project:
start_project
)
start_project:
start_project
,
actions:
[{
action: :create_dir
,
file_path:
path
}])
end
# rubocop:enable Metrics/ParameterLists
...
...
@@ -795,18 +799,8 @@ class Repository
message
:,
branch_name
:,
update:
true
,
author_email:
nil
,
author_name:
nil
,
start_branch_name:
nil
,
start_project:
project
)
unless
update
error_message
=
"Filename already exists; update not allowed"
if
tree_entry_at
(
branch_name
,
path
)
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
error_message
)
end
if
start_branch_name
&&
start_project
.
repository
.
tree_entry_at
(
start_branch_name
,
path
)
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
error_message
)
end
end
action
=
update
?
:update
:
:create
multi_action
(
user:
user
,
...
...
@@ -816,7 +810,7 @@ class Repository
author_name:
author_name
,
start_branch_name:
start_branch_name
,
start_project:
start_project
,
actions:
[{
action:
:create
,
actions:
[{
action:
action
,
file_path:
path
,
content:
content
}])
end
...
...
@@ -855,6 +849,7 @@ class Repository
message
:,
branch_name
:,
author_email:
nil
,
author_name:
nil
,
start_branch_name:
nil
,
start_project:
project
)
multi_action
(
user:
user
,
message:
message
,
...
...
@@ -877,21 +872,22 @@ class Repository
branch_name
,
start_branch_name:
start_branch_name
,
start_project:
start_project
)
do
|
start_commit
|
index
=
rugged
.
index
parents
=
if
start_commit
index
.
read_tree
(
start_commit
.
raw_commit
.
tree
)
[
start_commit
.
sha
]
else
[]
end
index
=
Gitlab
::
Git
::
Index
.
new
(
raw_repository
)
actions
.
each
do
|
act
|
git_action
(
index
,
act
)
if
start_commit
index
.
read_tree
(
start_commit
.
raw_commit
.
tree
)
parents
=
[
start_commit
.
sha
]
else
parents
=
[]
end
actions
.
each
do
|
options
|
index
.
__send__
(
options
.
delete
(
:action
),
options
)
end
options
=
{
tree:
index
.
write_tree
(
rugged
)
,
tree:
index
.
write_tree
,
message:
message
,
parents:
parents
}
...
...
@@ -1263,22 +1259,6 @@ class Repository
raw_repository
.
send
(
:tree_entry
,
commit
(
branch_name
),
path
)
end
def
check_tree_entry_for_dir
(
branch_name
,
path
)
return
unless
branch_exists?
(
branch_name
)
entry
=
tree_entry_at
(
branch_name
,
path
)
return
unless
entry
if
entry
[
:type
]
==
:blob
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
"Directory already exists as a file"
)
else
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
"Directory already exists"
)
end
end
private
def
blob_data_at
(
sha
,
path
)
...
...
@@ -1289,58 +1269,6 @@ class Repository
blob
.
data
end
def
git_action
(
index
,
action
)
path
=
normalize_path
(
action
[
:file_path
])
if
action
[
:action
]
==
:move
previous_path
=
normalize_path
(
action
[
:previous_path
])
end
case
action
[
:action
]
when
:create
,
:update
,
:move
mode
=
case
action
[
:action
]
when
:update
index
.
get
(
path
)[
:mode
]
when
:move
index
.
get
(
previous_path
)[
:mode
]
end
mode
||=
0
o100644
index
.
remove
(
previous_path
)
if
action
[
:action
]
==
:move
content
=
if
action
[
:encoding
]
==
'base64'
Base64
.
decode64
(
action
[
:content
])
else
action
[
:content
]
end
detect
=
CharlockHolmes
::
EncodingDetector
.
new
.
detect
(
content
)
if
content
unless
detect
&&
detect
[
:type
]
==
:binary
# When writing to the repo directly as we are doing here,
# the `core.autocrlf` config isn't taken into account.
content
.
gsub!
(
"
\r\n
"
,
"
\n
"
)
if
self
.
autocrlf
end
oid
=
rugged
.
write
(
content
,
:blob
)
index
.
add
(
path:
path
,
oid:
oid
,
mode:
mode
)
when
:delete
index
.
remove
(
path
)
end
end
def
normalize_path
(
path
)
pathname
=
Gitlab
::
Git
::
PathHelper
.
normalize_path
(
path
)
if
pathname
.
each_filename
.
include?
(
'..'
)
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
'Invalid path'
)
end
pathname
.
to_s
end
def
refs_directory_exists?
return
false
unless
path_with_namespace
...
...
app/services/files/multi_service.rb
View file @
9f9ef5be
...
...
@@ -2,6 +2,8 @@ module Files
class
MultiService
<
Files
::
BaseService
class
FileChangedError
<
StandardError
;
end
ACTIONS
=
%w[create update delete move]
.
freeze
def
commit
repository
.
multi_action
(
user:
current_user
,
...
...
@@ -19,15 +21,23 @@ module Files
def
validate
super
params
[
:actions
].
each_with_index
do
|
action
,
index
|
unless
action
[
:file_path
].
present?
raise_error
(
"You must specify a file_path."
)
end
action
[
:file_path
].
slice!
(
0
)
if
action
[
:file_path
]
&&
action
[
:file_path
].
start_with?
(
'/'
)
action
[
:previous_path
].
slice!
(
0
)
if
action
[
:previous_path
]
&&
action
[
:previous_path
].
start_with?
(
'/'
)
regex_check
(
action
[
:file_path
])
regex_check
(
action
[
:previous_path
])
if
action
[
:previous_path
]
if
ACTIONS
.
include?
(
action
[
:action
].
to_s
)
action
[
:action
]
=
action
[
:action
].
to_sym
else
raise_error
(
"Unknown action type `
#{
action
[
:action
]
}
`."
)
end
if
project
.
empty_repo?
&&
action
[
:action
]
!=
:create
raise_error
(
"No files to
#{
action
[
:action
]
}
."
)
end
...
...
@@ -43,8 +53,6 @@ module Files
validate_delete
(
action
)
when
:move
validate_move
(
action
,
index
)
else
raise_error
(
"Unknown action type `
#{
action
[
:action
]
}
`."
)
end
end
end
...
...
db/fixtures/development/17_cycle_analytics.rb
View file @
9f9ef5be
...
...
@@ -155,17 +155,9 @@ class Gitlab::Seeder::CycleAnalytics
issue
.
project
.
repository
.
add_branch
(
@user
,
branch_name
,
'master'
)
options
=
{
committer:
issue
.
project
.
repository
.
user_to_committer
(
@user
),
author:
issue
.
project
.
repository
.
user_to_committer
(
@user
),
commit:
{
message:
"Commit for #
#{
issue
.
iid
}
"
,
branch:
branch_name
,
update_ref:
true
},
file:
{
content:
"content"
,
path:
filename
,
update:
false
}
}
commit_sha
=
Gitlab
::
Git
::
Blob
.
commit
(
issue
.
project
.
repository
,
options
)
commit_sha
=
issue
.
project
.
repository
.
commit_file
(
@user
,
filename
,
"content"
,
options
,
message:
"Commit for #
#{
issue
.
iid
}
"
,
branch_name:
branch_name
)
issue
.
project
.
repository
.
commit
(
commit_sha
)
GitPushService
.
new
(
issue
.
project
,
@user
,
oldrev:
issue
.
project
.
repository
.
commit
(
"master"
).
sha
,
...
...
lib/api/commits.rb
View file @
9f9ef5be
...
...
@@ -52,13 +52,6 @@ module API
attrs
=
declared_params
.
merge
(
start_branch:
declared_params
[
:branch
],
target_branch:
declared_params
[
:branch
])
attrs
[
:actions
].
map!
do
|
action
|
action
[
:action
]
=
action
[
:action
].
to_sym
action
[
:file_path
].
slice!
(
0
)
if
action
[
:file_path
]
&&
action
[
:file_path
].
start_with?
(
'/'
)
action
[
:previous_path
].
slice!
(
0
)
if
action
[
:previous_path
]
&&
action
[
:previous_path
].
start_with?
(
'/'
)
action
end
result
=
::
Files
::
MultiService
.
new
(
user_project
,
current_user
,
attrs
).
execute
if
result
[
:status
]
==
:success
...
...
lib/gitlab/git/blob.rb
View file @
9f9ef5be
...
...
@@ -93,163 +93,6 @@ module Gitlab
commit_id:
sha
,
)
end
# Commit file in repository and return commit sha
#
# options should contain next structure:
# file: {
# content: 'Lorem ipsum...',
# path: 'documents/story.txt',
# update: true
# },
# author: {
# email: 'user@example.com',
# name: 'Test User',
# time: Time.now
# },
# committer: {
# email: 'user@example.com',
# name: 'Test User',
# time: Time.now
# },
# commit: {
# message: 'Wow such commit',
# branch: 'master',
# update_ref: false
# }
#
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/PerceivedComplexity
def
commit
(
repository
,
options
,
action
=
:add
)
file
=
options
[
:file
]
update
=
file
[
:update
].
nil?
?
true
:
file
[
:update
]
author
=
options
[
:author
]
committer
=
options
[
:committer
]
commit
=
options
[
:commit
]
repo
=
repository
.
rugged
ref
=
commit
[
:branch
]
update_ref
=
commit
[
:update_ref
].
nil?
?
true
:
commit
[
:update_ref
]
parents
=
[]
mode
=
0
o100644
unless
ref
.
start_with?
(
'refs/'
)
ref
=
'refs/heads/'
+
ref
end
path_name
=
Gitlab
::
Git
::
PathHelper
.
normalize_path
(
file
[
:path
])
# Abort if any invalid characters remain (e.g. ../foo)
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
"Invalid path"
)
if
path_name
.
each_filename
.
to_a
.
include?
(
'..'
)
filename
=
path_name
.
to_s
index
=
repo
.
index
unless
repo
.
empty?
rugged_ref
=
repo
.
references
[
ref
]
raise
Gitlab
::
Git
::
Repository
::
InvalidRef
.
new
(
"Invalid branch name"
)
unless
rugged_ref
last_commit
=
rugged_ref
.
target
index
.
read_tree
(
last_commit
.
tree
)
parents
=
[
last_commit
]
end
if
action
==
:remove
index
.
remove
(
filename
)
else
file_entry
=
index
.
get
(
filename
)
if
action
==
:rename
old_path_name
=
Gitlab
::
Git
::
PathHelper
.
normalize_path
(
file
[
:previous_path
])
old_filename
=
old_path_name
.
to_s
file_entry
=
index
.
get
(
old_filename
)
index
.
remove
(
old_filename
)
unless
file_entry
.
blank?
end
if
file_entry
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
"Filename already exists; update not allowed"
)
unless
update
# Preserve the current file mode if one is available
mode
=
file_entry
[
:mode
]
if
file_entry
[
:mode
]
end
content
=
file
[
:content
]
detect
=
CharlockHolmes
::
EncodingDetector
.
new
.
detect
(
content
)
if
content
unless
detect
&&
detect
[
:type
]
==
:binary
# When writing to the repo directly as we are doing here,
# the `core.autocrlf` config isn't taken into account.
content
.
gsub!
(
"
\r\n
"
,
"
\n
"
)
if
repository
.
autocrlf
end
oid
=
repo
.
write
(
content
,
:blob
)
index
.
add
(
path:
filename
,
oid:
oid
,
mode:
mode
)
end
opts
=
{}
opts
[
:tree
]
=
index
.
write_tree
(
repo
)
opts
[
:author
]
=
author
opts
[
:committer
]
=
committer
opts
[
:message
]
=
commit
[
:message
]
opts
[
:parents
]
=
parents
opts
[
:update_ref
]
=
ref
if
update_ref
Rugged
::
Commit
.
create
(
repo
,
opts
)
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/PerceivedComplexity
# Remove file from repository and return commit sha
#
# options should contain next structure:
# file: {
# path: 'documents/story.txt'
# },
# author: {
# email: 'user@example.com',
# name: 'Test User',
# time: Time.now
# },
# committer: {
# email: 'user@example.com',
# name: 'Test User',
# time: Time.now
# },
# commit: {
# message: 'Remove FILENAME',
# branch: 'master'
# }
#
def
remove
(
repository
,
options
)
commit
(
repository
,
options
,
:remove
)
end
# Rename file from repository and return commit sha
#
# options should contain next structure:
# file: {
# previous_path: 'documents/old_story.txt'
# path: 'documents/story.txt'
# content: 'Lorem ipsum...',
# update: true
# },
# author: {
# email: 'user@example.com',
# name: 'Test User',
# time: Time.now
# },
# committer: {
# email: 'user@example.com',
# name: 'Test User',
# time: Time.now
# },
# commit: {
# message: 'Rename FILENAME',
# branch: 'master'
# }
#
def
rename
(
repository
,
options
)
commit
(
repository
,
options
,
:rename
)
end
end
def
initialize
(
options
)
...
...
lib/gitlab/git/index.rb
0 → 100644
View file @
9f9ef5be
module
Gitlab
module
Git
class
Index
DEFAULT_MODE
=
0
o100644
attr_reader
:repository
,
:raw_index
def
initialize
(
repository
)
@repository
=
repository
@raw_index
=
repository
.
rugged
.
index
end
def
read_tree
(
tree
)
raw_index
.
read_tree
(
tree
)
end
def
write_tree
raw_index
.
write_tree
(
repository
.
rugged
)
end
def
get
(
*
args
)
raw_index
.
get
(
*
args
)
end
def
create
(
options
)
normalize_options!
(
options
)
file_entry
=
raw_index
.
get
(
options
[
:file_path
])
if
file_entry
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
"Filename already exists"
)
end
add_blob
(
options
)
end
def
create_dir
(
options
)
normalize_options!
(
options
)
file_entry
=
raw_index
.
get
(
options
[
:file_path
])
if
file_entry
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
"Directory already exists as a file"
)
end
options
=
options
.
dup
options
[
:file_path
]
+=
'/.gitkeep'
options
[
:content
]
=
''
add_blob
(
options
)
end
def
update
(
options
)
normalize_options!
(
options
)
file_entry
=
raw_index
.
get
(
options
[
:file_path
])
unless
file_entry
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
"File doesn't exist"
)
end
add_blob
(
options
,
mode:
file_entry
[
:mode
])
end
def
move
(
options
)
normalize_options!
(
options
)
file_entry
=
raw_index
.
get
(
options
[
:previous_path
])
unless
file_entry
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
"File doesn't exist"
)
end
raw_index
.
remove
(
options
[
:previous_path
])
add_blob
(
options
,
mode:
file_entry
[
:mode
])
end
def
delete
(
options
)
normalize_options!
(
options
)
file_entry
=
raw_index
.
get
(
options
[
:file_path
])
unless
file_entry
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
"File doesn't exist"
)
end
raw_index
.
remove
(
options
[
:file_path
])
end
private
def
normalize_options!
(
options
)
options
[
:file_path
]
=
normalize_path
(
options
[
:file_path
])
if
options
[
:file_path
]
options
[
:previous_path
]
=
normalize_path
(
options
[
:previous_path
])
if
options
[
:previous_path
]
end
def
normalize_path
(
path
)
pathname
=
Gitlab
::
Git
::
PathHelper
.
normalize_path
(
path
)
if
pathname
.
each_filename
.
include?
(
'..'
)
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
'Invalid path'
)
end
pathname
.
to_s
end
def
add_blob
(
options
,
mode:
nil
)
content
=
options
[
:content
]
return
unless
content
content
=
Base64
.
decode64
(
content
)
if
options
[
:encoding
]
==
'base64'
detect
=
CharlockHolmes
::
EncodingDetector
.
new
.
detect
(
content
)
unless
detect
&&
detect
[
:type
]
==
:binary
# When writing to the repo directly as we are doing here,
# the `core.autocrlf` config isn't taken into account.
content
.
gsub!
(
"
\r\n
"
,
"
\n
"
)
if
repository
.
autocrlf
end
oid
=
repository
.
rugged
.
write
(
content
,
:blob
)
raw_index
.
add
(
path:
options
[
:file_path
],
oid:
oid
,
mode:
mode
||
DEFAULT_MODE
)
rescue
Rugged
::
IndexError
=>
e
raise
Gitlab
::
Git
::
Repository
::
InvalidBlobName
.
new
(
e
.
message
)
end
end
end
end
lib/gitlab/git/repository.rb
View file @
9f9ef5be
...
...
@@ -837,57 +837,6 @@ module Gitlab
rugged
.
config
[
'core.autocrlf'
]
=
AUTOCRLF_VALUES
.
invert
[
value
]
end
# Create a new directory with a .gitkeep file. Creates
# all required nested directories (i.e. mkdir -p behavior)
#
# options should contain next structure:
# author: {
# email: 'user@example.com',
# name: 'Test User',
# time: Time.now
# },
# committer: {
# email: 'user@example.com',
# name: 'Test User',
# time: Time.now
# },
# commit: {
# message: 'Wow such commit',
# branch: 'master',
# update_ref: false
# }
def
mkdir
(
path
,
options
=
{})
# Check if this directory exists; if it does, then don't bother
# adding .gitkeep file.
ref
=
options
[
:commit
][
:branch
]
path
=
Gitlab
::
Git
::
PathHelper
.
normalize_path
(
path
).
to_s
rugged_ref
=
rugged
.
ref
(
ref
)
raise
InvalidRef
.
new
(
"Invalid ref"
)
if
rugged_ref
.
nil?
target_commit
=
rugged_ref
.
target
raise
InvalidRef
.
new
(
"Invalid target commit"
)
if
target_commit
.
nil?
entry
=
tree_entry
(
target_commit
,
path
)
if
entry
if
entry
[
:type
]
==
:blob
raise
InvalidBlobName
.
new
(
"Directory already exists as a file"
)
else
raise
InvalidBlobName
.
new
(
"Directory already exists"
)
end
end
options
[
:file
]
=
{
content:
''
,
path:
"
#{
path
}
/.gitkeep"
,
update:
true
}
Gitlab
::
Git
::
Blob
.
commit
(
self
,
options
)
end
# Returns result like "git ls-files" , recursive and full file path
#
# Ex.
...
...
spec/lib/gitlab/git/blob_spec.rb
View file @
9f9ef5be
...
...
@@ -222,191 +222,6 @@ describe Gitlab::Git::Blob, seed_helper: true do
end
end
describe
:commit
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
TEST_REPO_PATH
)
}
let
(
:commit_options
)
do
{
file:
{
content:
'Lorem ipsum...'
,
path:
'documents/story.txt'
},
author:
{
email:
'user@example.com'
,
name:
'Test User'
,
time:
Time
.
now
},
committer:
{
email:
'user@example.com'
,
name:
'Test User'
,
time:
Time
.
now
},
commit:
{
message:
'Wow such commit'
,
branch:
'fix-mode'
}
}
end
let
(
:commit_sha
)
{
Gitlab
::
Git
::
Blob
.
commit
(
repository
,
commit_options
)
}
let
(
:commit
)
{
repository
.
lookup
(
commit_sha
)
}
it
'should add file with commit'
do
# Commit message valid
expect
(
commit
.
message
).
to
eq
(
'Wow such commit'
)
tree
=
commit
.
tree
.
to_a
.
find
{
|
tree
|
tree
[
:name
]
==
'documents'
}
# Directory was created
expect
(
tree
[
:type
]).
to
eq
(
:tree
)
# File was created
expect
(
repository
.
lookup
(
tree
[
:oid
]).
first
[
:name
]).
to
eq
(
'story.txt'
)
end
describe
"ref updating"
do
it
'creates a commit but does not udate a ref'
do
commit_opts
=
commit_options
.
tap
{
|
opts
|
opts
[
:commit
][
:update_ref
]
=
false
}
commit_sha
=
Gitlab
::
Git
::
Blob
.
commit
(
repository
,
commit_opts
)
commit
=
repository
.
lookup
(
commit_sha
)
# Commit message valid
expect
(
commit
.
message
).
to
eq
(
'Wow such commit'
)
# Does not update any related ref
expect
(
repository
.
lookup
(
"fix-mode"
).
oid
).
not_to
eq
(
commit
.
oid
)
expect
(
repository
.
lookup
(
"HEAD"
).
oid
).
not_to
eq
(
commit
.
oid
)
end
end
describe
'reject updates'
do
it
'should reject updates'
do
commit_options
[
:file
][
:update
]
=
false
commit_options
[
:file
][
:path
]
=
'files/executables/ls'
expect
{
commit_sha
}.
to
raise_error
(
'Filename already exists; update not allowed'
)
end
end
describe
'file modes'
do
it
'should preserve file modes with commit'
do
commit_options
[
:file
][
:path
]
=
'files/executables/ls'
entry
=
Gitlab
::
Git
::
Blob
.
find_entry_by_path
(
repository
,
commit
.
tree
.
oid
,
commit_options
[
:file
][
:path
])
expect
(
entry
[
:filemode
]).
to
eq
(
0100755
)
end
end
end
describe
:rename
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
TEST_NORMAL_REPO_PATH
)
}
let
(
:rename_options
)
do
{
file:
{
path:
'NEWCONTRIBUTING.md'
,
previous_path:
'CONTRIBUTING.md'
,
content:
'Lorem ipsum...'
,
update:
true
},
author:
{
email:
'user@example.com'
,
name:
'Test User'
,
time:
Time
.
now
},
committer:
{
email:
'user@example.com'
,
name:
'Test User'
,
time:
Time
.
now
},
commit:
{
message:
'Rename readme'
,
branch:
'master'
}
}
end
let
(
:rename_options2
)
do
{
file:
{
content:
'Lorem ipsum...'
,
path:
'bin/new_executable'
,
previous_path:
'bin/executable'
,
},
author:
{
email:
'user@example.com'
,
name:
'Test User'
,
time:
Time
.
now
},
committer:
{
email:
'user@example.com'
,
name:
'Test User'
,
time:
Time
.
now
},
commit:
{
message:
'Updates toberenamed.txt'
,
branch:
'master'
,
update_ref:
false
}
}
end
it
'maintains file permissions when renaming'
do
mode
=
0
o100755
Gitlab
::
Git
::
Blob
.
rename
(
repository
,
rename_options2
)
expect
(
repository
.
rugged
.
index
.
get
(
rename_options2
[
:file
][
:path
])[
:mode
]).
to
eq
(
mode
)
end
it
'renames the file with commit and not change file permissions'
do
ref
=
rename_options
[
:commit
][
:branch
]
expect
(
repository
.
rugged
.
index
.
get
(
'CONTRIBUTING.md'
)).
not_to
be_nil
expect
{
Gitlab
::
Git
::
Blob
.
rename
(
repository
,
rename_options
)
}.
to
change
{
repository
.
commit_count
(
ref
)
}.
by
(
1
)
expect
(
repository
.
rugged
.
index
.
get
(
'CONTRIBUTING.md'
)).
to
be_nil
expect
(
repository
.
rugged
.
index
.
get
(
'NEWCONTRIBUTING.md'
)).
not_to
be_nil
end
end
describe
:remove
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
TEST_REPO_PATH
)
}
let
(
:commit_options
)
do
{
file:
{
path:
'README.md'
},
author:
{
email:
'user@example.com'
,
name:
'Test User'
,
time:
Time
.
now
},
committer:
{
email:
'user@example.com'
,
name:
'Test User'
,
time:
Time
.
now
},
commit:
{
message:
'Remove readme'
,
branch:
'feature'
}
}
end
let
(
:commit_sha
)
{
Gitlab
::
Git
::
Blob
.
remove
(
repository
,
commit_options
)
}
let
(
:commit
)
{
repository
.
lookup
(
commit_sha
)
}
let
(
:blob
)
{
Gitlab
::
Git
::
Blob
.
find
(
repository
,
commit_sha
,
"README.md"
)
}
it
'should remove file with commit'
do
# Commit message valid
expect
(
commit
.
message
).
to
eq
(
'Remove readme'
)
# File was removed
expect
(
blob
).
to
be_nil
end
end
describe
:lfs_pointers
do
context
'file a valid lfs pointer'
do
let
(
:blob
)
do
...
...
spec/lib/gitlab/git/index_spec.rb
0 → 100644
View file @
9f9ef5be
require
'spec_helper'
describe
Gitlab
::
Git
::
Index
,
seed_helper:
true
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
TEST_REPO_PATH
)
}
let
(
:index
)
{
described_class
.
new
(
repository
)
}
before
do
index
.
read_tree
(
repository
.
lookup
(
'master'
).
tree
)
end
describe
'#create'
do
let
(
:options
)
do
{
content:
'Lorem ipsum...'
,
file_path:
'documents/story.txt'
}
end
context
'when no file at that path exists'
do
it
'creates the file in the index'
do
index
.
create
(
options
)
entry
=
index
.
get
(
options
[
:file_path
])
expect
(
entry
).
not_to
be_nil
expect
(
repository
.
lookup
(
entry
[
:oid
]).
content
).
to
eq
(
options
[
:content
])
end
end
context
'when a file at that path exists'
do
before
do
options
[
:file_path
]
=
'files/executables/ls'
end
it
'raises an error'
do
expect
{
index
.
create
(
options
)
}.
to
raise_error
(
'Filename already exists'
)
end
end
context
'when content is in base64'
do
before
do
options
[
:content
]
=
Base64
.
encode64
(
options
[
:content
])
options
[
:encoding
]
=
'base64'
end
it
'decodes base64'
do
index
.
create
(
options
)
entry
=
index
.
get
(
options
[
:file_path
])
expect
(
repository
.
lookup
(
entry
[
:oid
]).
content
).
to
eq
(
Base64
.
decode64
(
options
[
:content
]))
end
end
context
'when content contains CRLF'
do
before
do
repository
.
autocrlf
=
:input
options
[
:content
]
=
"Hello,
\r\n
World"
end
it
'converts to LF'
do
index
.
create
(
options
)
entry
=
index
.
get
(
options
[
:file_path
])
expect
(
repository
.
lookup
(
entry
[
:oid
]).
content
).
to
eq
(
"Hello,
\n
World"
)
end
end
end
describe
'#create_dir'
do
let
(
:options
)
do
{
file_path:
'newdir'
}
end
context
'when no file or dir at that path exists'
do
it
'creates the dir in the index'
do
index
.
create_dir
(
options
)
entry
=
index
.
get
(
options
[
:file_path
]
+
'/.gitkeep'
)
expect
(
entry
).
not_to
be_nil
end
end
context
'when a file at that path exists'
do
before
do
options
[
:file_path
]
=
'files/executables/ls'
end
it
'raises an error'
do
expect
{
index
.
create_dir
(
options
)
}.
to
raise_error
(
'Directory already exists as a file'
)
end
end
end
describe
'#update'
do
let
(
:options
)
do
{
content:
'Lorem ipsum...'
,
file_path:
'README.md'
}
end
context
'when no file at that path exists'
do
before
do
options
[
:file_path
]
=
'documents/story.txt'
end
it
'raises an error'
do
expect
{
index
.
update
(
options
)
}.
to
raise_error
(
"File doesn't exist"
)
end
end
context
'when a file at that path exists'
do
it
'updates the file in the index'
do
index
.
update
(
options
)
entry
=
index
.
get
(
options
[
:file_path
])
expect
(
repository
.
lookup
(
entry
[
:oid
]).
content
).
to
eq
(
options
[
:content
])
end
it
'preserves file mode'
do
options
[
:file_path
]
=
'files/executables/ls'
index
.
update
(
options
)
entry
=
index
.
get
(
options
[
:file_path
])
expect
(
entry
[
:mode
]).
to
eq
(
0100755
)
end
end
end
describe
'#move'
do
let
(
:options
)
do
{
content:
'Lorem ipsum...'
,
previous_path:
'README.md'
,
file_path:
'NEWREADME.md'
}
end
context
'when no file at that path exists'
do
it
'raises an error'
do
options
[
:previous_path
]
=
'documents/story.txt'
expect
{
index
.
move
(
options
)
}.
to
raise_error
(
"File doesn't exist"
)
end
end
context
'when a file at that path exists'
do
it
'removes the old file in the index'
do
index
.
move
(
options
)
entry
=
index
.
get
(
options
[
:previous_path
])
expect
(
entry
).
to
be_nil
end
it
'creates the new file in the index'
do
index
.
move
(
options
)
entry
=
index
.
get
(
options
[
:file_path
])
expect
(
entry
).
not_to
be_nil
expect
(
repository
.
lookup
(
entry
[
:oid
]).
content
).
to
eq
(
options
[
:content
])
end
it
'preserves file mode'
do
options
[
:previous_path
]
=
'files/executables/ls'
index
.
move
(
options
)
entry
=
index
.
get
(
options
[
:file_path
])
expect
(
entry
[
:mode
]).
to
eq
(
0100755
)
end
end
end
describe
'#delete'
do
let
(
:options
)
do
{
file_path:
'README.md'
}
end
context
'when no file at that path exists'
do
before
do
options
[
:file_path
]
=
'documents/story.txt'
end
it
'raises an error'
do
expect
{
index
.
delete
(
options
)
}.
to
raise_error
(
"File doesn't exist"
)
end
end
context
'when a file at that path exists'
do
it
'removes the file in the index'
do
index
.
delete
(
options
)
entry
=
index
.
get
(
options
[
:file_path
])
expect
(
entry
).
to
be_nil
end
end
end
end
spec/lib/gitlab/git/repository_spec.rb
View file @
9f9ef5be
...
...
@@ -844,81 +844,6 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
describe
'#mkdir'
do
let
(
:commit_options
)
do
{
author:
{
email:
'user@example.com'
,
name:
'Test User'
,
time:
Time
.
now
},
committer:
{
email:
'user@example.com'
,
name:
'Test User'
,
time:
Time
.
now
},
commit:
{
message:
'Test message'
,
branch:
'refs/heads/fix'
,
}
}
end
def
generate_diff_for_path
(
path
)
"diff --git a/
#{
path
}
/.gitkeep b/
#{
path
}
/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/
#{
path
}
/.gitkeep
\n
"
end
shared_examples
'mkdir diff check'
do
|
path
,
expected_path
|
it
'creates a directory'
do
result
=
repository
.
mkdir
(
path
,
commit_options
)
expect
(
result
).
not_to
eq
(
nil
)
# Verify another mkdir doesn't create a directory that already exists
expect
{
repository
.
mkdir
(
path
,
commit_options
)
}.
to
raise_error
(
'Directory already exists'
)
end
end
describe
'creates a directory in root directory'
do
it_should_behave_like
'mkdir diff check'
,
'new_dir'
,
'new_dir'
end
describe
'creates a directory in subdirectory'
do
it_should_behave_like
'mkdir diff check'
,
'files/ruby/test'
,
'files/ruby/test'
end
describe
'creates a directory in subdirectory with a slash'
do
it_should_behave_like
'mkdir diff check'
,
'/files/ruby/test2'
,
'files/ruby/test2'
end
describe
'creates a directory in subdirectory with multiple slashes'
do
it_should_behave_like
'mkdir diff check'
,
'//files/ruby/test3'
,
'files/ruby/test3'
end
describe
'handles relative paths'
do
it_should_behave_like
'mkdir diff check'
,
'files/ruby/../test_relative'
,
'files/test_relative'
end
describe
'creates nested directories'
do
it_should_behave_like
'mkdir diff check'
,
'files/missing/test'
,
'files/missing/test'
end
it
'does not attempt to create a directory with invalid relative path'
do
expect
{
repository
.
mkdir
(
'../files/missing/test'
,
commit_options
)
}.
to
raise_error
(
'Invalid path'
)
end
it
'does not attempt to overwrite a file'
do
expect
{
repository
.
mkdir
(
'README.md'
,
commit_options
)
}.
to
raise_error
(
'Directory already exists as a file'
)
end
it
'does not attempt to overwrite a directory'
do
expect
{
repository
.
mkdir
(
'files'
,
commit_options
)
}.
to
raise_error
(
'Directory already exists'
)
end
end
describe
"#ls_files"
do
let
(
:master_file_paths
)
{
repository
.
ls_files
(
"master"
)
}
let
(
:not_existed_branch
)
{
repository
.
ls_files
(
"not_existed_branch"
)
}
...
...
spec/models/repository_spec.rb
View file @
9f9ef5be
...
...
@@ -355,7 +355,7 @@ describe Repository, models: true do
repository
.
commit_file
(
user
,
'hello.txt'
,
"Hello,
\r\n
World"
,
message:
'Add hello world'
,
branch_name:
'master'
,
update:
tru
e
)
update:
fals
e
)
blob
=
repository
.
blob_at
(
'master'
,
'hello.txt'
)
...
...
spec/requests/api/commits_spec.rb
View file @
9f9ef5be
...
...
@@ -146,16 +146,6 @@ describe API::Commits, api: true do
expect
(
response
).
to
have_http_status
(
400
)
end
context
'with project path in URL'
do
let
(
:url
)
{
"/projects/
#{
project
.
namespace
.
path
}
%2F
#{
project
.
path
}
/repository/commits"
}
it
'a new file in project repo'
do
post
api
(
url
,
user
),
valid_c_params
expect
(
response
).
to
have_http_status
(
201
)
end
end
end
context
:delete
do
...
...
spec/support/cycle_analytics_helpers.rb
View file @
9f9ef5be
...
...
@@ -9,14 +9,7 @@ module CycleAnalyticsHelpers
commit_shas
=
Array
.
new
(
count
)
do
|
index
|
filename
=
random_git_name
options
=
{
committer:
project
.
repository
.
user_to_committer
(
user
),
author:
project
.
repository
.
user_to_committer
(
user
),
commit:
{
message:
message
,
branch:
branch_name
,
update_ref:
true
},
file:
{
content:
"content"
,
path:
filename
,
update:
false
}
}
commit_sha
=
Gitlab
::
Git
::
Blob
.
commit
(
project
.
repository
,
options
)
commit_sha
=
project
.
repository
.
commit_file
(
user
,
filename
,
"content"
,
message:
message
,
branch_name:
branch_name
)
project
.
repository
.
commit
(
commit_sha
)
commit_sha
...
...
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