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
8850fb9d
Commit
8850fb9d
authored
Sep 10, 2018
by
Douglas Barbosa Alexandre
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Synchronize the default branch when updating a remote mirror
parent
7f0a346e
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
113 additions
and
60 deletions
+113
-60
app/models/project.rb
app/models/project.rb
+6
-0
app/models/repository.rb
app/models/repository.rb
+1
-0
app/services/projects/update_remote_mirror_service.rb
app/services/projects/update_remote_mirror_service.rb
+3
-2
spec/models/project_spec.rb
spec/models/project_spec.rb
+34
-0
spec/services/projects/update_remote_mirror_service_spec.rb
spec/services/projects/update_remote_mirror_service_spec.rb
+69
-58
No files found.
app/models/project.rb
View file @
8850fb9d
...
@@ -2063,6 +2063,12 @@ class Project < ActiveRecord::Base
...
@@ -2063,6 +2063,12 @@ class Project < ActiveRecord::Base
auto_cancel_pending_pipelines
==
'enabled'
auto_cancel_pending_pipelines
==
'enabled'
end
end
# Update the default branch querying the remote to determine its HEAD
def
update_root_ref
(
remote_name
)
root_ref
=
repository
.
find_remote_root_ref
(
remote_name
)
change_head
(
root_ref
)
if
root_ref
.
present?
&&
root_ref
!=
default_branch
end
private
private
def
rename_or_migrate_repository!
def
rename_or_migrate_repository!
...
...
app/models/repository.rb
View file @
8850fb9d
...
@@ -24,6 +24,7 @@ class Repository
...
@@ -24,6 +24,7 @@ class Repository
delegate
:ref_name_for_sha
,
to: :raw_repository
delegate
:ref_name_for_sha
,
to: :raw_repository
delegate
:bundle_to_disk
,
to: :raw_repository
delegate
:bundle_to_disk
,
to: :raw_repository
delegate
:find_remote_root_ref
,
to: :raw_repository
CreateTreeError
=
Class
.
new
(
StandardError
)
CreateTreeError
=
Class
.
new
(
StandardError
)
...
...
app/services/projects/update_remote_mirror_service.rb
View file @
8850fb9d
...
@@ -5,13 +5,14 @@ module Projects
...
@@ -5,13 +5,14 @@ module Projects
attr_reader
:errors
attr_reader
:errors
def
execute
(
remote_mirror
)
def
execute
(
remote_mirror
)
@errors
=
[]
return
success
unless
remote_mirror
.
enabled?
return
success
unless
remote_mirror
.
enabled?
errors
=
[]
begin
begin
remote_mirror
.
ensure_remote!
remote_mirror
.
ensure_remote!
repository
.
fetch_remote
(
remote_mirror
.
remote_name
,
no_tags:
true
)
repository
.
fetch_remote
(
remote_mirror
.
remote_name
,
no_tags:
true
)
project
.
update_root_ref
(
remote_mirror
.
remote_name
)
opts
=
{}
opts
=
{}
if
remote_mirror
.
only_protected_branches?
if
remote_mirror
.
only_protected_branches?
...
...
spec/models/project_spec.rb
View file @
8850fb9d
...
@@ -3983,6 +3983,40 @@ describe Project do
...
@@ -3983,6 +3983,40 @@ describe Project do
end
end
end
end
describe
'#update_root_ref'
do
let
(
:project
)
{
create
(
:project
,
:repository
)
}
it
'updates the default branch when HEAD has changed'
do
stub_find_remote_root_ref
(
project
,
ref:
'feature'
)
expect
{
project
.
update_root_ref
(
'origin'
)
}
.
to
change
{
project
.
default_branch
}
.
from
(
'master'
)
.
to
(
'feature'
)
end
it
'does not update the default branch when HEAD does not change'
do
stub_find_remote_root_ref
(
project
,
ref:
'master'
)
expect
{
project
.
update_root_ref
(
'origin'
)
}
.
not_to
change
{
project
.
default_branch
}
end
it
'does not update the default branch when HEAD does not exist'
do
stub_find_remote_root_ref
(
project
,
ref:
'foo'
)
expect
{
project
.
update_root_ref
(
'origin'
)
}
.
not_to
change
{
project
.
default_branch
}
end
def
stub_find_remote_root_ref
(
project
,
ref
:)
allow
(
project
.
repository
)
.
to
receive
(
:find_remote_root_ref
)
.
with
(
'origin'
)
.
and_return
(
ref
)
end
end
def
rugged_config
def
rugged_config
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
project
.
repository
.
rugged
.
config
project
.
repository
.
rugged
.
config
...
...
spec/services/projects/update_remote_mirror_service_spec.rb
View file @
8850fb9d
require
'spec_helper'
require
'spec_helper'
describe
Projects
::
UpdateRemoteMirrorService
do
describe
Projects
::
UpdateRemoteMirrorService
do
set
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:owner
)
{
project
.
owner
}
let
(
:remote_project
)
{
create
(
:forked_project_with_submodules
)
}
let
(
:remote_project
)
{
create
(
:forked_project_with_submodules
)
}
let
(
:repository
)
{
project
.
repository
}
let
(
:raw_repository
)
{
repository
.
raw
}
let
(
:remote_mirror
)
{
project
.
remote_mirrors
.
create!
(
url:
remote_project
.
http_url_to_repo
,
enabled:
true
,
only_protected_branches:
false
)
}
let
(
:remote_mirror
)
{
project
.
remote_mirrors
.
create!
(
url:
remote_project
.
http_url_to_repo
,
enabled:
true
,
only_protected_branches:
false
)
}
let
(
:remote_name
)
{
remote_mirror
.
remote_name
}
subject
{
described_class
.
new
(
project
,
project
.
creator
)
}
subject
(
:service
)
{
described_class
.
new
(
project
,
project
.
creator
)
}
describe
"#execute"
do
describe
"#execute"
do
before
do
before
do
repository
.
add_branch
(
owner
,
'existing-branch'
,
'master'
)
project
.
repository
.
add_branch
(
project
.
owner
,
'existing-branch'
,
'master'
)
allow
(
remote_mirror
).
to
receive
(
:update_repository
).
and_return
(
true
)
allow
(
remote_mirror
).
to
receive
(
:update_repository
).
and_return
(
true
)
end
end
it
"ensures the remote exists"
do
stub_fetch_remote
(
project
,
remote_name:
remote_name
)
stub_find_remote_root_ref
(
project
,
remote_name:
remote_name
)
expect
(
remote_mirror
).
to
receive
(
:ensure_remote!
)
service
.
execute
(
remote_mirror
)
end
it
"fetches the remote repository"
do
it
"fetches the remote repository"
do
expect
(
remote_mirror
).
to
receive
(
:ensure_remote!
).
and_call_original
stub_find_remote_root_ref
(
project
,
remote_name:
remote_name
)
expect
(
repository
).
to
receive
(
:fetch_remote
).
with
(
remote_mirror
.
remote_name
,
no_tags:
true
)
do
sync_remote
(
repository
,
remote_mirror
.
remote_name
,
local_branch_names
)
expect
(
project
.
repository
)
.
to
receive
(
:fetch_remote
)
.
with
(
remote_mirror
.
remote_name
,
no_tags:
true
)
service
.
execute
(
remote_mirror
)
end
end
subject
.
execute
(
remote_mirror
)
it
"updates the default branch when HEAD has changed"
do
stub_fetch_remote
(
project
,
remote_name:
remote_name
)
stub_find_remote_root_ref
(
project
,
remote_name:
remote_name
,
ref:
"existing-branch"
)
expect
{
service
.
execute
(
remote_mirror
)
}
.
to
change
{
project
.
default_branch
}
.
from
(
"master"
)
.
to
(
"existing-branch"
)
end
end
it
"succeeds"
do
it
"does not update the default branch when HEAD does not change"
do
allow
(
repository
).
to
receive
(
:fetch_remote
)
{
sync_remote
(
repository
,
remote_mirror
.
remote_name
,
local_branch_names
)
}
stub_fetch_remote
(
project
,
remote_name:
remote_name
)
stub_find_remote_root_ref
(
project
,
remote_name:
remote_name
,
ref:
"master"
)
result
=
subject
.
execute
(
remote_mirror
)
expect
{
service
.
execute
(
remote_mirror
)
}.
not_to
change
{
project
.
default_branch
}
end
it
"returns success when updated succeeds"
do
stub_fetch_remote
(
project
,
remote_name:
remote_name
)
stub_find_remote_root_ref
(
project
,
remote_name:
remote_name
)
result
=
service
.
execute
(
remote_mirror
)
expect
(
result
[
:status
]).
to
eq
(
:success
)
expect
(
result
[
:status
]).
to
eq
(
:success
)
end
end
context
'when syncing all branches'
do
context
'when syncing all branches'
do
it
"push all the branches the first time"
do
it
"push all the branches the first time"
do
allow
(
repository
).
to
receive
(
:fetch_remote
)
stub_fetch_remote
(
project
,
remote_name:
remote_name
)
stub_find_remote_root_ref
(
project
,
remote_name:
remote_name
)
expect
(
remote_mirror
).
to
receive
(
:update_repository
).
with
({})
expect
(
remote_mirror
).
to
receive
(
:update_repository
).
with
({})
s
ubject
.
execute
(
remote_mirror
)
s
ervice
.
execute
(
remote_mirror
)
end
end
end
end
context
'when only syncing protected branches'
do
context
'when only syncing protected branches'
do
let
(
:unprotected_branch_name
)
{
'existing-branch'
}
it
"sync updated protected branches"
do
let
(
:protected_branch_name
)
do
stub_fetch_remote
(
project
,
remote_name:
remote_name
)
project
.
repository
.
branch_names
.
find
{
|
n
|
n
!=
unprotected_branch_name
}
stub_find_remote_root_ref
(
project
,
remote_name:
remote_name
)
end
protected_branch
=
create_protected_branch
(
project
)
let!
(
:protected_branch
)
do
create
(
:protected_branch
,
project:
project
,
name:
protected_branch_name
)
end
before
do
project
.
reload
remote_mirror
.
only_protected_branches
=
true
remote_mirror
.
only_protected_branches
=
true
end
it
"sync updated protected branches"
do
expect
(
remote_mirror
)
allow
(
repository
).
to
receive
(
:fetch_remote
)
.
to
receive
(
:update_repository
)
expect
(
remote_mirror
).
to
receive
(
:update_repository
).
with
(
only_branches_matching:
[
protected_branch_
name
])
.
with
(
only_branches_matching:
[
protected_branch
.
name
])
subject
.
execute
(
remote_mirror
)
service
.
execute
(
remote_mirror
)
end
end
end
end
def
sync_remote
(
repository
,
remote_name
,
local_branch_names
)
def
create_protected_branch
(
project
)
local_branch_names
.
each
do
|
branch
|
branch_name
=
project
.
repository
.
branch_names
.
find
{
|
n
|
n
!=
'existing-branch'
}
commit
=
repository
.
commit
(
branch
)
create
(
:protected_branch
,
project:
project
,
name:
branch_name
)
repository
.
write_ref
(
"refs/remotes/
#{
remote_name
}
/
#{
branch
}
"
,
commit
.
id
)
if
commit
end
end
end
end
def
update_remote_branch
(
repository
,
remote_name
,
branch
)
masterrev
=
repository
.
commit
(
'master'
).
id
repository
.
write_ref
(
"refs/remotes/
#{
remote_name
}
/
#{
branch
}
"
,
masterrev
,
force:
true
)
repository
.
expire_branches_cache
end
end
def
update_branch
(
repository
,
branch
)
def
stub_find_remote_root_ref
(
project
,
ref:
'master'
,
remote_name
:)
masterrev
=
repository
.
commit
(
'master'
).
id
allow
(
project
.
repository
)
.
to
receive
(
:find_remote_root_ref
)
.
with
(
remote_name
)
.
and_return
(
ref
)
end
repository
.
write_ref
(
"refs/heads/
#{
branch
}
"
,
masterrev
,
force:
true
)
def
stub_fetch_remote
(
project
,
remote_name
:)
repository
.
expire_branches_cache
allow
(
project
.
repository
)
.
to
receive
(
:fetch_remote
)
.
with
(
remote_name
,
no_tags:
true
)
{
fetch_remote
(
project
.
repository
,
remote_name
)
}
end
end
def
generate_tags
(
repository
,
*
tag_names
)
def
fetch_remote
(
repository
,
remote_name
)
tag_names
.
each_with_object
([])
do
|
name
,
tags
|
local_branch_names
(
repository
).
each
do
|
branch
|
tag
=
repository
.
find_tag
(
name
)
commit
=
repository
.
commit
(
branch
)
target
=
tag
.
try
(
:target
)
repository
.
write_ref
(
"refs/remotes/
#{
remote_name
}
/
#{
branch
}
"
,
commit
.
id
)
if
commit
target_commit
=
tag
.
try
(
:dereferenced_target
)
tags
<<
Gitlab
::
Git
::
Tag
.
new
(
repository
.
raw_repository
,
{
name:
name
,
target:
target
,
target_commit:
target_commit
})
end
end
end
end
def
local_branch_names
def
local_branch_names
(
repository
)
branch_names
=
repository
.
branches
.
map
(
&
:name
)
branch_names
=
repository
.
branches
.
map
(
&
:name
)
# we want the protected branch to be pushed first
# we want the protected branch to be pushed first
branch_names
.
unshift
(
branch_names
.
delete
(
'master'
))
branch_names
.
unshift
(
branch_names
.
delete
(
'master'
))
...
...
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