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
1bca36b6
Commit
1bca36b6
authored
Apr 05, 2018
by
Marin Jankovski
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce
parents
c48a9c73
32d2206b
Changes
26
Show whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
563 additions
and
16 deletions
+563
-16
.gitlab-ci.yml
.gitlab-ci.yml
+95
-0
app/assets/javascripts/boards/services/board_service.js
app/assets/javascripts/boards/services/board_service.js
+1
-1
app/controllers/projects/lfs_api_controller.rb
app/controllers/projects/lfs_api_controller.rb
+1
-1
app/models/project.rb
app/models/project.rb
+10
-0
app/services/boards/issues/move_service.rb
app/services/boards/issues/move_service.rb
+4
-1
app/services/issues/update_service.rb
app/services/issues/update_service.rb
+13
-4
app/services/projects/import_export/export_service.rb
app/services/projects/import_export/export_service.rb
+5
-1
app/views/projects/_export.html.haml
app/views/projects/_export.html.haml
+1
-1
changelogs/unreleased/bvl-export-import-lfs.yml
changelogs/unreleased/bvl-export-import-lfs.yml
+5
-0
changelogs/unreleased/issue_44551.yml
changelogs/unreleased/issue_44551.yml
+5
-0
changelogs/unreleased/zj-opt-out-list-commits-by-oid.yml
changelogs/unreleased/zj-opt-out-list-commits-by-oid.yml
+5
-0
doc/user/project/settings/import_export.md
doc/user/project/settings/import_export.md
+1
-1
lib/gitlab/checks/lfs_integrity.rb
lib/gitlab/checks/lfs_integrity.rb
+1
-2
lib/gitlab/git/commit.rb
lib/gitlab/git/commit.rb
+2
-1
lib/gitlab/import_export/importer.rb
lib/gitlab/import_export/importer.rb
+10
-1
lib/gitlab/import_export/lfs_restorer.rb
lib/gitlab/import_export/lfs_restorer.rb
+43
-0
lib/gitlab/import_export/lfs_saver.rb
lib/gitlab/import_export/lfs_saver.rb
+55
-0
spec/fixtures/exported-project.gz
spec/fixtures/exported-project.gz
+0
-0
spec/lib/gitlab/import_export/importer_spec.rb
spec/lib/gitlab/import_export/importer_spec.rb
+64
-0
spec/lib/gitlab/import_export/lfs_restorer_spec.rb
spec/lib/gitlab/import_export/lfs_restorer_spec.rb
+75
-0
spec/lib/gitlab/import_export/lfs_saver_spec.rb
spec/lib/gitlab/import_export/lfs_saver_spec.rb
+62
-0
spec/models/project_spec.rb
spec/models/project_spec.rb
+16
-0
spec/services/boards/issues/move_service_spec.rb
spec/services/boards/issues/move_service_spec.rb
+1
-1
spec/services/issues/update_service_spec.rb
spec/services/issues/update_service_spec.rb
+31
-0
spec/services/projects/import_export/export_service_spec.rb
spec/services/projects/import_export/export_service_spec.rb
+43
-0
spec/support/shared_examples/services/boards/issues_move_service.rb
...rt/shared_examples/services/boards/issues_move_service.rb
+14
-1
No files found.
.gitlab-ci.yml
View file @
1bca36b6
...
@@ -78,6 +78,19 @@ stages:
...
@@ -78,6 +78,19 @@ stages:
-
mysql:latest
-
mysql:latest
-
redis:alpine
-
redis:alpine
.rails5-variables
:
&rails5-variables
script
:
-
export RAILS5=${RAILS5}
-
export BUNDLE_GEMFILE=${BUNDLE_GEMFILE}
.rails5
:
&rails5
allow_failure
:
true
only
:
-
/rails5/
variables
:
BUNDLE_GEMFILE
:
"
Gemfile.rails5"
RAILS5
:
"
true"
# Skip all jobs except the ones that begin with 'docs/'.
# Skip all jobs except the ones that begin with 'docs/'.
# Used for commits including ONLY documentation changes.
# Used for commits including ONLY documentation changes.
# https://docs.gitlab.com/ce/development/writing_documentation.html#testing
# https://docs.gitlab.com/ce/development/writing_documentation.html#testing
...
@@ -118,6 +131,7 @@ stages:
...
@@ -118,6 +131,7 @@ stages:
<<
:
*dedicated-runner
<<
:
*dedicated-runner
<<
:
*except-docs-and-qa
<<
:
*except-docs-and-qa
<<
:
*pull-cache
<<
:
*pull-cache
<<
:
*rails5-variables
stage
:
test
stage
:
test
script
:
script
:
-
JOB_NAME=( $CI_JOB_NAME )
-
JOB_NAME=( $CI_JOB_NAME )
...
@@ -148,14 +162,23 @@ stages:
...
@@ -148,14 +162,23 @@ stages:
<<
:
*rspec-metadata
<<
:
*rspec-metadata
<<
:
*use-pg
<<
:
*use-pg
.rspec-metadata-pg-rails5
:
&rspec-metadata-pg-rails5
<<
:
*rspec-metadata-pg
<<
:
*rails5
.rspec-metadata-mysql
:
&rspec-metadata-mysql
.rspec-metadata-mysql
:
&rspec-metadata-mysql
<<
:
*rspec-metadata
<<
:
*rspec-metadata
<<
:
*use-mysql
<<
:
*use-mysql
.rspec-metadata-mysql-rails5
:
&rspec-metadata-mysql-rails5
<<
:
*rspec-metadata-mysql
<<
:
*rails5
.spinach-metadata
:
&spinach-metadata
.spinach-metadata
:
&spinach-metadata
<<
:
*dedicated-runner
<<
:
*dedicated-runner
<<
:
*except-docs-and-qa
<<
:
*except-docs-and-qa
<<
:
*pull-cache
<<
:
*pull-cache
<<
:
*rails5-variables
stage
:
test
stage
:
test
script
:
script
:
-
JOB_NAME=( $CI_JOB_NAME )
-
JOB_NAME=( $CI_JOB_NAME )
...
@@ -179,10 +202,18 @@ stages:
...
@@ -179,10 +202,18 @@ stages:
<<
:
*spinach-metadata
<<
:
*spinach-metadata
<<
:
*use-pg
<<
:
*use-pg
.spinach-metadata-pg-rails5
:
&spinach-metadata-pg-rails5
<<
:
*spinach-metadata-pg
<<
:
*rails5
.spinach-metadata-mysql
:
&spinach-metadata-mysql
.spinach-metadata-mysql
:
&spinach-metadata-mysql
<<
:
*spinach-metadata
<<
:
*spinach-metadata
<<
:
*use-mysql
<<
:
*use-mysql
.spinach-metadata-mysql-rails5
:
&spinach-metadata-mysql-rails5
<<
:
*spinach-metadata-mysql
<<
:
*rails5
.only-canonical-masters
:
&only-canonical-masters
.only-canonical-masters
:
&only-canonical-masters
only
:
only
:
-
master@gitlab-org/gitlab-ce
-
master@gitlab-org/gitlab-ce
...
@@ -468,6 +499,70 @@ spinach-pg 1 2: *spinach-metadata-pg
...
@@ -468,6 +499,70 @@ spinach-pg 1 2: *spinach-metadata-pg
spinach-mysql 0 2
:
*spinach-metadata-mysql
spinach-mysql 0 2
:
*spinach-metadata-mysql
spinach-mysql 1 2
:
*spinach-metadata-mysql
spinach-mysql 1 2
:
*spinach-metadata-mysql
rspec-pg-rails5 0 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 1 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 2 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 3 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 4 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 5 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 6 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 7 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 8 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 9 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 10 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 11 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 12 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 13 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 14 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 15 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 16 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 17 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 18 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 19 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 20 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 21 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 22 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 23 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 24 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 25 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 26 28
:
*rspec-metadata-pg-rails5
rspec-pg-rails5 27 28
:
*rspec-metadata-pg-rails5
rspec-mysql-rails5 0 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 1 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 2 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 3 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 4 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 5 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 6 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 7 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 8 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 9 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 10 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 11 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 12 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 13 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 14 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 15 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 16 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 17 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 18 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 19 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 20 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 21 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 22 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 23 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 24 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 25 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 26 28
:
*rspec-metadata-mysql-rails5
rspec-mysql-rails5 27 28
:
*rspec-metadata-mysql-rails5
spinach-pg-rails5 0 2
:
*spinach-metadata-pg-rails5
spinach-pg-rails5 1 2
:
*spinach-metadata-pg-rails5
spinach-mysql-rails5 0 2
:
*spinach-metadata-mysql-rails5
spinach-mysql-rails5 1 2
:
*spinach-metadata-mysql-rails5
static-analysis
:
static-analysis
:
<<
:
*dedicated-no-docs-no-db-pull-cache-job
<<
:
*dedicated-no-docs-no-db-pull-cache-job
dependencies
:
dependencies
:
...
...
app/assets/javascripts/boards/services/board_service.js
View file @
1bca36b6
...
@@ -19,7 +19,7 @@ export default class BoardService {
...
@@ -19,7 +19,7 @@ export default class BoardService {
}
}
static
generateIssuePath
(
boardId
,
id
)
{
static
generateIssuePath
(
boardId
,
id
)
{
return
`
${
gon
.
relative_url_root
}
/-/boards/
${
boardId
?
`
/
${
boardId
}
`
:
''
}
/issues
${
id
?
`/
${
id
}
`
:
''
}
`
;
return
`
${
gon
.
relative_url_root
}
/-/boards/
${
boardId
?
`
${
boardId
}
`
:
''
}
/issues
${
id
?
`/
${
id
}
`
:
''
}
`
;
}
}
all
()
{
all
()
{
...
...
app/controllers/projects/lfs_api_controller.rb
View file @
1bca36b6
...
@@ -41,7 +41,7 @@ class Projects::LfsApiController < Projects::GitHttpClientController
...
@@ -41,7 +41,7 @@ class Projects::LfsApiController < Projects::GitHttpClientController
def
existing_oids
def
existing_oids
@existing_oids
||=
begin
@existing_oids
||=
begin
storage_project
.
lfs_objects
.
where
(
oid:
objects
.
map
{
|
o
|
o
[
'oid'
].
to_s
}).
pluck
(
:oid
)
project
.
all_
lfs_objects
.
where
(
oid:
objects
.
map
{
|
o
|
o
[
'oid'
].
to_s
}).
pluck
(
:oid
)
end
end
end
end
...
...
app/models/project.rb
View file @
1bca36b6
...
@@ -1066,6 +1066,16 @@ class Project < ActiveRecord::Base
...
@@ -1066,6 +1066,16 @@ class Project < ActiveRecord::Base
end
end
end
end
# This will return all `lfs_objects` that are accessible to the project.
# So this might be `self.lfs_objects` if the project is not part of a fork
# network, or it is the base of the fork network.
#
# TODO: refactor this to get the correct lfs objects when implementing
# https://gitlab.com/gitlab-org/gitlab-ce/issues/39769
def
all_lfs_objects
lfs_storage_project
.
lfs_objects
end
def
personal?
def
personal?
!
group
!
group
end
end
...
...
app/services/boards/issues/move_service.rb
View file @
1bca36b6
...
@@ -42,7 +42,10 @@ module Boards
...
@@ -42,7 +42,10 @@ module Boards
)
)
end
end
attrs
[
:move_between_ids
]
=
move_between_ids
if
move_between_ids
if
move_between_ids
attrs
[
:move_between_ids
]
=
move_between_ids
attrs
[
:board_group_id
]
=
board
.
group
&
.
id
end
attrs
attrs
end
end
...
...
app/services/issues/update_service.rb
View file @
1bca36b6
...
@@ -55,9 +55,10 @@ module Issues
...
@@ -55,9 +55,10 @@ module Issues
return
unless
params
[
:move_between_ids
]
return
unless
params
[
:move_between_ids
]
after_id
,
before_id
=
params
.
delete
(
:move_between_ids
)
after_id
,
before_id
=
params
.
delete
(
:move_between_ids
)
board_group_id
=
params
.
delete
(
:board_group_id
)
issue_before
=
get_issue_if_allowed
(
issue
.
project
,
before_id
)
if
before_id
issue_before
=
get_issue_if_allowed
(
before_id
,
board_group_id
)
issue_after
=
get_issue_if_allowed
(
issue
.
project
,
after_id
)
if
after_id
issue_after
=
get_issue_if_allowed
(
after_id
,
board_group_id
)
issue
.
move_between
(
issue_before
,
issue_after
)
issue
.
move_between
(
issue_before
,
issue_after
)
end
end
...
@@ -84,8 +85,16 @@ module Issues
...
@@ -84,8 +85,16 @@ module Issues
private
private
def
get_issue_if_allowed
(
project
,
id
)
def
get_issue_if_allowed
(
id
,
board_group_id
=
nil
)
issue
=
project
.
issues
.
find
(
id
)
return
unless
id
issue
=
if
board_group_id
IssuesFinder
.
new
(
current_user
,
group_id:
board_group_id
).
find_by
(
id:
id
)
else
project
.
issues
.
find
(
id
)
end
issue
if
can?
(
current_user
,
:update_issue
,
issue
)
issue
if
can?
(
current_user
,
:update_issue
,
issue
)
end
end
...
...
app/services/projects/import_export/export_service.rb
View file @
1bca36b6
...
@@ -28,7 +28,7 @@ module Projects
...
@@ -28,7 +28,7 @@ module Projects
end
end
def
save_services
def
save_services
[
version_saver
,
avatar_saver
,
project_tree_saver
,
uploads_saver
,
repo_saver
,
wiki_repo_saver
].
all?
(
&
:save
)
[
version_saver
,
avatar_saver
,
project_tree_saver
,
uploads_saver
,
repo_saver
,
wiki_repo_saver
,
lfs_saver
].
all?
(
&
:save
)
end
end
def
version_saver
def
version_saver
...
@@ -55,6 +55,10 @@ module Projects
...
@@ -55,6 +55,10 @@ module Projects
Gitlab
::
ImportExport
::
WikiRepoSaver
.
new
(
project:
project
,
shared:
@shared
)
Gitlab
::
ImportExport
::
WikiRepoSaver
.
new
(
project:
project
,
shared:
@shared
)
end
end
def
lfs_saver
Gitlab
::
ImportExport
::
LfsSaver
.
new
(
project:
project
,
shared:
@shared
)
end
def
cleanup_and_notify_error
def
cleanup_and_notify_error
Rails
.
logger
.
error
(
"Import/Export - Project
#{
project
.
name
}
with ID:
#{
project
.
id
}
export error -
#{
@shared
.
errors
.
join
(
', '
)
}
"
)
Rails
.
logger
.
error
(
"Import/Export - Project
#{
project
.
name
}
with ID:
#{
project
.
id
}
export error -
#{
@shared
.
errors
.
join
(
', '
)
}
"
)
...
...
app/views/projects/_export.html.haml
View file @
1bca36b6
...
@@ -21,11 +21,11 @@
...
@@ -21,11 +21,11 @@
%li
Project uploads
%li
Project uploads
%li
Project configuration including web hooks and services
%li
Project configuration including web hooks and services
%li
Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities
%li
Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities
%li
LFS objects
%p
%p
The following items will NOT be exported:
The following items will NOT be exported:
%ul
%ul
%li
Job traces and artifacts
%li
Job traces and artifacts
%li
LFS objects
%li
Container registry images
%li
Container registry images
%li
CI variables
%li
CI variables
%li
Any encrypted tokens
%li
Any encrypted tokens
...
...
changelogs/unreleased/bvl-export-import-lfs.yml
0 → 100644
View file @
1bca36b6
---
title
:
Support LFS objects when importing/exporting GitLab project archives
merge_request
:
18115
author
:
type
:
added
changelogs/unreleased/issue_44551.yml
0 → 100644
View file @
1bca36b6
---
title
:
Fix 404 in group boards when moving issue between lists
merge_request
:
author
:
type
:
fixed
changelogs/unreleased/zj-opt-out-list-commits-by-oid.yml
0 → 100644
View file @
1bca36b6
---
title
:
ListCommitsByOid is executed by Gitaly by default
merge_request
:
author
:
type
:
performance
doc/user/project/settings/import_export.md
View file @
1bca36b6
...
@@ -57,11 +57,11 @@ The following items will be exported:
...
@@ -57,11 +57,11 @@ The following items will be exported:
-
Project configuration including web hooks and services
-
Project configuration including web hooks and services
-
Issues with comments, merge requests with diffs and comments, labels, milestones, snippets,
-
Issues with comments, merge requests with diffs and comments, labels, milestones, snippets,
and other project entities
and other project entities
-
LFS objects
The following items will NOT be exported:
The following items will NOT be exported:
-
Build traces and artifacts
-
Build traces and artifacts
-
LFS objects
-
Container registry images
-
Container registry images
-
CI variables
-
CI variables
-
Any encrypted tokens
-
Any encrypted tokens
...
...
lib/gitlab/checks/lfs_integrity.rb
View file @
1bca36b6
...
@@ -15,8 +15,7 @@ module Gitlab
...
@@ -15,8 +15,7 @@ module Gitlab
return
false
unless
new_lfs_pointers
.
present?
return
false
unless
new_lfs_pointers
.
present?
existing_count
=
@project
.
lfs_storage_project
existing_count
=
@project
.
all_lfs_objects
.
lfs_objects
.
where
(
oid:
new_lfs_pointers
.
map
(
&
:lfs_oid
))
.
where
(
oid:
new_lfs_pointers
.
map
(
&
:lfs_oid
))
.
count
.
count
...
...
lib/gitlab/git/commit.rb
View file @
1bca36b6
...
@@ -231,7 +231,8 @@ module Gitlab
...
@@ -231,7 +231,8 @@ module Gitlab
# relation to each other. The last 10 commits for a branch for example,
# relation to each other. The last 10 commits for a branch for example,
# should go through .where
# should go through .where
def
batch_by_oid
(
repo
,
oids
)
def
batch_by_oid
(
repo
,
oids
)
repo
.
gitaly_migrate
(
:list_commits_by_oid
)
do
|
is_enabled
|
repo
.
gitaly_migrate
(
:list_commits_by_oid
,
status:
Gitlab
::
GitalyClient
::
MigrationStatus
::
OPT_OUT
)
do
|
is_enabled
|
if
is_enabled
if
is_enabled
repo
.
gitaly_commit_client
.
list_commits_by_oid
(
oids
)
repo
.
gitaly_commit_client
.
list_commits_by_oid
(
oids
)
else
else
...
...
lib/gitlab/import_export/importer.rb
View file @
1bca36b6
...
@@ -13,7 +13,7 @@ module Gitlab
...
@@ -13,7 +13,7 @@ module Gitlab
end
end
def
execute
def
execute
if
import_file
&&
check_version!
&&
[
repo_restorer
,
wiki_restorer
,
project_tree
,
avatar_restorer
,
uploads_restorer
]
.
all?
(
&
:restore
)
if
import_file
&&
check_version!
&&
restorers
.
all?
(
&
:restore
)
project_tree
.
restored_project
project_tree
.
restored_project
else
else
raise
Projects
::
ImportService
::
Error
.
new
(
@shared
.
errors
.
join
(
', '
))
raise
Projects
::
ImportService
::
Error
.
new
(
@shared
.
errors
.
join
(
', '
))
...
@@ -24,6 +24,11 @@ module Gitlab
...
@@ -24,6 +24,11 @@ module Gitlab
private
private
def
restorers
[
repo_restorer
,
wiki_restorer
,
project_tree
,
avatar_restorer
,
uploads_restorer
,
lfs_restorer
]
end
def
import_file
def
import_file
Gitlab
::
ImportExport
::
FileImporter
.
import
(
archive_file:
@archive_file
,
Gitlab
::
ImportExport
::
FileImporter
.
import
(
archive_file:
@archive_file
,
shared:
@shared
)
shared:
@shared
)
...
@@ -60,6 +65,10 @@ module Gitlab
...
@@ -60,6 +65,10 @@ module Gitlab
Gitlab
::
ImportExport
::
UploadsRestorer
.
new
(
project:
project_tree
.
restored_project
,
shared:
@shared
)
Gitlab
::
ImportExport
::
UploadsRestorer
.
new
(
project:
project_tree
.
restored_project
,
shared:
@shared
)
end
end
def
lfs_restorer
Gitlab
::
ImportExport
::
LfsRestorer
.
new
(
project:
project_tree
.
restored_project
,
shared:
@shared
)
end
def
path_with_namespace
def
path_with_namespace
File
.
join
(
@project
.
namespace
.
full_path
,
@project
.
path
)
File
.
join
(
@project
.
namespace
.
full_path
,
@project
.
path
)
end
end
...
...
lib/gitlab/import_export/lfs_restorer.rb
0 → 100644
View file @
1bca36b6
module
Gitlab
module
ImportExport
class
LfsRestorer
def
initialize
(
project
:,
shared
:)
@project
=
project
@shared
=
shared
end
def
restore
return
true
if
lfs_file_paths
.
empty?
lfs_file_paths
.
each
do
|
file_path
|
link_or_create_lfs_object!
(
file_path
)
end
true
rescue
=>
e
@shared
.
error
(
e
)
false
end
private
def
link_or_create_lfs_object!
(
path
)
size
=
File
.
size
(
path
)
oid
=
LfsObject
.
calculate_oid
(
path
)
lfs_object
=
LfsObject
.
find_or_initialize_by
(
oid:
oid
,
size:
size
)
lfs_object
.
file
=
File
.
open
(
path
)
unless
lfs_object
.
file
&
.
exists?
@project
.
all_lfs_objects
<<
lfs_object
end
def
lfs_file_paths
@lfs_file_paths
||=
Dir
.
glob
(
"
#{
lfs_storage_path
}
/*"
)
end
def
lfs_storage_path
File
.
join
(
@shared
.
export_path
,
'lfs-objects'
)
end
end
end
end
lib/gitlab/import_export/lfs_saver.rb
0 → 100644
View file @
1bca36b6
module
Gitlab
module
ImportExport
class
LfsSaver
include
Gitlab
::
ImportExport
::
CommandLineUtil
def
initialize
(
project
:,
shared
:)
@project
=
project
@shared
=
shared
end
def
save
@project
.
all_lfs_objects
.
each
do
|
lfs_object
|
save_lfs_object
(
lfs_object
)
end
true
rescue
=>
e
@shared
.
error
(
e
)
false
end
private
def
save_lfs_object
(
lfs_object
)
if
lfs_object
.
local_store?
copy_file_for_lfs_object
(
lfs_object
)
else
download_file_for_lfs_object
(
lfs_object
)
end
end
def
download_file_for_lfs_object
(
lfs_object
)
destination
=
destination_path_for_object
(
lfs_object
)
mkdir_p
(
File
.
dirname
(
destination
))
File
.
open
(
destination
,
'w'
)
do
|
file
|
IO
.
copy_stream
(
URI
.
parse
(
lfs_object
.
file
.
url
).
open
,
file
)
end
end
def
copy_file_for_lfs_object
(
lfs_object
)
copy_files
(
lfs_object
.
file
.
path
,
destination_path_for_object
(
lfs_object
))
end
def
destination_path_for_object
(
lfs_object
)
File
.
join
(
lfs_export_path
,
lfs_object
.
oid
)
end
def
lfs_export_path
File
.
join
(
@shared
.
export_path
,
'lfs-objects'
)
end
end
end
end
spec/fixtures/exported-project.gz
0 → 100644
View file @
1bca36b6
File added
spec/lib/gitlab/import_export/importer_spec.rb
0 → 100644
View file @
1bca36b6
require
'spec_helper'
describe
Gitlab
::
ImportExport
::
Importer
do
let
(
:test_path
)
{
"
#{
Dir
.
tmpdir
}
/importer_spec"
}
let
(
:shared
)
{
project
.
import_export_shared
}
let
(
:project
)
{
create
(
:project
,
import_source:
File
.
join
(
test_path
,
'exported-project.gz'
))
}
subject
(
:importer
)
{
described_class
.
new
(
project
)
}
before
do
allow_any_instance_of
(
Gitlab
::
ImportExport
).
to
receive
(
:storage_path
).
and_return
(
test_path
)
FileUtils
.
mkdir_p
(
shared
.
export_path
)
FileUtils
.
cp
(
Rails
.
root
.
join
(
'spec'
,
'fixtures'
,
'exported-project.gz'
),
test_path
)
end
after
do
FileUtils
.
rm_rf
(
test_path
)
end
describe
'#execute'
do
it
'succeeds'
do
importer
.
execute
expect
(
shared
.
errors
).
to
be_empty
end
it
'extracts the archive'
do
expect
(
Gitlab
::
ImportExport
::
FileImporter
).
to
receive
(
:import
).
and_call_original
importer
.
execute
end
it
'checks the version'
do
expect
(
Gitlab
::
ImportExport
::
VersionChecker
).
to
receive
(
:check!
).
and_call_original
importer
.
execute
end
context
'all restores are executed'
do
[
Gitlab
::
ImportExport
::
AvatarRestorer
,
Gitlab
::
ImportExport
::
RepoRestorer
,
Gitlab
::
ImportExport
::
WikiRestorer
,
Gitlab
::
ImportExport
::
UploadsRestorer
,
Gitlab
::
ImportExport
::
LfsRestorer
].
each
do
|
restorer
|
it
"calls the
#{
restorer
}
"
do
fake_restorer
=
double
(
restorer
.
to_s
)
expect
(
fake_restorer
).
to
receive
(
:restore
).
and_return
(
true
).
at_least
(
1
)
expect
(
restorer
).
to
receive
(
:new
).
and_return
(
fake_restorer
).
at_least
(
1
)
importer
.
execute
end
end
it
'restores the ProjectTree'
do
expect
(
Gitlab
::
ImportExport
::
ProjectTreeRestorer
).
to
receive
(
:new
).
and_call_original
importer
.
execute
end
end
end
end
spec/lib/gitlab/import_export/lfs_restorer_spec.rb
0 → 100644
View file @
1bca36b6
require
'spec_helper'
describe
Gitlab
::
ImportExport
::
LfsRestorer
do
include
UploadHelpers
let
(
:export_path
)
{
"
#{
Dir
.
tmpdir
}
/lfs_object_restorer_spec"
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:shared
)
{
project
.
import_export_shared
}
subject
(
:restorer
)
{
described_class
.
new
(
project:
project
,
shared:
shared
)
}
before
do
allow_any_instance_of
(
Gitlab
::
ImportExport
).
to
receive
(
:storage_path
).
and_return
(
export_path
)
FileUtils
.
mkdir_p
(
shared
.
export_path
)
end
after
do
FileUtils
.
rm_rf
(
shared
.
export_path
)
end
describe
'#restore'
do
context
'when the archive contains lfs files'
do
let
(
:dummy_lfs_file_path
)
{
File
.
join
(
shared
.
export_path
,
'lfs-objects'
,
'dummy'
)
}
def
create_lfs_object_with_content
(
content
)
dummy_lfs_file
=
Tempfile
.
new
(
'existing'
)
File
.
write
(
dummy_lfs_file
.
path
,
content
)
size
=
dummy_lfs_file
.
size
oid
=
LfsObject
.
calculate_oid
(
dummy_lfs_file
.
path
)
LfsObject
.
create!
(
oid:
oid
,
size:
size
,
file:
dummy_lfs_file
)
end
before
do
FileUtils
.
mkdir_p
(
File
.
dirname
(
dummy_lfs_file_path
))
File
.
write
(
dummy_lfs_file_path
,
'not very large'
)
allow
(
restorer
).
to
receive
(
:lfs_file_paths
).
and_return
([
dummy_lfs_file_path
])
end
it
'creates an lfs object for the project'
do
expect
{
restorer
.
restore
}.
to
change
{
project
.
reload
.
lfs_objects
.
size
}.
by
(
1
)
end
it
'assigns the file correctly'
do
restorer
.
restore
expect
(
project
.
lfs_objects
.
first
.
file
.
read
).
to
eq
(
'not very large'
)
end
it
'links an existing LFS object if it existed'
do
lfs_object
=
create_lfs_object_with_content
(
'not very large'
)
restorer
.
restore
expect
(
project
.
lfs_objects
).
to
include
(
lfs_object
)
end
it
'succeeds'
do
expect
(
restorer
.
restore
).
to
be_truthy
expect
(
shared
.
errors
).
to
be_empty
end
it
'stores the upload'
do
expect_any_instance_of
(
LfsObjectUploader
).
to
receive
(
:store!
)
restorer
.
restore
end
end
context
'without any LFS-objects'
do
it
'succeeds'
do
expect
(
restorer
.
restore
).
to
be_truthy
expect
(
shared
.
errors
).
to
be_empty
end
end
end
end
spec/lib/gitlab/import_export/lfs_saver_spec.rb
0 → 100644
View file @
1bca36b6
require
'spec_helper'
describe
Gitlab
::
ImportExport
::
LfsSaver
do
let
(
:shared
)
{
project
.
import_export_shared
}
let
(
:export_path
)
{
"
#{
Dir
.
tmpdir
}
/project_tree_saver_spec"
}
let
(
:project
)
{
create
(
:project
)
}
subject
(
:saver
)
{
described_class
.
new
(
project:
project
,
shared:
shared
)
}
before
do
allow_any_instance_of
(
Gitlab
::
ImportExport
).
to
receive
(
:storage_path
).
and_return
(
export_path
)
FileUtils
.
mkdir_p
(
shared
.
export_path
)
end
after
do
FileUtils
.
rm_rf
(
shared
.
export_path
)
end
describe
'#save'
do
context
'when the project has LFS objects locally stored'
do
let
(
:lfs_object
)
{
create
(
:lfs_object
,
:with_file
)
}
before
do
project
.
lfs_objects
<<
lfs_object
end
it
'does not cause errors'
do
saver
.
save
expect
(
shared
.
errors
).
to
be_empty
end
it
'copies the file in the correct location when there is an lfs object'
do
saver
.
save
expect
(
File
).
to
exist
(
"
#{
shared
.
export_path
}
/lfs-objects/
#{
lfs_object
.
oid
}
"
)
end
end
context
'when the LFS objects are stored in object storage'
do
let
(
:lfs_object
)
{
create
(
:lfs_object
,
:object_storage
)
}
before
do
allow
(
LfsObjectUploader
).
to
receive
(
:object_store_enabled?
).
and_return
(
true
)
allow
(
lfs_object
.
file
).
to
receive
(
:url
).
and_return
(
'http://my-object-storage.local'
)
project
.
lfs_objects
<<
lfs_object
end
it
'downloads the file to include in an archive'
do
fake_uri
=
double
exported_file_path
=
"
#{
shared
.
export_path
}
/lfs-objects/
#{
lfs_object
.
oid
}
"
expect
(
fake_uri
).
to
receive
(
:open
).
and_return
(
StringIO
.
new
(
'LFS file content'
))
expect
(
URI
).
to
receive
(
:parse
).
with
(
'http://my-object-storage.local'
).
and_return
(
fake_uri
)
saver
.
save
expect
(
File
.
read
(
exported_file_path
)).
to
eq
(
'LFS file content'
)
end
end
end
end
spec/models/project_spec.rb
View file @
1bca36b6
...
@@ -2022,6 +2022,22 @@ describe Project do
...
@@ -2022,6 +2022,22 @@ describe Project do
expect
(
forked_project
.
lfs_storage_project
).
to
eq
forked_project
expect
(
forked_project
.
lfs_storage_project
).
to
eq
forked_project
end
end
end
end
describe
'#all_lfs_objects'
do
let
(
:lfs_object
)
{
create
(
:lfs_object
)
}
before
do
project
.
lfs_objects
<<
lfs_object
end
it
'returns the lfs object for a project'
do
expect
(
project
.
all_lfs_objects
).
to
contain_exactly
(
lfs_object
)
end
it
'returns the lfs object for a fork'
do
expect
(
forked_project
.
all_lfs_objects
).
to
contain_exactly
(
lfs_object
)
end
end
end
end
describe
'#pushes_since_gc'
do
describe
'#pushes_since_gc'
do
...
...
spec/services/boards/issues/move_service_spec.rb
View file @
1bca36b6
...
@@ -48,7 +48,7 @@ describe Boards::Issues::MoveService do
...
@@ -48,7 +48,7 @@ describe Boards::Issues::MoveService do
parent
.
add_developer
(
user
)
parent
.
add_developer
(
user
)
end
end
it_behaves_like
'issues move service'
it_behaves_like
'issues move service'
,
true
end
end
end
end
end
end
spec/services/issues/update_service_spec.rb
View file @
1bca36b6
...
@@ -97,6 +97,37 @@ describe Issues::UpdateService, :mailer do
...
@@ -97,6 +97,37 @@ describe Issues::UpdateService, :mailer do
expect
(
issue
.
relative_position
).
to
be_between
(
issue1
.
relative_position
,
issue2
.
relative_position
)
expect
(
issue
.
relative_position
).
to
be_between
(
issue1
.
relative_position
,
issue2
.
relative_position
)
end
end
context
'when moving issue between issues from different projects'
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:project_1
)
{
create
(
:project
,
namespace:
group
)
}
let
(
:project_2
)
{
create
(
:project
,
namespace:
group
)
}
let
(
:project_3
)
{
create
(
:project
,
namespace:
group
)
}
let
(
:issue_1
)
{
create
(
:issue
,
project:
project_1
)
}
let
(
:issue_2
)
{
create
(
:issue
,
project:
project_2
)
}
let
(
:issue_3
)
{
create
(
:issue
,
project:
project_3
)
}
before
do
group
.
add_developer
(
user
)
end
it
'sorts issues as specified by parameters'
do
# Moving all issues to end here like the last example won't work since
# all projects only have the same issue count
# so their relative_position will be the same.
issue_1
.
move_to_end
issue_2
.
move_after
(
issue_1
)
issue_3
.
move_after
(
issue_2
)
[
issue_1
,
issue_2
,
issue_3
].
map
(
&
:save
)
opts
[
:move_between_ids
]
=
[
issue_1
.
id
,
issue_2
.
id
]
opts
[
:board_group_id
]
=
group
.
id
described_class
.
new
(
issue_3
.
project
,
user
,
opts
).
execute
(
issue_3
)
expect
(
issue_2
.
relative_position
).
to
be_between
(
issue_1
.
relative_position
,
issue_2
.
relative_position
)
end
end
context
'when current user cannot admin issues in the project'
do
context
'when current user cannot admin issues in the project'
do
let
(
:guest
)
{
create
(
:user
)
}
let
(
:guest
)
{
create
(
:user
)
}
before
do
before
do
...
...
spec/services/projects/import_export/export_service_spec.rb
View file @
1bca36b6
...
@@ -8,6 +8,49 @@ describe Projects::ImportExport::ExportService do
...
@@ -8,6 +8,49 @@ describe Projects::ImportExport::ExportService do
let
(
:service
)
{
described_class
.
new
(
project
,
user
)
}
let
(
:service
)
{
described_class
.
new
(
project
,
user
)
}
let!
(
:after_export_strategy
)
{
Gitlab
::
ImportExport
::
AfterExportStrategies
::
DownloadNotificationStrategy
.
new
}
let!
(
:after_export_strategy
)
{
Gitlab
::
ImportExport
::
AfterExportStrategies
::
DownloadNotificationStrategy
.
new
}
it
'saves the version'
do
expect
(
Gitlab
::
ImportExport
::
VersionSaver
).
to
receive
(
:new
).
and_call_original
service
.
execute
end
it
'saves the avatar'
do
expect
(
Gitlab
::
ImportExport
::
AvatarSaver
).
to
receive
(
:new
).
and_call_original
service
.
execute
end
it
'saves the models'
do
expect
(
Gitlab
::
ImportExport
::
ProjectTreeSaver
).
to
receive
(
:new
).
and_call_original
service
.
execute
end
it
'saves the uploads'
do
expect
(
Gitlab
::
ImportExport
::
UploadsSaver
).
to
receive
(
:new
).
and_call_original
service
.
execute
end
it
'saves the repo'
do
# once for the normal repo, once for the wiki
expect
(
Gitlab
::
ImportExport
::
RepoSaver
).
to
receive
(
:new
).
twice
.
and_call_original
service
.
execute
end
it
'saves the lfs objects'
do
expect
(
Gitlab
::
ImportExport
::
LfsSaver
).
to
receive
(
:new
).
and_call_original
service
.
execute
end
it
'saves the wiki repo'
do
expect
(
Gitlab
::
ImportExport
::
WikiRepoSaver
).
to
receive
(
:new
).
and_call_original
service
.
execute
end
context
'when all saver services succeed'
do
context
'when all saver services succeed'
do
before
do
before
do
allow
(
service
).
to
receive
(
:save_services
).
and_return
(
true
)
allow
(
service
).
to
receive
(
:save_services
).
and_return
(
true
)
...
...
spec/support/shared_examples/services/boards/issues_move_service.rb
View file @
1bca36b6
shared_examples
'issues move service'
do
shared_examples
'issues move service'
do
|
group
|
context
'when moving an issue between lists'
do
context
'when moving an issue between lists'
do
let
(
:issue
)
{
create
(
:labeled_issue
,
project:
project
,
labels:
[
bug
,
development
])
}
let
(
:issue
)
{
create
(
:labeled_issue
,
project:
project
,
labels:
[
bug
,
development
])
}
let
(
:params
)
{
{
board_id:
board1
.
id
,
from_list_id:
list1
.
id
,
to_list_id:
list2
.
id
}
}
let
(
:params
)
{
{
board_id:
board1
.
id
,
from_list_id:
list1
.
id
,
to_list_id:
list2
.
id
}
}
...
@@ -83,5 +83,18 @@ shared_examples 'issues move service' do
...
@@ -83,5 +83,18 @@ shared_examples 'issues move service' do
expect
(
issue
.
relative_position
).
to
be_between
(
issue1
.
relative_position
,
issue2
.
relative_position
)
expect
(
issue
.
relative_position
).
to
be_between
(
issue1
.
relative_position
,
issue2
.
relative_position
)
end
end
if
group
context
'when on a group board'
do
it
'sends the board_group_id parameter'
do
params
.
merge!
(
move_after_id:
issue1
.
id
,
move_before_id:
issue2
.
id
)
match_params
=
{
move_between_ids:
[
issue1
.
id
,
issue2
.
id
],
board_group_id:
parent
.
id
}
expect
(
Issues
::
UpdateService
).
to
receive
(
:new
).
with
(
issue
.
project
,
user
,
match_params
).
and_return
(
double
(
execute:
build
(
:issue
)))
described_class
.
new
(
parent
,
user
,
params
).
execute
(
issue
)
end
end
end
end
end
end
end
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