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
0
Merge Requests
0
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
Boxiang Sun
gitlab-ce
Commits
0625af3b
Commit
0625af3b
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
faaca5e1
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
376 additions
and
596 deletions
+376
-596
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/support/cycle_analytics_helpers.rb
spec/support/cycle_analytics_helpers.rb
+1
-8
No files found.
app/models/repository.rb
View file @
0625af3b
...
@@ -752,24 +752,28 @@ class Repository
...
@@ -752,24 +752,28 @@ class Repository
message
:,
branch_name
:,
message
:,
branch_name
:,
author_email:
nil
,
author_name:
nil
,
author_email:
nil
,
author_name:
nil
,
start_branch_name:
nil
,
start_project:
project
)
start_branch_name:
nil
,
start_project:
project
)
check_tree_entry_for_dir
(
branch_name
,
path
)
if
start_branch_name
entry
=
tree_entry_at
(
start_branch_name
||
branch_name
,
path
)
start_project
.
repository
.
if
entry
check_tree_entry_for_dir
(
start_branch_name
,
path
)
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
end
commit_file
(
multi_action
(
user
,
user:
user
,
"
#{
path
}
/.gitkeep"
,
''
,
message:
message
,
message:
message
,
branch_name:
branch_name
,
branch_name:
branch_name
,
update:
false
,
author_email:
author_email
,
author_email:
author_email
,
author_name:
author_name
,
author_name:
author_name
,
start_branch_name:
start_branch_name
,
start_branch_name:
start_branch_name
,
start_project:
start_project
)
start_project:
start_project
,
actions:
[{
action: :create_dir
,
file_path:
path
}])
end
end
# rubocop:enable Metrics/ParameterLists
# rubocop:enable Metrics/ParameterLists
...
@@ -779,18 +783,8 @@ class Repository
...
@@ -779,18 +783,8 @@ class Repository
message
:,
branch_name
:,
update:
true
,
message
:,
branch_name
:,
update:
true
,
author_email:
nil
,
author_name:
nil
,
author_email:
nil
,
author_name:
nil
,
start_branch_name:
nil
,
start_project:
project
)
start_branch_name:
nil
,
start_project:
project
)
unless
update
error_message
=
"Filename already exists; update not allowed"
if
tree_entry_at
(
branch_name
,
path
)
action
=
update
?
:update
:
:create
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
multi_action
(
multi_action
(
user:
user
,
user:
user
,
...
@@ -800,7 +794,7 @@ class Repository
...
@@ -800,7 +794,7 @@ class Repository
author_name:
author_name
,
author_name:
author_name
,
start_branch_name:
start_branch_name
,
start_branch_name:
start_branch_name
,
start_project:
start_project
,
start_project:
start_project
,
actions:
[{
action:
:create
,
actions:
[{
action:
action
,
file_path:
path
,
file_path:
path
,
content:
content
}])
content:
content
}])
end
end
...
@@ -839,6 +833,7 @@ class Repository
...
@@ -839,6 +833,7 @@ class Repository
message
:,
branch_name
:,
message
:,
branch_name
:,
author_email:
nil
,
author_name:
nil
,
author_email:
nil
,
author_name:
nil
,
start_branch_name:
nil
,
start_project:
project
)
start_branch_name:
nil
,
start_project:
project
)
multi_action
(
multi_action
(
user:
user
,
user:
user
,
message:
message
,
message:
message
,
...
@@ -861,21 +856,22 @@ class Repository
...
@@ -861,21 +856,22 @@ class Repository
branch_name
,
branch_name
,
start_branch_name:
start_branch_name
,
start_branch_name:
start_branch_name
,
start_project:
start_project
)
do
|
start_commit
|
start_project:
start_project
)
do
|
start_commit
|
index
=
rugged
.
index
parents
=
if
start_commit
index
=
Gitlab
::
Git
::
Index
.
new
(
raw_repository
)
index
.
read_tree
(
start_commit
.
raw_commit
.
tree
)
[
start_commit
.
sha
]
else
[]
end
actions
.
each
do
|
act
|
if
start_commit
git_action
(
index
,
act
)
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
end
options
=
{
options
=
{
tree:
index
.
write_tree
(
rugged
)
,
tree:
index
.
write_tree
,
message:
message
,
message:
message
,
parents:
parents
parents:
parents
}
}
...
@@ -1174,22 +1170,6 @@ class Repository
...
@@ -1174,22 +1170,6 @@ class Repository
raw_repository
.
send
(
:tree_entry
,
commit
(
branch_name
),
path
)
raw_repository
.
send
(
:tree_entry
,
commit
(
branch_name
),
path
)
end
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
private
def
blob_data_at
(
sha
,
path
)
def
blob_data_at
(
sha
,
path
)
...
@@ -1200,58 +1180,6 @@ class Repository
...
@@ -1200,58 +1180,6 @@ class Repository
blob
.
data
blob
.
data
end
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?
def
refs_directory_exists?
return
false
unless
path_with_namespace
return
false
unless
path_with_namespace
...
...
app/services/files/multi_service.rb
View file @
0625af3b
...
@@ -2,6 +2,8 @@ module Files
...
@@ -2,6 +2,8 @@ module Files
class
MultiService
<
Files
::
BaseService
class
MultiService
<
Files
::
BaseService
class
FileChangedError
<
StandardError
;
end
class
FileChangedError
<
StandardError
;
end
ACTIONS
=
%w[create update delete move]
.
freeze
def
commit
def
commit
repository
.
multi_action
(
repository
.
multi_action
(
user:
current_user
,
user:
current_user
,
...
@@ -19,15 +21,23 @@ module Files
...
@@ -19,15 +21,23 @@ module Files
def
validate
def
validate
super
super
params
[
:actions
].
each_with_index
do
|
action
,
index
|
params
[
:actions
].
each_with_index
do
|
action
,
index
|
unless
action
[
:file_path
].
present?
unless
action
[
:file_path
].
present?
raise_error
(
"You must specify a file_path."
)
raise_error
(
"You must specify a file_path."
)
end
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
[
:file_path
])
regex_check
(
action
[
:previous_path
])
if
action
[
:previous_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
if
project
.
empty_repo?
&&
action
[
:action
]
!=
:create
raise_error
(
"No files to
#{
action
[
:action
]
}
."
)
raise_error
(
"No files to
#{
action
[
:action
]
}
."
)
end
end
...
@@ -43,8 +53,6 @@ module Files
...
@@ -43,8 +53,6 @@ module Files
validate_delete
(
action
)
validate_delete
(
action
)
when
:move
when
:move
validate_move
(
action
,
index
)
validate_move
(
action
,
index
)
else
raise_error
(
"Unknown action type `
#{
action
[
:action
]
}
`."
)
end
end
end
end
end
end
...
...
db/fixtures/development/17_cycle_analytics.rb
View file @
0625af3b
...
@@ -155,17 +155,9 @@ class Gitlab::Seeder::CycleAnalytics
...
@@ -155,17 +155,9 @@ class Gitlab::Seeder::CycleAnalytics
issue
.
project
.
repository
.
add_branch
(
@user
,
branch_name
,
'master'
)
issue
.
project
.
repository
.
add_branch
(
@user
,
branch_name
,
'master'
)
options
=
{
commit_sha
=
issue
.
project
.
repository
.
commit_file
(
@user
,
filename
,
"content"
,
options
,
message:
"Commit for #
#{
issue
.
iid
}
"
,
branch_name:
branch_name
)
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
)
issue
.
project
.
repository
.
commit
(
commit_sha
)
issue
.
project
.
repository
.
commit
(
commit_sha
)
GitPushService
.
new
(
issue
.
project
,
GitPushService
.
new
(
issue
.
project
,
@user
,
@user
,
oldrev:
issue
.
project
.
repository
.
commit
(
"master"
).
sha
,
oldrev:
issue
.
project
.
repository
.
commit
(
"master"
).
sha
,
...
...
lib/api/commits.rb
View file @
0625af3b
...
@@ -52,13 +52,6 @@ module API
...
@@ -52,13 +52,6 @@ module API
attrs
=
declared_params
.
merge
(
start_branch:
declared_params
[
:branch
],
target_branch:
declared_params
[
:branch
])
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
result
=
::
Files
::
MultiService
.
new
(
user_project
,
current_user
,
attrs
).
execute
if
result
[
:status
]
==
:success
if
result
[
:status
]
==
:success
...
...
lib/gitlab/git/blob.rb
View file @
0625af3b
...
@@ -93,163 +93,6 @@ module Gitlab
...
@@ -93,163 +93,6 @@ module Gitlab
commit_id:
sha
,
commit_id:
sha
,
)
)
end
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
end
def
initialize
(
options
)
def
initialize
(
options
)
...
...
lib/gitlab/git/index.rb
0 → 100644
View file @
0625af3b
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 @
0625af3b
...
@@ -837,57 +837,6 @@ module Gitlab
...
@@ -837,57 +837,6 @@ module Gitlab
rugged
.
config
[
'core.autocrlf'
]
=
AUTOCRLF_VALUES
.
invert
[
value
]
rugged
.
config
[
'core.autocrlf'
]
=
AUTOCRLF_VALUES
.
invert
[
value
]
end
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
# Returns result like "git ls-files" , recursive and full file path
#
#
# Ex.
# Ex.
...
...
spec/lib/gitlab/git/blob_spec.rb
View file @
0625af3b
...
@@ -222,191 +222,6 @@ describe Gitlab::Git::Blob, seed_helper: true do
...
@@ -222,191 +222,6 @@ describe Gitlab::Git::Blob, seed_helper: true do
end
end
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
describe
:lfs_pointers
do
context
'file a valid lfs pointer'
do
context
'file a valid lfs pointer'
do
let
(
:blob
)
do
let
(
:blob
)
do
...
...
spec/lib/gitlab/git/index_spec.rb
0 → 100644
View file @
0625af3b
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 @
0625af3b
...
@@ -844,81 +844,6 @@ describe Gitlab::Git::Repository, seed_helper: true do
...
@@ -844,81 +844,6 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
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
describe
"#ls_files"
do
let
(
:master_file_paths
)
{
repository
.
ls_files
(
"master"
)
}
let
(
:master_file_paths
)
{
repository
.
ls_files
(
"master"
)
}
let
(
:not_existed_branch
)
{
repository
.
ls_files
(
"not_existed_branch"
)
}
let
(
:not_existed_branch
)
{
repository
.
ls_files
(
"not_existed_branch"
)
}
...
...
spec/models/repository_spec.rb
View file @
0625af3b
...
@@ -355,7 +355,7 @@ describe Repository, models: true do
...
@@ -355,7 +355,7 @@ describe Repository, models: true do
repository
.
commit_file
(
user
,
'hello.txt'
,
"Hello,
\r\n
World"
,
repository
.
commit_file
(
user
,
'hello.txt'
,
"Hello,
\r\n
World"
,
message:
'Add hello world'
,
message:
'Add hello world'
,
branch_name:
'master'
,
branch_name:
'master'
,
update:
tru
e
)
update:
fals
e
)
blob
=
repository
.
blob_at
(
'master'
,
'hello.txt'
)
blob
=
repository
.
blob_at
(
'master'
,
'hello.txt'
)
...
...
spec/support/cycle_analytics_helpers.rb
View file @
0625af3b
...
@@ -9,14 +9,7 @@ module CycleAnalyticsHelpers
...
@@ -9,14 +9,7 @@ module CycleAnalyticsHelpers
commit_shas
=
Array
.
new
(
count
)
do
|
index
|
commit_shas
=
Array
.
new
(
count
)
do
|
index
|
filename
=
random_git_name
filename
=
random_git_name
options
=
{
commit_sha
=
project
.
repository
.
commit_file
(
user
,
filename
,
"content"
,
message:
message
,
branch_name:
branch_name
)
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
)
project
.
repository
.
commit
(
commit_sha
)
project
.
repository
.
commit
(
commit_sha
)
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