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
Jérome Perrin
gitlab-ce
Commits
580d8953
Commit
580d8953
authored
Nov 15, 2017
by
Takuya Noguchi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add overview of branches and a filter for active/stale branches
parent
65348cf0
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
338 additions
and
50 deletions
+338
-50
app/controllers/projects/branches_controller.rb
app/controllers/projects/branches_controller.rb
+36
-5
app/finders/branches_finder.rb
app/finders/branches_finder.rb
+1
-1
app/helpers/branches_helper.rb
app/helpers/branches_helper.rb
+0
-11
app/views/projects/branches/_panel.html.haml
app/views/projects/branches/_panel.html.haml
+19
-0
app/views/projects/branches/index.html.haml
app/views/projects/branches/index.html.haml
+36
-17
changelogs/unreleased/40187-project-branch-dashboard-with-active-stale-branches.yml
...7-project-branch-dashboard-with-active-stale-branches.yml
+5
-0
config/routes/repository.rb
config/routes/repository.rb
+1
-0
lib/gitlab/git/branch.rb
lib/gitlab/git/branch.rb
+14
-0
spec/controllers/projects/branches_controller_spec.rb
spec/controllers/projects/branches_controller_spec.rb
+33
-0
spec/features/projects/branches/download_buttons_spec.rb
spec/features/projects/branches/download_buttons_spec.rb
+1
-1
spec/features/projects/branches_spec.rb
spec/features/projects/branches_spec.rb
+125
-12
spec/features/projects/environments/environment_spec.rb
spec/features/projects/environments/environment_spec.rb
+1
-1
spec/features/projects/merge_request_button_spec.rb
spec/features/projects/merge_request_button_spec.rb
+2
-2
spec/lib/gitlab/git/branch_spec.rb
spec/lib/gitlab/git/branch_spec.rb
+64
-0
No files found.
app/controllers/projects/branches_controller.rb
View file @
580d8953
...
@@ -7,13 +7,19 @@ class Projects::BranchesController < Projects::ApplicationController
...
@@ -7,13 +7,19 @@ class Projects::BranchesController < Projects::ApplicationController
before_action
:authorize_download_code!
before_action
:authorize_download_code!
before_action
:authorize_push_code!
,
only:
[
:new
,
:create
,
:destroy
,
:destroy_all_merged
]
before_action
:authorize_push_code!
,
only:
[
:new
,
:create
,
:destroy
,
:destroy_all_merged
]
def
index
# Support legacy URLs
@sort
=
params
[
:sort
].
presence
||
sort_value_recently_updated
before_action
:redirect_for_legacy_index_sort_or_search
,
only:
[
:index
]
@branches
=
BranchesFinder
.
new
(
@repository
,
params
.
merge
(
sort:
@sort
)).
execute
@branches
=
Kaminari
.
paginate_array
(
@branches
).
page
(
params
[
:page
])
def
index
respond_to
do
|
format
|
respond_to
do
|
format
|
format
.
html
do
format
.
html
do
@sort
=
params
[
:sort
].
presence
||
sort_value_recently_updated
@mode
=
params
[
:state
].
presence
||
'overview'
@overview_max_branches
=
5
# Fetch branches for the specified mode
fetch_branches_by_mode
@refs_pipelines
=
@project
.
pipelines
.
latest_successful_for_refs
(
@branches
.
map
(
&
:name
))
@refs_pipelines
=
@project
.
pipelines
.
latest_successful_for_refs
(
@branches
.
map
(
&
:name
))
@merged_branch_names
=
@merged_branch_names
=
repository
.
merged_branch_names
(
@branches
.
map
(
&
:name
))
repository
.
merged_branch_names
(
@branches
.
map
(
&
:name
))
...
@@ -28,7 +34,9 @@ class Projects::BranchesController < Projects::ApplicationController
...
@@ -28,7 +34,9 @@ class Projects::BranchesController < Projects::ApplicationController
end
end
end
end
format
.
json
do
format
.
json
do
render
json:
@branches
.
map
(
&
:name
)
branches
=
BranchesFinder
.
new
(
@repository
,
params
).
execute
branches
=
Kaminari
.
paginate_array
(
branches
).
page
(
params
[
:page
])
render
json:
branches
.
map
(
&
:name
)
end
end
end
end
end
end
...
@@ -123,4 +131,27 @@ class Projects::BranchesController < Projects::ApplicationController
...
@@ -123,4 +131,27 @@ class Projects::BranchesController < Projects::ApplicationController
context:
'autodeploy'
context:
'autodeploy'
)
)
end
end
def
redirect_for_legacy_index_sort_or_search
# Normalize a legacy URL with redirect
if
request
.
format
!=
:json
&&
!
params
[
:state
].
presence
&&
[
:sort
,
:search
,
:page
].
any?
{
|
key
|
params
[
key
].
presence
}
redirect_to
project_branches_filtered_path
(
@project
,
state:
'all'
),
notice:
'Update your bookmarked URLs as filtered/sorted branches URL has been changed.'
end
end
def
fetch_branches_by_mode
if
@mode
==
'overview'
# overview mode
@active_branches
,
@stale_branches
=
BranchesFinder
.
new
(
@repository
,
sort:
sort_value_recently_updated
).
execute
.
partition
(
&
:active?
)
# Here we get one more branch to indicate if there are more data we're not showing
@active_branches
=
@active_branches
.
first
(
@overview_max_branches
+
1
)
@stale_branches
=
@stale_branches
.
first
(
@overview_max_branches
+
1
)
@branches
=
@active_branches
+
@stale_branches
else
# active/stale/all view mode
@branches
=
BranchesFinder
.
new
(
@repository
,
params
.
merge
(
sort:
@sort
)).
execute
@branches
=
@branches
.
select
{
|
b
|
b
.
state
.
to_s
==
@mode
}
if
%w[active stale]
.
include?
(
@mode
)
@branches
=
Kaminari
.
paginate_array
(
@branches
).
page
(
params
[
:page
])
end
end
end
end
app/finders/branches_finder.rb
View file @
580d8953
class
BranchesFinder
class
BranchesFinder
def
initialize
(
repository
,
params
)
def
initialize
(
repository
,
params
=
{}
)
@repository
=
repository
@repository
=
repository
@params
=
params
@params
=
params
end
end
...
...
app/helpers/branches_helper.rb
View file @
580d8953
module
BranchesHelper
module
BranchesHelper
def
filter_branches_path
(
options
=
{})
exist_opts
=
{
search:
params
[
:search
],
sort:
params
[
:sort
]
}
options
=
exist_opts
.
merge
(
options
)
project_branches_path
(
@project
,
@id
,
options
)
end
def
project_branches
def
project_branches
options_for_select
(
@project
.
repository
.
branch_names
,
@project
.
default_branch
)
options_for_select
(
@project
.
repository
.
branch_names
,
@project
.
default_branch
)
end
end
...
...
app/views/projects/branches/_panel.html.haml
0 → 100644
View file @
580d8953
-
branches
=
local_assigns
.
fetch
(
:branches
)
-
state
=
local_assigns
.
fetch
(
:state
)
-
panel_title
=
local_assigns
.
fetch
(
:panel_title
)
-
show_more_text
=
local_assigns
.
fetch
(
:show_more_text
)
-
project
=
local_assigns
.
fetch
(
:project
)
-
overview_max_branches
=
local_assigns
.
fetch
(
:overview_max_branches
)
-
return
unless
branches
.
any?
.panel.panel-default.prepend-top-10
.panel-heading
%h4
.panel-title
=
panel_title
%ul
.content-list.all-branches
-
branches
.
first
(
overview_max_branches
).
each
do
|
branch
|
=
render
"projects/branches/branch"
,
branch:
branch
,
merged:
project
.
repository
.
merged_to_root_ref?
(
branch
)
-
if
branches
.
size
>
overview_max_branches
.panel-footer.text-center
=
link_to
show_more_text
,
project_branches_filtered_path
(
project
,
state:
state
),
id:
"state-
#{
state
}
"
,
data:
{
state:
state
}
app/views/projects/branches/index.html.haml
View file @
580d8953
...
@@ -3,15 +3,24 @@
...
@@ -3,15 +3,24 @@
%div
{
class:
container_class
}
%div
{
class:
container_class
}
.top-area.adjust
.top-area.adjust
-
if
can?
(
current_user
,
:admin_project
,
@project
)
%ul
.nav-links.issues-state-filters
.nav-text
%li
{
class:
active_when
(
@mode
==
'overview'
)
}
>
-
project_settings_link
=
link_to
s_
(
'Branches|project settings'
),
project_protected_branches_path
(
@project
)
=
link_to
s_
(
'Branches|Overview'
),
project_branches_path
(
@project
),
title:
s_
(
'Branches|Show overview of the branches'
)
=
s_
(
'Branches|Protected branches can be managed in %{project_settings_link}'
).
html_safe
%
{
project_settings_link:
project_settings_link
}
%li
{
class:
active_when
(
@mode
==
'active'
)
}
>
=
link_to
s_
(
'Branches|Active'
),
project_branches_filtered_path
(
@project
,
state:
'active'
),
title:
s_
(
'Branches|Show active branches'
)
%li
{
class:
active_when
(
@mode
==
'stale'
)
}
>
=
link_to
s_
(
'Branches|Stale'
),
project_branches_filtered_path
(
@project
,
state:
'stale'
),
title:
s_
(
'Branches|Show stale branches'
)
%li
{
class:
active_when
(
!
%w[overview active stale]
.
include?
(
@mode
))
}
>
=
link_to
s_
(
'Branches|All'
),
project_branches_filtered_path
(
@project
,
state:
'all'
),
title:
s_
(
'Branches|Show all branches'
)
.nav-controls
.nav-controls
=
form_tag
(
filter_branches_path
,
method: :get
)
do
=
form_tag
(
project_branches_filtered_path
(
@project
,
state:
'all'
)
,
method: :get
)
do
=
search_field_tag
:search
,
params
[
:search
],
{
placeholder:
s_
(
'Branches|Filter by branch name'
),
id:
'branch-search'
,
class:
'form-control search-text-input input-short'
,
spellcheck:
false
}
=
search_field_tag
:search
,
params
[
:search
],
{
placeholder:
s_
(
'Branches|Filter by branch name'
),
id:
'branch-search'
,
class:
'form-control search-text-input input-short'
,
spellcheck:
false
}
-
unless
@mode
==
'overview'
.dropdown.inline
>
.dropdown.inline
>
%button
.dropdown-menu-toggle
{
type:
'button'
,
'data-toggle'
=>
'dropdown'
}
%button
.dropdown-menu-toggle
{
type:
'button'
,
'data-toggle'
=>
'dropdown'
}
%span
.light
%span
.light
...
@@ -22,7 +31,7 @@
...
@@ -22,7 +31,7 @@
=
s_
(
'Branches|Sort by'
)
=
s_
(
'Branches|Sort by'
)
-
branches_sort_options_hash
.
each
do
|
value
,
title
|
-
branches_sort_options_hash
.
each
do
|
value
,
title
|
%li
%li
=
link_to
title
,
filter_branches_path
(
sort:
value
),
class:
(
"is-active"
if
@sort
==
value
)
=
link_to
title
,
project_branches_filtered_path
(
@project
,
state:
'all'
,
search:
params
[
:search
],
sort:
value
),
class:
(
"is-active"
if
@sort
==
value
)
-
if
can?
current_user
,
:push_code
,
@project
-
if
can?
current_user
,
:push_code
,
@project
=
link_to
project_merged_branches_path
(
@project
),
=
link_to
project_merged_branches_path
(
@project
),
...
@@ -35,7 +44,17 @@
...
@@ -35,7 +44,17 @@
=
link_to
new_project_branch_path
(
@project
),
class:
'btn btn-create'
do
=
link_to
new_project_branch_path
(
@project
),
class:
'btn btn-create'
do
=
s_
(
'Branches|New branch'
)
=
s_
(
'Branches|New branch'
)
-
if
@branches
.
any?
-
if
can?
(
current_user
,
:admin_project
,
@project
)
-
project_settings_link
=
link_to
s_
(
'Branches|project settings'
),
project_protected_branches_path
(
@project
)
.row-content-block
%h5
=
s_
(
'Branches|Protected branches can be managed in %{project_settings_link}.'
).
html_safe
%
{
project_settings_link:
project_settings_link
}
-
if
@mode
==
'overview'
&&
(
@active_branches
.
any?
||
@stale_branches
.
any?
)
=
render
"projects/branches/panel"
,
branches:
@active_branches
,
state:
'active'
,
panel_title:
s_
(
'Branches|Active branches'
),
show_more_text:
s_
(
'Branches|Show more active branches'
),
project:
@project
,
overview_max_branches:
@overview_max_branches
=
render
"projects/branches/panel"
,
branches:
@stale_branches
,
state:
'stale'
,
panel_title:
s_
(
'Branches|Stale branches'
),
show_more_text:
s_
(
'Branches|Show more stale branches'
),
project:
@project
,
overview_max_branches:
@overview_max_branches
-
elsif
@branches
.
any?
%ul
.content-list.all-branches
%ul
.content-list.all-branches
-
@branches
.
each
do
|
branch
|
-
@branches
.
each
do
|
branch
|
=
render
"projects/branches/branch"
,
branch:
branch
,
merged:
@merged_branch_names
.
include?
(
branch
.
name
)
=
render
"projects/branches/branch"
,
branch:
branch
,
merged:
@merged_branch_names
.
include?
(
branch
.
name
)
...
...
changelogs/unreleased/40187-project-branch-dashboard-with-active-stale-branches.yml
0 → 100644
View file @
580d8953
---
title
:
Add overview of branches and a filter for active/stale branches
merge_request
:
15402
author
:
Takuya Noguchi
type
:
added
config/routes/repository.rb
View file @
580d8953
...
@@ -49,6 +49,7 @@ scope format: false do
...
@@ -49,6 +49,7 @@ scope format: false do
end
end
end
end
get
'/branches/:state'
,
to:
'branches#index'
,
as: :branches_filtered
,
constraints:
{
state:
/active|stale|all/
}
resources
:branches
,
only:
[
:index
,
:new
,
:create
,
:destroy
]
resources
:branches
,
only:
[
:index
,
:new
,
:create
,
:destroy
]
delete
:merged_branches
,
controller:
'branches'
,
action: :destroy_all_merged
delete
:merged_branches
,
controller:
'branches'
,
action: :destroy_all_merged
resources
:tags
,
only:
[
:index
,
:show
,
:new
,
:create
,
:destroy
]
do
resources
:tags
,
only:
[
:index
,
:show
,
:new
,
:create
,
:destroy
]
do
...
...
lib/gitlab/git/branch.rb
View file @
580d8953
module
Gitlab
module
Gitlab
module
Git
module
Git
class
Branch
<
Ref
class
Branch
<
Ref
STALE_BRANCH_THRESHOLD
=
3
.
months
def
self
.
find
(
repo
,
branch_name
)
def
self
.
find
(
repo
,
branch_name
)
if
branch_name
.
is_a?
(
Gitlab
::
Git
::
Branch
)
if
branch_name
.
is_a?
(
Gitlab
::
Git
::
Branch
)
branch_name
branch_name
...
@@ -12,6 +14,18 @@ module Gitlab
...
@@ -12,6 +14,18 @@ module Gitlab
def
initialize
(
repository
,
name
,
target
,
target_commit
)
def
initialize
(
repository
,
name
,
target
,
target_commit
)
super
(
repository
,
name
,
target
,
target_commit
)
super
(
repository
,
name
,
target
,
target_commit
)
end
end
def
active?
self
.
dereferenced_target
.
committed_date
>=
STALE_BRANCH_THRESHOLD
.
ago
end
def
stale?
!
active?
end
def
state
active?
?
:active
:
:stale
end
end
end
end
end
end
end
spec/controllers/projects/branches_controller_spec.rb
View file @
580d8953
...
@@ -407,10 +407,43 @@ describe Projects::BranchesController do
...
@@ -407,10 +407,43 @@ describe Projects::BranchesController do
get
:index
,
get
:index
,
namespace_id:
project
.
namespace
,
namespace_id:
project
.
namespace
,
project_id:
project
,
project_id:
project
,
state:
'all'
,
format: :html
format: :html
expect
(
response
).
to
have_gitlab_http_status
(
200
)
expect
(
response
).
to
have_gitlab_http_status
(
200
)
end
end
end
end
context
'when depreated sort/search/page parameters are specified'
do
it
'returns with a status 301 when sort specified'
do
get
:index
,
namespace_id:
project
.
namespace
,
project_id:
project
,
sort:
'updated_asc'
,
format: :html
expect
(
response
).
to
redirect_to
project_branches_filtered_path
(
project
,
state:
'all'
)
end
it
'returns with a status 301 when search specified'
do
get
:index
,
namespace_id:
project
.
namespace
,
project_id:
project
,
search:
'feature'
,
format: :html
expect
(
response
).
to
redirect_to
project_branches_filtered_path
(
project
,
state:
'all'
)
end
it
'returns with a status 301 when page specified'
do
get
:index
,
namespace_id:
project
.
namespace
,
project_id:
project
,
page:
2
,
format: :html
expect
(
response
).
to
redirect_to
project_branches_filtered_path
(
project
,
state:
'all'
)
end
end
end
end
end
end
spec/features/projects/branches/download_buttons_spec.rb
View file @
580d8953
...
@@ -29,7 +29,7 @@ feature 'Download buttons in branches page' do
...
@@ -29,7 +29,7 @@ feature 'Download buttons in branches page' do
describe
'when checking branches'
do
describe
'when checking branches'
do
context
'with artifacts'
do
context
'with artifacts'
do
before
do
before
do
visit
project_branches_
path
(
project
,
search:
'binary-encoding'
)
visit
project_branches_
filtered_path
(
project
,
state:
'all'
,
search:
'binary-encoding'
)
end
end
scenario
'shows download artifacts button'
do
scenario
'shows download artifacts button'
do
...
...
spec/features/projects/branches_spec.rb
View file @
580d8953
...
@@ -11,15 +11,109 @@ describe 'Branches' do
...
@@ -11,15 +11,109 @@ describe 'Branches' do
project
.
add_developer
(
user
)
project
.
add_developer
(
user
)
end
end
describe
'Initial branches page'
do
context
'on the projects with 6 active branches and 4 stale branches'
do
it
'shows all the branches sorted by last updated by default'
do
let
(
:project
)
{
create
(
:project
,
:public
,
:empty_repo
)
}
let
(
:repository
)
{
project
.
repository
}
let
(
:threshold
)
{
Gitlab
::
Git
::
Branch
::
STALE_BRANCH_THRESHOLD
}
before
do
# Add 4 stale branches
(
1
..
4
).
reverse_each
do
|
i
|
Timecop
.
freeze
((
threshold
+
i
).
ago
)
{
create_file
(
message:
"a commit in stale-
#{
i
}
"
,
branch_name:
"stale-
#{
i
}
"
)
}
end
# Add 6 active branches
(
1
..
6
).
each
do
|
i
|
Timecop
.
freeze
((
threshold
-
i
).
ago
)
{
create_file
(
message:
"a commit in active-
#{
i
}
"
,
branch_name:
"active-
#{
i
}
"
)
}
end
end
describe
'Overview page of the branches'
do
it
'shows the first 5 active branches and the first 4 stale branches sorted by last updated'
do
visit
project_branches_path
(
project
)
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
5
,
sort_by: :updated_desc
,
state:
'active'
))
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
4
,
sort_by: :updated_desc
,
state:
'stale'
))
expect
(
page
).
to
have_link
(
'Show more active branches'
,
href:
project_branches_filtered_path
(
project
,
state:
'active'
))
expect
(
page
).
not_to
have_content
(
'Show more stale branches'
)
end
end
describe
'Active branches page'
do
it
'shows 6 active branches sorted by last updated'
do
visit
project_branches_filtered_path
(
project
,
state:
'active'
)
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
6
,
sort_by: :updated_desc
,
state:
'active'
))
end
end
describe
'Stale branches page'
do
it
'shows 4 active branches sorted by last updated'
do
visit
project_branches_filtered_path
(
project
,
state:
'stale'
)
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
4
,
sort_by: :updated_desc
,
state:
'stale'
))
end
end
describe
'All branches page'
do
it
'shows 10 branches sorted by last updated'
do
visit
project_branches_filtered_path
(
project
,
state:
'all'
)
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
10
,
sort_by: :updated_desc
))
end
end
context
'with branches over more than one page'
do
before
do
allow
(
Kaminari
.
config
).
to
receive
(
:default_per_page
).
and_return
(
5
)
end
it
'shows only default_per_page active branches sorted by last updated'
do
visit
project_branches_filtered_path
(
project
,
state:
'active'
)
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
Kaminari
.
config
.
default_per_page
,
sort_by: :updated_desc
,
state:
'active'
))
end
it
'shows only default_per_page branches sorted by last updated on All branches'
do
visit
project_branches_filtered_path
(
project
,
state:
'all'
)
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
Kaminari
.
config
.
default_per_page
,
sort_by: :updated_desc
))
end
end
end
describe
'Find branches'
do
it
'shows filtered branches'
,
:js
do
visit
project_branches_path
(
project
)
visit
project_branches_path
(
project
)
fill_in
'branch-search'
,
with:
'fix'
find
(
'#branch-search'
).
native
.
send_keys
(
:enter
)
expect
(
page
).
to
have_content
(
'fix'
)
expect
(
find
(
'.all-branches'
)).
to
have_selector
(
'li'
,
count:
1
)
end
end
describe
'Delete unprotected branch on Overview'
do
it
'removes branch after confirmation'
,
:js
do
visit
project_branches_filtered_path
(
project
,
state:
'all'
)
expect
(
all
(
'.all-branches'
).
last
).
to
have_selector
(
'li'
,
count:
20
)
accept_confirm
{
find
(
'.js-branch-add-pdf-text-binary .btn-remove'
).
click
}
expect
(
all
(
'.all-branches'
).
last
).
to
have_selector
(
'li'
,
count:
19
)
end
end
describe
'All branches page'
do
it
'shows all the branches sorted by last updated by default'
do
visit
project_branches_filtered_path
(
project
,
state:
'all'
)
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
20
,
sort_by: :updated_desc
))
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
20
,
sort_by: :updated_desc
))
end
end
it
'sorts the branches by name'
do
it
'sorts the branches by name'
do
visit
project_branches_
path
(
project
)
visit
project_branches_
filtered_path
(
project
,
state:
'all'
)
click_button
"Last updated"
# Open sorting dropdown
click_button
"Last updated"
# Open sorting dropdown
click_link
"Name"
click_link
"Name"
...
@@ -28,7 +122,7 @@ describe 'Branches' do
...
@@ -28,7 +122,7 @@ describe 'Branches' do
end
end
it
'sorts the branches by oldest updated'
do
it
'sorts the branches by oldest updated'
do
visit
project_branches_
path
(
project
)
visit
project_branches_
filtered_path
(
project
,
state:
'all'
)
click_button
"Last updated"
# Open sorting dropdown
click_button
"Last updated"
# Open sorting dropdown
click_link
"Oldest updated"
click_link
"Oldest updated"
...
@@ -41,13 +135,13 @@ describe 'Branches' do
...
@@ -41,13 +135,13 @@ describe 'Branches' do
%w(one two three four five)
.
each
{
|
ref
|
repository
.
add_branch
(
user
,
ref
,
'master'
)
}
%w(one two three four five)
.
each
{
|
ref
|
repository
.
add_branch
(
user
,
ref
,
'master'
)
}
expect
{
visit
project_branches_
path
(
project
)
}.
not_to
exceed_query_limit
(
control_count
)
expect
{
visit
project_branches_
filtered_path
(
project
,
state:
'all'
)
}.
not_to
exceed_query_limit
(
control_count
)
end
end
end
end
describe
'Find branches'
do
describe
'Find branches
on All branches
'
do
it
'shows filtered branches'
,
:js
do
it
'shows filtered branches'
,
:js
do
visit
project_branches_
path
(
project
)
visit
project_branches_
filtered_path
(
project
,
state:
'all'
)
fill_in
'branch-search'
,
with:
'fix'
fill_in
'branch-search'
,
with:
'fix'
find
(
'#branch-search'
).
native
.
send_keys
(
:enter
)
find
(
'#branch-search'
).
native
.
send_keys
(
:enter
)
...
@@ -57,9 +151,9 @@ describe 'Branches' do
...
@@ -57,9 +151,9 @@ describe 'Branches' do
end
end
end
end
describe
'Delete unprotected branch'
do
describe
'Delete unprotected branch
on All branches
'
do
it
'removes branch after confirmation'
,
:js
do
it
'removes branch after confirmation'
,
:js
do
visit
project_branches_
path
(
project
)
visit
project_branches_
filtered_path
(
project
,
state:
'all'
)
fill_in
'branch-search'
,
with:
'fix'
fill_in
'branch-search'
,
with:
'fix'
...
@@ -73,6 +167,19 @@ describe 'Branches' do
...
@@ -73,6 +167,19 @@ describe 'Branches' do
expect
(
find
(
'.all-branches'
)).
to
have_selector
(
'li'
,
count:
0
)
expect
(
find
(
'.all-branches'
)).
to
have_selector
(
'li'
,
count:
0
)
end
end
end
end
context
'on project with 0 branch'
do
let
(
:project
)
{
create
(
:project
,
:public
,
:empty_repo
)
}
let
(
:repository
)
{
project
.
repository
}
describe
'0 branches on Overview'
do
it
'shows warning'
do
visit
project_branches_path
(
project
)
expect
(
page
).
not_to
have_selector
(
'.all-branches'
)
end
end
end
end
end
context
'logged in as master'
do
context
'logged in as master'
do
...
@@ -83,7 +190,7 @@ describe 'Branches' do
...
@@ -83,7 +190,7 @@ describe 'Branches' do
describe
'Initial branches page'
do
describe
'Initial branches page'
do
it
'shows description for admin'
do
it
'shows description for admin'
do
visit
project_branches_
path
(
project
)
visit
project_branches_
filtered_path
(
project
,
state:
'all'
)
expect
(
page
).
to
have_content
(
"Protected branches can be managed in project settings"
)
expect
(
page
).
to
have_content
(
"Protected branches can be managed in project settings"
)
end
end
...
@@ -102,12 +209,18 @@ describe 'Branches' do
...
@@ -102,12 +209,18 @@ describe 'Branches' do
end
end
end
end
def
sorted_branches
(
repository
,
count
:,
sort_by
:)
def
sorted_branches
(
repository
,
count
:,
sort_by
:,
state:
nil
)
branches
=
repository
.
branches_sorted_by
(
sort_by
)
branches
=
branches
.
select
{
|
b
|
state
==
'active'
?
b
.
active?
:
b
.
stale?
}
if
state
sorted_branches
=
sorted_branches
=
repository
.
branches_sorted_by
(
sort_by
)
.
first
(
count
).
map
do
|
branch
|
branches
.
first
(
count
).
map
do
|
branch
|
Regexp
.
escape
(
branch
.
name
)
Regexp
.
escape
(
branch
.
name
)
end
end
Regexp
.
new
(
sorted_branches
.
join
(
'.*'
))
Regexp
.
new
(
sorted_branches
.
join
(
'.*'
))
end
end
def
create_file
(
message:
'message'
,
branch_name
:)
repository
.
create_file
(
user
,
generate
(
:branch
),
'content'
,
message:
message
,
branch_name:
branch_name
)
end
end
end
spec/features/projects/environments/environment_spec.rb
View file @
580d8953
...
@@ -234,7 +234,7 @@ feature 'Environment' do
...
@@ -234,7 +234,7 @@ feature 'Environment' do
end
end
scenario
'user deletes the branch with running environment'
do
scenario
'user deletes the branch with running environment'
do
visit
project_branches_
path
(
project
,
search:
'feature'
)
visit
project_branches_
filtered_path
(
project
,
state:
'all'
,
search:
'feature'
)
remove_branch_with_hooks
(
project
,
user
,
'feature'
)
do
remove_branch_with_hooks
(
project
,
user
,
'feature'
)
do
page
.
within
(
'.js-branch-feature'
)
{
find
(
'a.btn-remove'
).
click
}
page
.
within
(
'.js-branch-feature'
)
{
find
(
'a.btn-remove'
).
click
}
...
...
spec/features/projects/merge_request_button_spec.rb
View file @
580d8953
...
@@ -81,8 +81,8 @@ feature 'Merge Request button' do
...
@@ -81,8 +81,8 @@ feature 'Merge Request button' do
context
'on branches page'
do
context
'on branches page'
do
it_behaves_like
'Merge request button only shown when allowed'
do
it_behaves_like
'Merge request button only shown when allowed'
do
let
(
:label
)
{
'Merge request'
}
let
(
:label
)
{
'Merge request'
}
let
(
:url
)
{
project_branches_
path
(
project
,
search:
'feature'
)
}
let
(
:url
)
{
project_branches_
filtered_path
(
project
,
state:
'all'
,
search:
'feature'
)
}
let
(
:fork_url
)
{
project_branches_
path
(
forked_project
,
search:
'feature'
)
}
let
(
:fork_url
)
{
project_branches_
filtered_path
(
forked_project
,
state:
'all'
,
search:
'feature'
)
}
end
end
end
end
...
...
spec/lib/gitlab/git/branch_spec.rb
View file @
580d8953
...
@@ -59,5 +59,69 @@ describe Gitlab::Git::Branch, seed_helper: true do
...
@@ -59,5 +59,69 @@ describe Gitlab::Git::Branch, seed_helper: true do
it
{
expect
(
branch
.
dereferenced_target
.
sha
).
to
eq
(
SeedRepo
::
LastCommit
::
ID
)
}
it
{
expect
(
branch
.
dereferenced_target
.
sha
).
to
eq
(
SeedRepo
::
LastCommit
::
ID
)
}
end
end
context
'with active, stale and future branches'
do
let
(
:repository
)
do
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_MUTABLE_REPO_PATH
,
''
)
end
let
(
:user
)
{
create
(
:user
)
}
let
(
:committer
)
do
Gitlab
::
Git
.
committer_hash
(
email:
user
.
email
,
name:
user
.
name
)
end
let
(
:params
)
do
parents
=
[
repository
.
rugged
.
head
.
target
]
tree
=
parents
.
first
.
tree
{
message:
'commit message'
,
author:
committer
,
committer:
committer
,
tree:
tree
,
parents:
parents
}
end
let
(
:stale_sha
)
{
Timecop
.
freeze
(
Gitlab
::
Git
::
Branch
::
STALE_BRANCH_THRESHOLD
.
ago
-
5
.
days
)
{
create_commit
}
}
let
(
:active_sha
)
{
Timecop
.
freeze
(
Gitlab
::
Git
::
Branch
::
STALE_BRANCH_THRESHOLD
.
ago
+
5
.
days
)
{
create_commit
}
}
let
(
:future_sha
)
{
Timecop
.
freeze
(
100
.
days
.
since
)
{
create_commit
}
}
before
do
repository
.
create_branch
(
'stale-1'
,
stale_sha
)
repository
.
create_branch
(
'active-1'
,
active_sha
)
repository
.
create_branch
(
'future-1'
,
future_sha
)
end
after
do
ensure_seeds
end
describe
'examine if the branch is active or stale'
do
let
(
:stale_branch
)
{
repository
.
find_branch
(
'stale-1'
)
}
let
(
:active_branch
)
{
repository
.
find_branch
(
'active-1'
)
}
let
(
:future_branch
)
{
repository
.
find_branch
(
'future-1'
)
}
describe
'#active?'
do
it
{
expect
(
stale_branch
.
active?
).
to
be_falsey
}
it
{
expect
(
active_branch
.
active?
).
to
be_truthy
}
it
{
expect
(
future_branch
.
active?
).
to
be_truthy
}
end
describe
'#stale?'
do
it
{
expect
(
stale_branch
.
stale?
).
to
be_truthy
}
it
{
expect
(
active_branch
.
stale?
).
to
be_falsey
}
it
{
expect
(
future_branch
.
stale?
).
to
be_falsey
}
end
describe
'#state'
do
it
{
expect
(
stale_branch
.
state
).
to
eq
(
:stale
)
}
it
{
expect
(
active_branch
.
state
).
to
eq
(
:active
)
}
it
{
expect
(
future_branch
.
state
).
to
eq
(
:active
)
}
end
end
end
it
{
expect
(
repository
.
branches
.
size
).
to
eq
(
SeedRepo
::
Repo
::
BRANCHES
.
size
)
}
it
{
expect
(
repository
.
branches
.
size
).
to
eq
(
SeedRepo
::
Repo
::
BRANCHES
.
size
)
}
def
create_commit
repository
.
create_commit
(
params
.
merge
(
committer:
committer
.
merge
(
time:
Time
.
now
)))
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