Commit 4a195089 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'ce-to-ee-2017-12-14' into 'master'

CE upstream - Thursday

Closes #4325, gitlab-ce#36054, #4277, #10, gitlab-ce#33926, gitlab-qa#102, gitaly#793, and gitlab-ce#39608

See merge request gitlab-org/gitlab-ee!3787
parents bd4b5181 a8d9352a
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
/* global BoardService */ /* global BoardService */
import Flash from '~/flash'; import Flash from '~/flash';
import PopupDialog from '~/vue_shared/components/popup_dialog.vue'; import modal from '../../vue_shared/components/modal.vue';
import { visitUrl } from '../../lib/utils/url_utility'; import { visitUrl } from '../../lib/utils/url_utility';
import BoardMilestoneSelect from './milestone_select.vue'; import BoardMilestoneSelect from './milestone_select.vue';
import BoardWeightSelect from './weight_select.vue'; import BoardWeightSelect from './weight_select.vue';
...@@ -74,7 +74,7 @@ export default { ...@@ -74,7 +74,7 @@ export default {
BoardLabelsSelect, BoardLabelsSelect,
BoardMilestoneSelect, BoardMilestoneSelect,
BoardWeightSelect, BoardWeightSelect,
PopupDialog, modal,
}, },
computed: { computed: {
isNewForm() { isNewForm() {
...@@ -179,7 +179,7 @@ export default { ...@@ -179,7 +179,7 @@ export default {
</script> </script>
<template> <template>
<popup-dialog <modal
v-show="currentPage" v-show="currentPage"
modal-dialog-class="board-config-modal" modal-dialog-class="board-config-modal"
:hide-footer="readonly" :hide-footer="readonly"
...@@ -275,5 +275,5 @@ export default { ...@@ -275,5 +275,5 @@ export default {
</div> </div>
</form> </form>
</template> </template>
</popup-dialog> </modal>
</template> </template>
...@@ -410,7 +410,6 @@ import initGroupAnalytics from './init_group_analytics'; ...@@ -410,7 +410,6 @@ import initGroupAnalytics from './init_group_analytics';
if ($('#tree-slider').length) new TreeView(); if ($('#tree-slider').length) new TreeView();
if ($('.blob-viewer').length) new BlobViewer(); if ($('.blob-viewer').length) new BlobViewer();
if ($('.project-show-activity').length) new Activities(); if ($('.project-show-activity').length) new Activities();
$('#tree-slider').waitForImages(function() { $('#tree-slider').waitForImages(function() {
ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath); ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath);
}); });
......
<script> <script>
import { s__ } from '../../locale'; import { s__ } from '../../locale';
import tooltip from '../../vue_shared/directives/tooltip'; import tooltip from '../../vue_shared/directives/tooltip';
import PopupDialog from '../../vue_shared/components/popup_dialog.vue'; import modal from '../../vue_shared/components/modal.vue';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import { COMMON_STR } from '../constants'; import { COMMON_STR } from '../constants';
import Icon from '../../vue_shared/components/icon.vue'; import Icon from '../../vue_shared/components/icon.vue';
...@@ -9,7 +9,7 @@ import Icon from '../../vue_shared/components/icon.vue'; ...@@ -9,7 +9,7 @@ import Icon from '../../vue_shared/components/icon.vue';
export default { export default {
components: { components: {
Icon, Icon,
PopupDialog, modal,
}, },
directives: { directives: {
tooltip, tooltip,
...@@ -27,7 +27,7 @@ export default { ...@@ -27,7 +27,7 @@ export default {
}, },
data() { data() {
return { return {
dialogStatus: false, modalStatus: false,
}; };
}, },
computed: { computed: {
...@@ -43,10 +43,10 @@ export default { ...@@ -43,10 +43,10 @@ export default {
}, },
methods: { methods: {
onLeaveGroup() { onLeaveGroup() {
this.dialogStatus = true; this.modalStatus = true;
}, },
leaveGroup(leaveConfirmed) { leaveGroup(leaveConfirmed) {
this.dialogStatus = false; this.modalStatus = false;
if (leaveConfirmed) { if (leaveConfirmed) {
eventHub.$emit('leaveGroup', this.group, this.parentGroup); eventHub.$emit('leaveGroup', this.group, this.parentGroup);
} }
...@@ -82,8 +82,8 @@ export default { ...@@ -82,8 +82,8 @@ export default {
class="fa fa-sign-out" class="fa fa-sign-out"
aria-hidden="true"/> aria-hidden="true"/>
</a> </a>
<popup-dialog <modal
v-show="dialogStatus" v-show="modalStatus"
:primary-button-label="__('Leave')" :primary-button-label="__('Leave')"
kind="warning" kind="warning"
:title="__('Are you sure?')" :title="__('Are you sure?')"
......
...@@ -48,7 +48,7 @@ export default class Issue { ...@@ -48,7 +48,7 @@ export default class Issue {
}) })
.fail(() => new Flash(issueFailMessage)) .fail(() => new Flash(issueFailMessage))
.done((data) => { .done((data) => {
const isClosedBadge = $('div.status-box-closed'); const isClosedBadge = $('div.status-box-issue-closed');
const isOpenBadge = $('div.status-box-open'); const isOpenBadge = $('div.status-box-open');
const projectIssuesCounter = $('.issue_counter'); const projectIssuesCounter = $('.issue_counter');
......
...@@ -9,7 +9,7 @@ import titleComponent from './title.vue'; ...@@ -9,7 +9,7 @@ import titleComponent from './title.vue';
import descriptionComponent from './description.vue'; import descriptionComponent from './description.vue';
import editedComponent from './edited.vue'; import editedComponent from './edited.vue';
import formComponent from './form.vue'; import formComponent from './form.vue';
import RecaptchaDialogImplementor from '../../vue_shared/mixins/recaptcha_dialog_implementor'; import recaptchaModalImplementor from '../../vue_shared/mixins/recaptcha_modal_implementor';
export default { export default {
props: { props: {
...@@ -152,7 +152,7 @@ export default { ...@@ -152,7 +152,7 @@ export default {
}, },
mixins: [ mixins: [
RecaptchaDialogImplementor, recaptchaModalImplementor,
], ],
methods: { methods: {
...@@ -197,7 +197,7 @@ export default { ...@@ -197,7 +197,7 @@ export default {
}); });
}, },
closeRecaptchaDialog() { closeRecaptchaModal() {
this.store.setFormState({ this.store.setFormState({
updateLoading: false, updateLoading: false,
}); });
...@@ -272,10 +272,10 @@ export default { ...@@ -272,10 +272,10 @@ export default {
:enable-autocomplete="enableAutocomplete" :enable-autocomplete="enableAutocomplete"
/> />
<recaptcha-dialog <recaptcha-modal
v-show="showRecaptcha" v-show="showRecaptcha"
:html="recaptchaHTML" :html="recaptchaHTML"
@close="closeRecaptchaDialog" @close="closeRecaptchaModal"
/> />
</div> </div>
<div v-else> <div v-else>
......
<script> <script>
import animateMixin from '../mixins/animate'; import animateMixin from '../mixins/animate';
import TaskList from '../../task_list'; import TaskList from '../../task_list';
import RecaptchaDialogImplementor from '../../vue_shared/mixins/recaptcha_dialog_implementor'; import recaptchaModalImplementor from '../../vue_shared/mixins/recaptcha_modal_implementor';
export default { export default {
mixins: [ mixins: [
animateMixin, animateMixin,
RecaptchaDialogImplementor, recaptchaModalImplementor,
], ],
props: { props: {
...@@ -126,7 +126,7 @@ ...@@ -126,7 +126,7 @@
> >
</textarea> </textarea>
<recaptcha-dialog <recaptcha-modal
v-show="showRecaptcha" v-show="showRecaptcha"
:html="recaptchaHTML" :html="recaptchaHTML"
@close="closeRecaptcha" @close="closeRecaptcha"
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
<textarea <textarea
id="issue-description" id="issue-description"
class="note-textarea js-gfm-input js-autosize markdown-area" class="note-textarea js-gfm-input js-autosize markdown-area"
data-supports-quick-actionss="false" data-supports-quick-actions="false"
aria-label="Description" aria-label="Description"
v-model="formState.description" v-model="formState.description"
ref="textarea" ref="textarea"
......
...@@ -123,9 +123,7 @@ ...@@ -123,9 +123,7 @@
// we need to do this to prevent noteForm inconsistent content warning // we need to do this to prevent noteForm inconsistent content warning
// this is something we intentionally do so we need to recover the content // this is something we intentionally do so we need to recover the content
this.note.note = noteText; this.note.note = noteText;
if (this.$refs.noteBody) { this.$refs.noteBody.$refs.noteForm.note = noteText;
this.$refs.noteBody.$refs.noteForm.note = noteText; // TODO: This could be better
}
}, },
}, },
created() { created() {
......
<script> <script>
export default { export default {
props: { props: {
helpPagePath: { helpPagePath: {
type: String, type: String,
...@@ -10,28 +10,33 @@ export default { ...@@ -10,28 +10,33 @@ export default {
required: true, required: true,
}, },
}, },
}; };
</script> </script>
<template> <template>
<div class="row empty-state js-empty-state"> <div class="row empty-state js-empty-state">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="svg-content"> <div class="svg-content svg-250">
<img :src="emptyStateSvgPath"/> <img :src="emptyStateSvgPath" />
</div> </div>
</div> </div>
<div class="col-xs-12 text-center"> <div class="col-xs-12">
<div class="text-content"> <div class="text-content">
<h4>Build with confidence</h4> <h4 class="text-center">
{{ s__("Pipelines|Build with confidence") }}
</h4>
<p> <p>
Continous Integration can help catch bugs by running your tests automatically, {{ s__("Pipelines|Continous Integration can help catch bugs by running your tests automatically, while Continuous Deployment can help you deliver code to your product environment.") }}
while Continuous Deployment can help you deliver code to your product environment.
</p> </p>
<a :href="helpPagePath" class="btn btn-info"> <div class="text-center">
Get started with Pipelines <a
:href="helpPagePath"
class="btn btn-info"
>
{{ s__("Pipelines|Get started with Pipelines") }}
</a> </a>
</div> </div>
</div> </div>
</div> </div>
</div>
</template> </template>
...@@ -59,8 +59,26 @@ ...@@ -59,8 +59,26 @@
}, },
computed: { computed: {
status() {
return this.job && this.job.status ? this.job.status : {};
},
tooltipText() { tooltipText() {
return `${this.job.name} - ${this.job.status.label}`; const textBuilder = [];
if (this.job.name) {
textBuilder.push(this.job.name);
}
if (this.job.name && this.status.label) {
textBuilder.push('-');
}
if (this.status.label) {
textBuilder.push(`${this.job.status.label}`);
}
return textBuilder.join(' ');
}, },
/** /**
...@@ -78,8 +96,8 @@ ...@@ -78,8 +96,8 @@
<div class="ci-job-component"> <div class="ci-job-component">
<a <a
v-tooltip v-tooltip
v-if="job.status.has_details" v-if="status.has_details"
:href="job.status.details_path" :href="status.details_path"
:title="tooltipText" :title="tooltipText"
:class="cssClassJobName" :class="cssClassJobName"
data-container="body" data-container="body"
...@@ -95,6 +113,7 @@ ...@@ -95,6 +113,7 @@
<div <div
v-else v-else
v-tooltip v-tooltip
class="js-job-component-tooltip"
:title="tooltipText" :title="tooltipText"
:class="cssClassJobName" :class="cssClassJobName"
data-container="body" data-container="body"
...@@ -108,18 +127,18 @@ ...@@ -108,18 +127,18 @@
<action-component <action-component
v-if="hasAction && !isDropdown" v-if="hasAction && !isDropdown"
:tooltip-text="job.status.action.title" :tooltip-text="status.action.title"
:link="job.status.action.path" :link="status.action.path"
:action-icon="job.status.action.icon" :action-icon="status.action.icon"
:action-method="job.status.action.method" :action-method="status.action.method"
/> />
<dropdown-action-component <dropdown-action-component
v-if="hasAction && isDropdown" v-if="hasAction && isDropdown"
:tooltip-text="job.status.action.title" :tooltip-text="status.action.title"
:link="job.status.action.path" :link="status.action.path"
:action-icon="job.status.action.icon" :action-icon="status.action.icon"
:action-method="job.status.action.method" :action-method="status.action.method"
/> />
</div> </div>
</template> </template>
import Vue from 'vue'; import Vue from 'vue';
import PipelinesStore from './stores/pipelines_store'; import PipelinesStore from './stores/pipelines_store';
import pipelinesComponent from './components/pipelines.vue'; import pipelinesComponent from './components/pipelines.vue';
import Translate from '../vue_shared/translate';
Vue.use(Translate);
document.addEventListener('DOMContentLoaded', () => new Vue({ document.addEventListener('DOMContentLoaded', () => new Vue({
el: '#pipelines-list-vue', el: '#pipelines-list-vue',
......
<script> <script>
import popupDialog from '../../../vue_shared/components/popup_dialog.vue'; import modal from '../../../vue_shared/components/modal.vue';
import { __, s__, sprintf } from '../../../locale'; import { __, s__, sprintf } from '../../../locale';
import csrf from '../../../lib/utils/csrf'; import csrf from '../../../lib/utils/csrf';
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
}; };
}, },
components: { components: {
popupDialog, modal,
}, },
computed: { computed: {
csrfToken() { csrfToken() {
...@@ -89,7 +89,7 @@ Once you confirm %{deleteAccount}, it cannot be undone or recovered.`), ...@@ -89,7 +89,7 @@ Once you confirm %{deleteAccount}, it cannot be undone or recovered.`),
<template> <template>
<div> <div>
<popup-dialog <modal
v-if="isOpen" v-if="isOpen"
:title="s__('Profiles|Delete your account?')" :title="s__('Profiles|Delete your account?')"
:text="text" :text="text"
...@@ -134,7 +134,7 @@ Once you confirm %{deleteAccount}, it cannot be undone or recovered.`), ...@@ -134,7 +134,7 @@ Once you confirm %{deleteAccount}, it cannot be undone or recovered.`),
</form> </form>
</template> </template>
</popup-dialog> </modal>
<button <button
type="button" type="button"
......
...@@ -28,8 +28,7 @@ const highlighter = function(element, text, matches) { ...@@ -28,8 +28,7 @@ const highlighter = function(element, text, matches) {
}; };
export default class ProjectFindFile { export default class ProjectFindFile {
constructor(element1, options) {
constructor (element1, options) {
this.element = element1; this.element = element1;
this.options = options; this.options = options;
this.goToBlob = this.goToBlob.bind(this); this.goToBlob = this.goToBlob.bind(this);
......
<script> <script>
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import { __ } from '../../../locale'; import { __ } from '../../../locale';
import popupDialog from '../../../vue_shared/components/popup_dialog.vue'; import modal from '../../../vue_shared/components/modal.vue';
export default { export default {
props: { props: {
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
}; };
}, },
components: { components: {
popupDialog, modal,
}, },
methods: { methods: {
...mapActions([ ...mapActions([
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
</script> </script>
<template> <template>
<popup-dialog <modal
:title="modalTitle" :title="modalTitle"
:primary-button-label="buttonLabel" :primary-button-label="buttonLabel"
kind="success" kind="success"
...@@ -94,5 +94,5 @@ ...@@ -94,5 +94,5 @@
</div> </div>
</fieldset> </fieldset>
</form> </form>
</popup-dialog> </modal>
</template> </template>
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
import { mapGetters, mapState, mapActions } from 'vuex'; import { mapGetters, mapState, mapActions } from 'vuex';
import tooltip from '../../vue_shared/directives/tooltip'; import tooltip from '../../vue_shared/directives/tooltip';
import icon from '../../vue_shared/components/icon.vue'; import icon from '../../vue_shared/components/icon.vue';
import PopupDialog from '../../vue_shared/components/popup_dialog.vue'; import modal from '../../vue_shared/components/modal.vue';
import commitFilesList from './commit_sidebar/list.vue'; import commitFilesList from './commit_sidebar/list.vue';
export default { export default {
components: { components: {
PopupDialog, modal,
icon, icon,
commitFilesList, commitFilesList,
}, },
...@@ -16,7 +16,7 @@ export default { ...@@ -16,7 +16,7 @@ export default {
}, },
data() { data() {
return { return {
showNewBranchDialog: false, showNewBranchModal: false,
submitCommitsLoading: false, submitCommitsLoading: false,
startNewMR: false, startNewMR: false,
commitMessage: '', commitMessage: '',
...@@ -58,7 +58,7 @@ export default { ...@@ -58,7 +58,7 @@ export default {
start_branch: createNewBranch ? this.currentBranch : undefined, start_branch: createNewBranch ? this.currentBranch : undefined,
}; };
this.showNewBranchDialog = false; this.showNewBranchModal = false;
this.submitCommitsLoading = true; this.submitCommitsLoading = true;
this.commitChanges({ payload, newMr: this.startNewMR }) this.commitChanges({ payload, newMr: this.startNewMR })
...@@ -76,7 +76,7 @@ export default { ...@@ -76,7 +76,7 @@ export default {
this.checkCommitStatus() this.checkCommitStatus()
.then((branchChanged) => { .then((branchChanged) => {
if (branchChanged) { if (branchChanged) {
this.showNewBranchDialog = true; this.showNewBranchModal = true;
} else { } else {
this.makeCommit(); this.makeCommit();
} }
...@@ -99,13 +99,13 @@ export default { ...@@ -99,13 +99,13 @@ export default {
'is-collapsed': collapsed, 'is-collapsed': collapsed,
}" }"
> >
<popup-dialog <modal
v-if="showNewBranchDialog" v-if="showNewBranchModal"
:primary-button-label="__('Create new branch')" :primary-button-label="__('Create new branch')"
kind="primary" kind="primary"
:title="__('Branch has changed')" :title="__('Branch has changed')"
:text="__('This branch has changed since you started editing. Would you like to create a new branch?')" :text="__('This branch has changed since you started editing. Would you like to create a new branch?')"
@toggle="showNewBranchDialog = false" @toggle="showNewBranchModal = false"
@submit="makeCommit(true)" @submit="makeCommit(true)"
/> />
<button <button
......
<script> <script>
import { mapGetters, mapActions, mapState } from 'vuex'; import { mapGetters, mapActions, mapState } from 'vuex';
import popupDialog from '../../vue_shared/components/popup_dialog.vue'; import modal from '../../vue_shared/components/modal.vue';
export default { export default {
components: { components: {
popupDialog, modal,
}, },
computed: { computed: {
...mapState([ ...mapState([
...@@ -43,7 +43,7 @@ export default { ...@@ -43,7 +43,7 @@ export default {
{{buttonLabel}} {{buttonLabel}}
</span> </span>
</button> </button>
<popup-dialog <modal
v-if="discardPopupOpen" v-if="discardPopupOpen"
class="text-left" class="text-left"
:primary-button-label="__('Discard changes')" :primary-button-label="__('Discard changes')"
......
...@@ -79,7 +79,7 @@ export default class Search { ...@@ -79,7 +79,7 @@ export default class Search {
.on('keyup', this.searchInput, this.searchKeyUp); .on('keyup', this.searchInput, this.searchKeyUp);
$(document) $(document)
.off('click', this.searchClear) .off('click', this.searchClear)
.on('click', this.searchClear, this.clearSearchField); .on('click', this.searchClear, this.clearSearchField.bind(this));
} }
static submitSearch() { static submitSearch() {
......
<script> <script>
export default { export default {
name: 'popup-dialog', name: 'modal',
props: { props: {
title: { title: {
...@@ -75,7 +75,7 @@ export default { ...@@ -75,7 +75,7 @@ export default {
<template> <template>
<div class="modal-open"> <div class="modal-open">
<div <div
class="modal popup-dialog" class="modal show"
role="dialog" role="dialog"
tabindex="-1" tabindex="-1"
> >
......
<script> <script>
import PopupDialog from './popup_dialog.vue'; import modal from './modal.vue';
export default { export default {
name: 'recaptcha-dialog', name: 'recaptcha-modal',
props: { props: {
html: { html: {
...@@ -20,7 +20,7 @@ export default { ...@@ -20,7 +20,7 @@ export default {
}, },
components: { components: {
PopupDialog, modal,
}, },
methods: { methods: {
...@@ -65,9 +65,9 @@ export default { ...@@ -65,9 +65,9 @@ export default {
</script> </script>
<template> <template>
<popup-dialog <modal
kind="warning" kind="warning"
class="recaptcha-dialog js-recaptcha-dialog" class="recaptcha-modal js-recaptcha-modal"
:hide-footer="true" :hide-footer="true"
:title="__('Please solve the reCAPTCHA')" :title="__('Please solve the reCAPTCHA')"
@toggle="close" @toggle="close"
...@@ -81,5 +81,5 @@ export default { ...@@ -81,5 +81,5 @@ export default {
v-html="html" v-html="html"
></div> ></div>
</div> </div>
</popup-dialog> </modal>
</template> </template>
import RecaptchaDialog from '../components/recaptcha_dialog.vue'; import recaptchaModal from '../components/recaptcha_modal.vue';
export default { export default {
data() { data() {
...@@ -9,7 +9,7 @@ export default { ...@@ -9,7 +9,7 @@ export default {
}, },
components: { components: {
RecaptchaDialog, recaptchaModal,
}, },
methods: { methods: {
......
...@@ -19,6 +19,13 @@ ...@@ -19,6 +19,13 @@
max-width: 425px; max-width: 425px;
width: 100%; width: 100%;
} }
&.svg-250 {
img,
svg {
width: 250px;
}
}
} }
@mixin svg-size($size) { @mixin svg-size($size) {
......
...@@ -24,10 +24,14 @@ ...@@ -24,10 +24,14 @@
font-size: $gl-font-size; font-size: $gl-font-size;
line-height: 25px; line-height: 25px;
&.status-box-closed { &.status-box-mr-closed {
background-color: $gl-danger; background-color: $gl-danger;
} }
&.status-box-issue-closed {
background-color: $gl-primary;
}
&.status-box-merged { &.status-box-merged {
background-color: $gl-primary; background-color: $gl-primary;
} }
......
...@@ -44,11 +44,18 @@ body.modal-open { ...@@ -44,11 +44,18 @@ body.modal-open {
} }
} }
.modal.popup-dialog { .modal {
display: block; background-color: $black-transparent;
z-index: 2100;
@media (min-width: $screen-md-min) {
.modal-dialog {
margin: 30px auto;
}
}
} }
.recaptcha-dialog .recaptcha-form { .recaptcha-modal .recaptcha-form {
display: inline-block; display: inline-block;
.recaptcha { .recaptcha {
......
...@@ -610,11 +610,19 @@ ...@@ -610,11 +610,19 @@
} }
.issuable-status-box { .issuable-status-box {
float: none; align-self: stretch;
display: inline-block; display: flex;
justify-content: center;
align-items: center;
margin-top: 0; margin-top: 0;
padding-left: 9px;
padding-right: 9px;
@media (min-width: $screen-sm-min) {
display: inline-block;
height: auto; height: auto;
align-self: center; align-self: center;
}
} }
.issuable-gutter-toggle { .issuable-gutter-toggle {
......
.modal.popup-dialog {
display: block;
background-color: $black-transparent;
z-index: 2100;
@media (min-width: $screen-md-min) {
.modal-dialog {
width: 600px;
margin: 30px auto;
}
}
}
.project-refs-form, .project-refs-form,
.project-refs-target-form { .project-refs-target-form {
display: inline-block; display: inline-block;
......
class Admin::GroupsController < Admin::ApplicationController class Admin::GroupsController < Admin::ApplicationController
include MembersPresentation include MembersPresentation
prepend EE::Admin::GroupsController prepend EE::Admin::GroupsController
before_action :group, only: [:edit, :update, :destroy, :project_update, :members_update] before_action :group, only: [:edit, :update, :destroy, :project_update, :members_update]
......
...@@ -6,6 +6,7 @@ module WithPerformanceBar ...@@ -6,6 +6,7 @@ module WithPerformanceBar
end end
def peek_enabled? def peek_enabled?
return true if Rails.env.development?
return false unless Gitlab::PerformanceBar.enabled?(current_user) return false unless Gitlab::PerformanceBar.enabled?(current_user)
if RequestStore.active? if RequestStore.active?
......
...@@ -118,18 +118,22 @@ module BlobHelper ...@@ -118,18 +118,22 @@ module BlobHelper
icon("#{file_type_icon_class('file', mode, name)} fw") icon("#{file_type_icon_class('file', mode, name)} fw")
end end
def blob_raw_path def blob_raw_url(only_path: false)
if @build && @entry if @build && @entry
raw_project_job_artifacts_path(@project, @build, path: @entry.path) raw_project_job_artifacts_url(@project, @build, path: @entry.path, only_path: only_path)
elsif @snippet elsif @snippet
if @snippet.project_id if @snippet.project_id
raw_project_snippet_path(@project, @snippet) raw_project_snippet_url(@project, @snippet, only_path: only_path)
else else
raw_snippet_path(@snippet) raw_snippet_url(@snippet, only_path: only_path)
end end
elsif @blob elsif @blob
project_raw_path(@project, @id) project_raw_url(@project, @id, only_path: only_path)
end
end end
def blob_raw_path
blob_raw_url(only_path: true)
end end
# SVGs can contain malicious JavaScript; only include whitelisted # SVGs can contain malicious JavaScript; only include whitelisted
......
...@@ -104,15 +104,23 @@ module DiffHelper ...@@ -104,15 +104,23 @@ module DiffHelper
].join(' ').html_safe ].join(' ').html_safe
end end
def diff_file_blob_raw_path(diff_file) def diff_file_blob_raw_url(diff_file, only_path: false)
project_raw_path(@project, tree_join(diff_file.content_sha, diff_file.file_path)) project_raw_url(@project, tree_join(diff_file.content_sha, diff_file.file_path), only_path: only_path)
end end
def diff_file_old_blob_raw_path(diff_file) def diff_file_old_blob_raw_url(diff_file, only_path: false)
sha = diff_file.old_content_sha sha = diff_file.old_content_sha
return unless sha return unless sha
project_raw_path(@project, tree_join(diff_file.old_content_sha, diff_file.old_path)) project_raw_url(@project, tree_join(diff_file.old_content_sha, diff_file.old_path), only_path: only_path)
end
def diff_file_blob_raw_path(diff_file)
diff_file_blob_raw_url(diff_file, only_path: true)
end
def diff_file_old_blob_raw_path(diff_file)
diff_file_old_blob_raw_url(diff_file, only_path: true)
end end
def diff_file_html_data(project, diff_file_path, diff_commit_id) def diff_file_html_data(project, diff_file_path, diff_commit_id)
......
...@@ -76,7 +76,7 @@ module IssuesHelper ...@@ -76,7 +76,7 @@ module IssuesHelper
elsif item.try(:merged?) elsif item.try(:merged?)
'status-box-merged' 'status-box-merged'
elsif item.closed? elsif item.closed?
'status-box-closed' 'status-box-mr-closed'
elsif item.try(:upcoming?) elsif item.try(:upcoming?)
'status-box-upcoming' 'status-box-upcoming'
else else
......
module LabelsHelper module LabelsHelper
include ActionView::Helpers::TagHelper include ActionView::Helpers::TagHelper
def show_label_issuables_link?(label, issuables_type, current_user: nil, project: nil)
return true if label.is_a?(GroupLabel)
return true unless project
project.feature_available?(issuables_type, current_user)
end
# Link to a Label # Link to a Label
# #
# label - Label object to link to # label - Label object to link to
......
...@@ -5,7 +5,7 @@ module Emails ...@@ -5,7 +5,7 @@ module Emails
@commit = @note.noteable @commit = @note.noteable
@target_url = project_commit_url(*note_target_url_options) @target_url = project_commit_url(*note_target_url_options)
mail_answer_thread(@commit, note_thread_options(recipient_id)) mail_answer_note_thread(@commit, @note, note_thread_options(recipient_id))
end end
def note_issue_email(recipient_id, note_id) def note_issue_email(recipient_id, note_id)
...@@ -13,7 +13,7 @@ module Emails ...@@ -13,7 +13,7 @@ module Emails
@issue = @note.noteable @issue = @note.noteable
@target_url = project_issue_url(*note_target_url_options) @target_url = project_issue_url(*note_target_url_options)
mail_answer_thread(@issue, note_thread_options(recipient_id)) mail_answer_note_thread(@issue, @note, note_thread_options(recipient_id))
end end
def note_merge_request_email(recipient_id, note_id) def note_merge_request_email(recipient_id, note_id)
...@@ -21,7 +21,7 @@ module Emails ...@@ -21,7 +21,7 @@ module Emails
@merge_request = @note.noteable @merge_request = @note.noteable
@target_url = project_merge_request_url(*note_target_url_options) @target_url = project_merge_request_url(*note_target_url_options)
mail_answer_thread(@merge_request, note_thread_options(recipient_id)) mail_answer_note_thread(@merge_request, @note, note_thread_options(recipient_id))
end end
def note_snippet_email(recipient_id, note_id) def note_snippet_email(recipient_id, note_id)
...@@ -29,7 +29,7 @@ module Emails ...@@ -29,7 +29,7 @@ module Emails
@snippet = @note.noteable @snippet = @note.noteable
@target_url = project_snippet_url(*note_target_url_options) @target_url = project_snippet_url(*note_target_url_options)
mail_answer_thread(@snippet, note_thread_options(recipient_id)) mail_answer_note_thread(@snippet, @note, note_thread_options(recipient_id))
end end
def note_personal_snippet_email(recipient_id, note_id) def note_personal_snippet_email(recipient_id, note_id)
...@@ -37,7 +37,7 @@ module Emails ...@@ -37,7 +37,7 @@ module Emails
@snippet = @note.noteable @snippet = @note.noteable
@target_url = snippet_url(@note.noteable) @target_url = snippet_url(@note.noteable)
mail_answer_thread(@snippet, note_thread_options(recipient_id)) mail_answer_note_thread(@snippet, @note, note_thread_options(recipient_id))
end end
private private
......
...@@ -123,8 +123,8 @@ class Notify < BaseMailer ...@@ -123,8 +123,8 @@ class Notify < BaseMailer
headers['Reply-To'] = address headers['Reply-To'] = address
fallback_reply_message_id = "<reply-#{reply_key}@#{Gitlab.config.gitlab.host}>".freeze fallback_reply_message_id = "<reply-#{reply_key}@#{Gitlab.config.gitlab.host}>".freeze
headers['References'] ||= '' headers['References'] ||= []
headers['References'] << ' ' << fallback_reply_message_id headers['References'] << fallback_reply_message_id
@reply_by_email = true @reply_by_email = true
end end
...@@ -160,6 +160,18 @@ class Notify < BaseMailer ...@@ -160,6 +160,18 @@ class Notify < BaseMailer
mail_thread(model, headers) mail_thread(model, headers)
end end
def mail_answer_note_thread(model, note, headers = {})
headers['Message-ID'] = message_id(note)
headers['In-Reply-To'] = message_id(note.references.last)
headers['References'] = note.references.map { |ref| message_id(ref) }
headers['X-GitLab-Discussion-ID'] = note.discussion.id if note.part_of_discussion?
headers[:subject]&.prepend('Re: ')
mail_thread(model, headers)
end
def reply_key def reply_key
@reply_key ||= SentNotification.reply_key @reply_key ||= SentNotification.reply_key
end end
......
...@@ -501,7 +501,6 @@ module Ci ...@@ -501,7 +501,6 @@ module Ci
end end
def valid_dependency? def valid_dependency?
return false unless complete?
return false if artifacts_expired? return false if artifacts_expired?
return false if erased? return false if erased?
......
...@@ -52,6 +52,20 @@ class Commit ...@@ -52,6 +52,20 @@ class Commit
diffs.reduce(0) { |sum, d| sum + Gitlab::Git::Util.count_lines(d.diff) } diffs.reduce(0) { |sum, d| sum + Gitlab::Git::Util.count_lines(d.diff) }
end end
def order_by(collection:, order_by:, sort:)
return collection unless %w[email name commits].include?(order_by)
return collection unless %w[asc desc].include?(sort)
collection.sort do |a, b|
operands = [a, b].tap { |o| o.reverse! if sort == 'desc' }
attr1, attr2 = operands.first.public_send(order_by), operands.second.public_send(order_by) # rubocop:disable PublicSend
# use case insensitive comparison for string values
order_by.in?(%w[email name]) ? attr1.casecmp(attr2) : attr1 <=> attr2
end
end
# Truncate sha to 8 characters # Truncate sha to 8 characters
def truncate_sha(sha) def truncate_sha(sha)
sha[0..MIN_SHA_LENGTH] sha[0..MIN_SHA_LENGTH]
......
...@@ -85,8 +85,7 @@ module CacheMarkdownField ...@@ -85,8 +85,7 @@ module CacheMarkdownField
def cached_html_up_to_date?(markdown_field) def cached_html_up_to_date?(markdown_field)
html_field = cached_markdown_fields.html_field(markdown_field) html_field = cached_markdown_fields.html_field(markdown_field)
cached = cached_html_for(markdown_field).present? && __send__(markdown_field).present? # rubocop:disable GitlabSecurity/PublicSend return false if cached_html_for(markdown_field).nil? && !__send__(markdown_field).nil? # rubocop:disable GitlabSecurity/PublicSend
return false unless cached
markdown_changed = attribute_changed?(markdown_field) || false markdown_changed = attribute_changed?(markdown_field) || false
html_changed = attribute_changed?(html_field) || false html_changed = attribute_changed?(html_field) || false
......
...@@ -16,7 +16,7 @@ class Issue < ActiveRecord::Base ...@@ -16,7 +16,7 @@ class Issue < ActiveRecord::Base
include ThrottledTouch include ThrottledTouch
include IgnorableColumn include IgnorableColumn
ignore_column :assignee_id ignore_column :assignee_id, :branch_name
WEIGHT_RANGE = 1..9 WEIGHT_RANGE = 1..9
WEIGHT_ALL = 'Everything'.freeze WEIGHT_ALL = 'Everything'.freeze
......
...@@ -913,11 +913,11 @@ class MergeRequest < ActiveRecord::Base ...@@ -913,11 +913,11 @@ class MergeRequest < ActiveRecord::Base
def state_icon_name def state_icon_name
if merged? if merged?
"check" "git-merge"
elsif closed? elsif closed?
"times" "close"
else else
"circle-o" "issue-open-m"
end end
end end
......
...@@ -368,6 +368,16 @@ class Note < ActiveRecord::Base ...@@ -368,6 +368,16 @@ class Note < ActiveRecord::Base
end end
end end
def references
refs = [noteable]
if part_of_discussion?
refs += discussion.notes.take_while { |n| n.id < id }
end
refs
end
def expire_etag_cache def expire_etag_cache
return unless noteable&.discussions_rendered_on_frontend? return unless noteable&.discussions_rendered_on_frontend?
...@@ -409,6 +419,9 @@ class Note < ActiveRecord::Base ...@@ -409,6 +419,9 @@ class Note < ActiveRecord::Base
end end
noteable_object&.touch noteable_object&.touch
# We return the noteable object so we can re-use it in EE for ElasticSearch.
noteable_object
end end
def banzai_render_context(field) def banzai_render_context(field)
......
...@@ -669,7 +669,8 @@ class Project < ActiveRecord::Base ...@@ -669,7 +669,8 @@ class Project < ActiveRecord::Base
end end
def import_started? def import_started?
import? && import_status == 'started' # import? does SQL work so only run it if it looks like there's an import running
import_status == 'started' && import?
end end
def import_scheduled? def import_scheduled?
...@@ -1157,7 +1158,7 @@ class Project < ActiveRecord::Base ...@@ -1157,7 +1158,7 @@ class Project < ActiveRecord::Base
def change_head(branch) def change_head(branch)
if repository.branch_exists?(branch) if repository.branch_exists?(branch)
repository.before_change_head repository.before_change_head
repository.write_ref('HEAD', "refs/heads/#{branch}") repository.write_ref('HEAD', "refs/heads/#{branch}", force: true)
repository.copy_gitattributes(branch) repository.copy_gitattributes(branch)
repository.after_change_head repository.after_change_head
reload_default_branch reload_default_branch
......
...@@ -24,6 +24,7 @@ class Repository ...@@ -24,6 +24,7 @@ class Repository
attr_accessor :full_path, :disk_path, :project, :is_wiki attr_accessor :full_path, :disk_path, :project, :is_wiki
delegate :ref_name_for_sha, to: :raw_repository delegate :ref_name_for_sha, to: :raw_repository
delegate :write_ref, to: :raw_repository
CreateTreeError = Class.new(StandardError) CreateTreeError = Class.new(StandardError)
...@@ -244,11 +245,10 @@ class Repository ...@@ -244,11 +245,10 @@ class Repository
# This will still fail if the file is corrupted (e.g. 0 bytes) # This will still fail if the file is corrupted (e.g. 0 bytes)
begin begin
write_ref(keep_around_ref_name(sha), sha) write_ref(keep_around_ref_name(sha), sha, force: true)
rescue Rugged::ReferenceError => ex rescue Gitlab::Git::Repository::GitError => ex
Rails.logger.error "Unable to create #{REF_KEEP_AROUND} reference for repository #{path}: #{ex}" # Necessary because https://gitlab.com/gitlab-org/gitlab-ce/issues/20156
rescue Rugged::OSError => ex return true if ex.message =~ /Failed to create locked file/ && ex.message =~ /File exists/
raise unless ex.message =~ /Failed to create locked file/ && ex.message =~ /File exists/
Rails.logger.error "Unable to create #{REF_KEEP_AROUND} reference for repository #{path}: #{ex}" Rails.logger.error "Unable to create #{REF_KEEP_AROUND} reference for repository #{path}: #{ex}"
end end
...@@ -258,10 +258,6 @@ class Repository ...@@ -258,10 +258,6 @@ class Repository
ref_exists?(keep_around_ref_name(sha)) ref_exists?(keep_around_ref_name(sha))
end end
def write_ref(ref_path, sha)
rugged.references.create(ref_path, sha, force: true)
end
def diverging_commit_counts(branch) def diverging_commit_counts(branch)
root_ref_hash = raw_repository.commit(root_ref).id root_ref_hash = raw_repository.commit(root_ref).id
cache.fetch(:"diverging_commit_counts_#{branch.name}") do cache.fetch(:"diverging_commit_counts_#{branch.name}") do
...@@ -697,7 +693,9 @@ class Repository ...@@ -697,7 +693,9 @@ class Repository
def tags_sorted_by(value) def tags_sorted_by(value)
case value case value
when 'name' when 'name_asc'
VersionSorter.sort(tags) { |tag| tag.name }
when 'name_desc'
VersionSorter.rsort(tags) { |tag| tag.name } VersionSorter.rsort(tags) { |tag| tag.name }
when 'updated_desc' when 'updated_desc'
tags_sorted_by_committed_date.reverse tags_sorted_by_committed_date.reverse
...@@ -708,10 +706,14 @@ class Repository ...@@ -708,10 +706,14 @@ class Repository
end end
end end
def contributors # Params:
#
# order_by: name|email|commits
# sort: asc|desc default: 'asc'
def contributors(order_by: nil, sort: 'asc')
commits = self.commits(nil, limit: 2000, offset: 0, skip_merges: true) commits = self.commits(nil, limit: 2000, offset: 0, skip_merges: true)
commits.group_by(&:author_email).map do |email, commits| commits = commits.group_by(&:author_email).map do |email, commits|
contributor = Gitlab::Contributor.new contributor = Gitlab::Contributor.new
contributor.email = email contributor.email = email
...@@ -725,6 +727,7 @@ class Repository ...@@ -725,6 +727,7 @@ class Repository
contributor contributor
end end
Commit.order_by(collection: commits, order_by: order_by, sort: sort)
end end
def refs_contains_sha(ref_type, sha) def refs_contains_sha(ref_type, sha)
...@@ -1043,7 +1046,7 @@ class Repository ...@@ -1043,7 +1046,7 @@ class Repository
end end
def create_ref(ref, ref_path) def create_ref(ref, ref_path)
raw_repository.write_ref(ref_path, ref) write_ref(ref_path, ref)
end end
def ls_files(ref) def ls_files(ref)
......
...@@ -39,11 +39,15 @@ module Ci ...@@ -39,11 +39,15 @@ module Ci
begin begin
# In case when 2 runners try to assign the same build, second runner will be declined # In case when 2 runners try to assign the same build, second runner will be declined
# with StateMachines::InvalidTransition or StaleObjectError when doing run! or save method. # with StateMachines::InvalidTransition or StaleObjectError when doing run! or save method.
begin
build.runner_id = runner.id build.runner_id = runner.id
build.run! build.run!
register_success(build) register_success(build)
return Result.new(build, true) return Result.new(build, true)
rescue Ci::Build::MissingDependenciesError
build.drop!(:missing_dependency_failure)
end
rescue StateMachines::InvalidTransition, ActiveRecord::StaleObjectError rescue StateMachines::InvalidTransition, ActiveRecord::StaleObjectError
# We are looping to find another build that is not conflicting # We are looping to find another build that is not conflicting
# It also indicates that this build can be picked and passed to runner. # It also indicates that this build can be picked and passed to runner.
...@@ -55,9 +59,6 @@ module Ci ...@@ -55,9 +59,6 @@ module Ci
# we still have to return 409 in the end, # we still have to return 409 in the end,
# to make sure that this is properly handled by runner. # to make sure that this is properly handled by runner.
valid = false valid = false
rescue Ci::Build::MissingDependenciesError
build.drop!(:missing_dependency_failure)
valid = false
end end
end end
......
...@@ -108,12 +108,14 @@ class IssuableBaseService < BaseService ...@@ -108,12 +108,14 @@ class IssuableBaseService < BaseService
end end
def merge_quick_actions_into_params!(issuable) def merge_quick_actions_into_params!(issuable)
original_description = params.fetch(:description, issuable.description)
description, command_params = description, command_params =
QuickActions::InterpretService.new(project, current_user) QuickActions::InterpretService.new(project, current_user)
.execute(params[:description], issuable) .execute(original_description, issuable)
# Avoid a description already set on an issuable to be overwritten by a nil # Avoid a description already set on an issuable to be overwritten by a nil
params[:description] = description if params.key?(:description) params[:description] = description if description
params.merge!(command_params) params.merge!(command_params)
end end
......
...@@ -83,12 +83,12 @@ ...@@ -83,12 +83,12 @@
You're all done! You're all done!
- elsif current_user.todos.any? - elsif current_user.todos.any?
.todos-all-done .todos-all-done
.svg-content .svg-content.svg-250
= image_tag 'illustrations/todos_all_done.svg' = image_tag 'illustrations/todos_all_done.svg'
- if todos_filter_empty? - if todos_filter_empty?
%h4.text-center %h4.text-center
= Gitlab.config.gitlab.no_todos_messages.sample = Gitlab.config.gitlab.no_todos_messages.sample
%p.text-center %p
Are you looking for things to do? Take a look at Are you looking for things to do? Take a look at
= succeed "," do = succeed "," do
= link_to "the opened issues", issues_dashboard_path = link_to "the opened issues", issues_dashboard_path
...@@ -104,7 +104,7 @@ ...@@ -104,7 +104,7 @@
= image_tag 'illustrations/todos_empty.svg' = image_tag 'illustrations/todos_empty.svg'
.todos-empty-content .todos-empty-content
%h4 %h4
Todos let you see what you should do next. Todos let you see what you should do next
%p %p
When an issue or merge request is assigned to you, or when you When an issue or merge request is assigned to you, or when you
%strong %strong
......
- project_meta = { id: @project.id, name: @project.name, namespace: @project.name_with_namespace, web_url: @project.web_url, avatar_url: @project.avatar_url } if @project&.persisted? - project_meta = { id: @project.id, name: @project.name, namespace: @project.name_with_namespace, web_url: project_path(@project), avatar_url: @project.avatar_url } if @project&.persisted?
.projects-dropdown-container .projects-dropdown-container
.project-dropdown-sidebar .project-dropdown-sidebar
%ul %ul
......
.file-content.image_file .file-content.image_file
= image_tag(blob_raw_path, alt: viewer.blob.name) -# Uses the full URL rather than the path, to prevent it from getting prefixed with the asset host.
= image_tag(blob_raw_url, alt: viewer.blob.name)
.row.empty-state .row.empty-state
.col-xs-12 .col-xs-12
.svg-content= image_tag 'illustrations/clusters_empty.svg' .svg-content= image_tag 'illustrations/clusters_empty.svg'
.col-xs-12.text-center .col-xs-12
.text-content .text-content
%h4= s_('ClusterIntegration|Integrate cluster automation') %h4.text-center= s_('ClusterIntegration|Integrate cluster automation')
- link_to_help_page = link_to(s_('ClusterIntegration|Learn more about Clusters'), help_page_path('user/project/clusters/index'), target: '_blank', rel: 'noopener noreferrer') - link_to_help_page = link_to(s_('ClusterIntegration|Learn more about Clusters'), help_page_path('user/project/clusters/index'), target: '_blank', rel: 'noopener noreferrer')
%p= s_('ClusterIntegration|Clusters allow you to use review apps, deploy your applications, run your pipelines, and much more in an easy way. %{link_to_help_page}').html_safe % { link_to_help_page: link_to_help_page} %p= s_('ClusterIntegration|Clusters allow you to use review apps, deploy your applications, run your pipelines, and much more in an easy way. %{link_to_help_page}').html_safe % { link_to_help_page: link_to_help_page}
%p .text-center
= link_to s_('ClusterIntegration|Add cluster'), new_project_cluster_path(@project), class: 'btn btn-success' = link_to s_('ClusterIntegration|Add cluster'), new_project_cluster_path(@project), class: 'btn btn-success'
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
.nav-text .nav-text
= s_("ClusterIntegration|Clusters can be used to deploy applications and to provide Review Apps for this project") = s_("ClusterIntegration|Clusters can be used to deploy applications and to provide Review Apps for this project")
= render 'projects/ee/clusters/buttons', project: @project = render 'projects/ee/clusters/buttons', project: @project
.ci-table.js-clusters-list
.gl-responsive-table-row.table-row-header{ role: "row" } .gl-responsive-table-row.table-row-header{ role: "row" }
.table-section.section-30{ role: "rowheader" } .table-section.section-30{ role: "rowheader" }
= s_("ClusterIntegration|Cluster") = s_("ClusterIntegration|Cluster")
......
- blob = diff_file.blob - blob = diff_file.blob
- old_blob = diff_file.old_blob - old_blob = diff_file.old_blob
- blob_raw_path = diff_file_blob_raw_path(diff_file) - blob_raw_url = diff_file_blob_raw_url(diff_file)
- old_blob_raw_path = diff_file_old_blob_raw_path(diff_file) - old_blob_raw_url = diff_file_old_blob_raw_url(diff_file)
- click_to_comment = local_assigns.fetch(:click_to_comment, true) - click_to_comment = local_assigns.fetch(:click_to_comment, true)
- diff_view_data = local_assigns.fetch(:diff_view_data, '') - diff_view_data = local_assigns.fetch(:diff_view_data, '')
- class_name = '' - class_name = ''
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
.two-up.view .two-up.view
.wrap .wrap
.frame.deleted .frame.deleted
= image_tag(old_blob_raw_path, alt: diff_file.old_path, lazy: false) = image_tag(old_blob_raw_url, alt: diff_file.old_path, lazy: false)
%p.image-info.hide %p.image-info.hide
%span.meta-filesize= number_to_human_size(old_blob.size) %span.meta-filesize= number_to_human_size(old_blob.size)
| |
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
%strong H: %strong H:
%span.meta-height %span.meta-height
.wrap .wrap
= render partial: "projects/diffs/image_diff_frame", locals: { class_name: "added js-image-frame #{class_name}", position: position, note_type: DiffNote.name, image_path: blob_raw_path, alt: diff_file.new_path } = render partial: "projects/diffs/image_diff_frame", locals: { class_name: "added js-image-frame #{class_name}", position: position, note_type: DiffNote.name, image_path: blob_raw_url, alt: diff_file.new_path }
%p.image-info.hide %p.image-info.hide
%span.meta-filesize= number_to_human_size(blob.size) %span.meta-filesize= number_to_human_size(blob.size)
| |
...@@ -36,9 +36,9 @@ ...@@ -36,9 +36,9 @@
.swipe.view.hide .swipe.view.hide
.swipe-frame .swipe-frame
.frame.deleted .frame.deleted
= image_tag(old_blob_raw_path, alt: diff_file.old_path, lazy: false) = image_tag(old_blob_raw_url, alt: diff_file.old_path, lazy: false)
.swipe-wrap .swipe-wrap
= render partial: "projects/diffs/image_diff_frame", locals: { class_name: "added js-image-frame #{class_name}", position: position, note_type: DiffNote.name, image_path: blob_raw_path, alt: diff_file.new_path } = render partial: "projects/diffs/image_diff_frame", locals: { class_name: "added js-image-frame #{class_name}", position: position, note_type: DiffNote.name, image_path: blob_raw_url, alt: diff_file.new_path }
%span.swipe-bar %span.swipe-bar
%span.top-handle %span.top-handle
%span.bottom-handle %span.bottom-handle
...@@ -46,8 +46,8 @@ ...@@ -46,8 +46,8 @@
.onion-skin.view.hide .onion-skin.view.hide
.onion-skin-frame .onion-skin-frame
.frame.deleted .frame.deleted
= image_tag(old_blob_raw_path, alt: diff_file.old_path, lazy: false) = image_tag(old_blob_raw_url, alt: diff_file.old_path, lazy: false)
= render partial: "projects/diffs/image_diff_frame", locals: { class_name: "added js-image-frame #{class_name}", position: position, note_type: DiffNote.name, image_path: blob_raw_path, alt: diff_file.new_path } = render partial: "projects/diffs/image_diff_frame", locals: { class_name: "added js-image-frame #{class_name}", position: position, note_type: DiffNote.name, image_path: blob_raw_url, alt: diff_file.new_path }
.controls .controls
.transparent .transparent
.drag-track .drag-track
......
- blob = diff_file.blob - blob = diff_file.blob
- old_blob = diff_file.old_blob - old_blob = diff_file.old_blob
- blob_raw_path = diff_file_blob_raw_path(diff_file) - blob_raw_url = diff_file_blob_raw_url(diff_file)
- old_blob_raw_path = diff_file_old_blob_raw_path(diff_file) - old_blob_raw_url = diff_file_old_blob_raw_url(diff_file)
- click_to_comment = local_assigns.fetch(:click_to_comment, true) - click_to_comment = local_assigns.fetch(:click_to_comment, true)
- diff_view_data = local_assigns.fetch(:diff_view_data, '') - diff_view_data = local_assigns.fetch(:diff_view_data, '')
- class_name = '' - class_name = ''
...@@ -12,5 +12,5 @@ ...@@ -12,5 +12,5 @@
.image.js-single-image{ data: diff_view_data } .image.js-single-image{ data: diff_view_data }
.wrap .wrap
- single_class_name = diff_file.deleted_file? ? 'deleted' : 'added' - single_class_name = diff_file.deleted_file? ? 'deleted' : 'added'
= render partial: "projects/diffs/image_diff_frame", locals: { class_name: "#{single_class_name} #{class_name} js-image-frame", position: position, note_type: DiffNote.name, image_path: blob_raw_path, alt: diff_file.file_path } = render partial: "projects/diffs/image_diff_frame", locals: { class_name: "#{single_class_name} #{class_name} js-image-frame", position: position, note_type: DiffNote.name, image_path: blob_raw_url, alt: diff_file.file_path }
%p.image-info= number_to_human_size(blob.size) %p.image-info= number_to_human_size(blob.size)
...@@ -17,12 +17,12 @@ ...@@ -17,12 +17,12 @@
.detail-page-header .detail-page-header
.detail-page-header-body .detail-page-header-body
.issuable-status-box.status-box.status-box-closed{ class: issue_button_visibility(@issue, false) } .issuable-status-box.status-box.status-box-issue-closed{ class: issue_button_visibility(@issue, false) }
= icon('check', class: "hidden-sm hidden-md hidden-lg") = sprite_icon('mobile-issue-close', size: 16, css_class: 'hidden-sm hidden-md hidden-lg')
%span.hidden-xs %span.hidden-xs
Closed Closed
.issuable-status-box.status-box.status-box-open{ class: issue_button_visibility(@issue, true) } .issuable-status-box.status-box.status-box-open{ class: issue_button_visibility(@issue, true) }
= icon('circle-o', class: "hidden-sm hidden-md hidden-lg") = sprite_icon('issue-open-m', size: 16, css_class: 'hidden-sm hidden-md hidden-lg')
%span.hidden-xs Open %span.hidden-xs Open
.issuable-meta .issuable-meta
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
.detail-page-header .detail-page-header
.detail-page-header-body .detail-page-header-body
.issuable-status-box.status-box{ class: status_box_class(@merge_request) } .issuable-status-box.status-box{ class: status_box_class(@merge_request) }
= icon(@merge_request.state_icon_name, class: "hidden-sm hidden-md hidden-lg") = sprite_icon(@merge_request.state_icon_name, size: 16, css_class: 'hidden-sm hidden-md hidden-lg')
%span.hidden-xs %span.hidden-xs
= @merge_request.state_human_name = @merge_request.state_human_name
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
.dropdown-menu.dropdown-menu-align-right.hidden-lg .dropdown-menu.dropdown-menu-align-right.hidden-lg
%ul %ul
- if can_update_merge_request - if can_update_merge_request
%li= link_to 'Edit', edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: 'js-issuable-edit' %li= link_to 'Edit', edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)
- unless current_user == @merge_request.author - unless current_user == @merge_request.author
%li= link_to 'Report abuse', new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request)) %li= link_to 'Report abuse', new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request))
- if can_update_merge_request - if can_update_merge_request
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
.form-group .form-group
= label_tag :tag_name, nil, class: 'control-label' = label_tag :tag_name, nil, class: 'control-label'
.col-sm-10 .col-sm-10
= text_field_tag :tag_name, params[:tag_name], required: true, tabindex: 1, autofocus: true, class: 'form-control' = text_field_tag :tag_name, params[:tag_name], required: true, autofocus: true, class: 'form-control'
.form-group .form-group
= label_tag :ref, 'Create from', class: 'control-label' = label_tag :ref, 'Create from', class: 'control-label'
.col-sm-10.create-from .col-sm-10.create-from
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
.form-group .form-group
= label_tag :message, nil, class: 'control-label' = label_tag :message, nil, class: 'control-label'
.col-sm-10 .col-sm-10
= text_area_tag :message, @message, required: false, tabindex: 3, class: 'form-control', rows: 5 = text_area_tag :message, @message, required: false, class: 'form-control', rows: 5
.help-block .help-block
= s_('TagsPage|Optionally, add a message to the tag.') = s_('TagsPage|Optionally, add a message to the tag.')
%hr %hr
...@@ -41,6 +41,6 @@ ...@@ -41,6 +41,6 @@
.help-block .help-block
= s_('TagsPage|Optionally, add release notes to the tag. They will be stored in the GitLab database and displayed on the tags page.') = s_('TagsPage|Optionally, add release notes to the tag. They will be stored in the GitLab database and displayed on the tags page.')
.form-actions .form-actions
= button_tag s_('TagsPage|Create tag'), class: 'btn btn-create', tabindex: 3 = button_tag s_('TagsPage|Create tag'), class: 'btn btn-create'
= link_to s_('TagsPage|Cancel'), project_tags_path(@project), class: 'btn btn-cancel' = link_to s_('TagsPage|Cancel'), project_tags_path(@project), class: 'btn btn-cancel'
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe %script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
- status = label_subscription_status(label, @project).inquiry if current_user - status = label_subscription_status(label, @project).inquiry if current_user
- subject = local_assigns[:subject] - subject = local_assigns[:subject]
- toggle_subscription_path = toggle_subscription_label_path(label, @project) if current_user - toggle_subscription_path = toggle_subscription_label_path(label, @project) if current_user
- show_label_merge_requests_link = show_label_issuables_link?(label, :merge_requests, project: @project)
- show_label_issues_link = show_label_issuables_link?(label, :issues, project: @project)
%li{ id: label_css_id, data: { id: label.id } } %li{ id: label_css_id, data: { id: label.id } }
= render "shared/label_row", label: label = render "shared/label_row", label: label
...@@ -12,9 +14,11 @@ ...@@ -12,9 +14,11 @@
= icon('caret-down') = icon('caret-down')
.dropdown-menu.dropdown-menu-align-right .dropdown-menu.dropdown-menu-align-right
%ul %ul
- if show_label_merge_requests_link
%li %li
= link_to_label(label, subject: subject, type: :merge_request) do = link_to_label(label, subject: subject, type: :merge_request) do
View merge requests View merge requests
- if show_label_issues_link
%li %li
= link_to_label(label, subject: subject) do = link_to_label(label, subject: subject) do
View open issues View open issues
...@@ -43,8 +47,10 @@ ...@@ -43,8 +47,10 @@
class: 'text-danger' class: 'text-danger'
.pull-right.hidden-xs.hidden-sm.hidden-md .pull-right.hidden-xs.hidden-sm.hidden-md
- if show_label_merge_requests_link
= link_to_label(label, subject: subject, type: :merge_request, css_class: 'btn btn-transparent btn-action btn-link') do = link_to_label(label, subject: subject, type: :merge_request, css_class: 'btn btn-transparent btn-action btn-link') do
view merge requests view merge requests
- if show_label_issues_link
= link_to_label(label, subject: subject, css_class: 'btn btn-transparent btn-action btn-link') do = link_to_label(label, subject: subject, css_class: 'btn btn-transparent btn-action btn-link') do
view open issues view open issues
......
...@@ -6,18 +6,21 @@ ...@@ -6,18 +6,21 @@
.col-xs-12 .col-xs-12
.svg-content .svg-content
= image_tag 'illustrations/issues.svg' = image_tag 'illustrations/issues.svg'
.col-xs-12.text-center .col-xs-12
.text-content .text-content
- if has_button && current_user - if has_button && current_user
%h4 %h4
The Issue Tracker is the place to add things that need to be improved or solved in a project = _("The Issue Tracker is the place to add things that need to be improved or solved in a project")
%p %p
Issues can be bugs, tasks or ideas to be discussed. = _("Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable.")
Also, issues are searchable and filterable. .text-center
- if project_select_button - if project_select_button
= render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue', type: :issues = render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue', type: :issues
- else - else
= link_to 'New issue', button_path, class: 'btn btn-new', title: 'New issue', id: 'new_issue_link' = link_to 'New issue', button_path, class: 'btn btn-success', title: 'New issue', id: 'new_issue_link'
- else - else
%h4.text-center= _("There are no issues to show")
%p
= _("The Issue Tracker is the place to add things that need to be improved or solved in a project. You can register or sign in to create issues for this project.")
.text-center .text-center
%h4 There are no issues to show. = link_to _('Register / Sign In'), new_user_session_path, class: 'btn btn-success'
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
.col-xs-12 .col-xs-12
.svg-content .svg-content
= image_tag 'illustrations/labels.svg' = image_tag 'illustrations/labels.svg'
.col-xs-12.text-center .col-xs-12
.text-content .text-content
%h4 Labels can be applied to issues and merge requests to categorize them. %h4= _("Labels can be applied to issues and merge requests to categorize them.")
%p You can also star a label to make it a priority label. %p= _("You can also star a label to make it a priority label.")
- if can?(current_user, :admin_label, @project) - if can?(current_user, :admin_label, @project)
= link_to 'New label', new_project_label_path(@project), class: 'btn btn-new', title: 'New label', id: 'new_label_link' = link_to _('New label'), new_project_label_path(@project), class: 'btn btn-new', title: _('New label'), id: 'new_label_link'
= link_to 'Generate a default set of labels', generate_project_labels_path(@project), method: :post, class: 'btn btn-success btn-inverted', title: 'Generate a default set of labels', id: 'generate_labels_link' = link_to _('Generate a default set of labels'), generate_project_labels_path(@project), method: :post, class: 'btn btn-success btn-inverted', title: _('Generate a default set of labels'), id: 'generate_labels_link'
...@@ -6,17 +6,18 @@ ...@@ -6,17 +6,18 @@
.col-xs-12 .col-xs-12
.svg-content .svg-content
= image_tag 'illustrations/merge_requests.svg' = image_tag 'illustrations/merge_requests.svg'
.col-xs-12.text-center .col-xs-12
.text-content .text-content
- if has_button - if has_button
%h4 %h4
Merge requests are a place to propose changes you've made to a project and discuss those changes with others. = _("Merge requests are a place to propose changes you've made to a project and discuss those changes with others")
%p %p
Interested parties can even contribute by pushing commits if they want to. = _("Interested parties can even contribute by pushing commits if they want to.")
.text-center
- if project_select_button - if project_select_button
= render 'shared/new_project_item_select', path: 'merge_requests/new', label: 'New merge request', type: :merge_requests = render 'shared/new_project_item_select', path: 'merge_requests/new', label: _('New merge request'), type: :merge_requests
- else - else
= link_to 'New merge request', button_path, class: 'btn btn-new', title: 'New merge request', id: 'new_merge_request_link' = link_to _('New merge request'), button_path, class: 'btn btn-new', title: _('New merge request'), id: 'new_merge_request_link'
- else - else
%h4.text-center %h4.text-center
There are no merge requests to show. = _("There are no merge requests to show")
---
title: Adds ordering to projects contributors in API
merge_request: 15469
author: Jacopo Beschi @jacopo-beschi
type: added
---
title: Update issuable status icons
merge_request: 15898
author:
type: changed
---
title: Fix broken illustration images for monitoring page empty states
merge_request: 15889
author:
type: fixed
---
title: add support for sorting in tags api
merge_request: 15772
author: haseebeqx
type: added
---
title: Use relative URL for projects to avoid storing domains
merge_request: 15876
author:
type: fixed
---
title: Add a gitlab:tcp_check rake task
merge_request: 15759
author:
type: added
---
title: Use app host instead of asset host when rendering image blob or diff
merge_request:
author:
type: fixed
---
title: Execute quick actions (if present) when creating MR from issue
merge_request: 15810
author:
type: fixed
---
title: Fixed typo for issue description field declaration
merge_request:
author: Marcus Amargi
type: fixed
---
title: Treat empty markdown and html strings as valid cached text, not missing cache
that needs to be updated
merge_request:
author:
type: performance
---
title: check the import_status field before doing SQL operations to check the import
url
merge_request:
author:
type: performance
---
title: removed tabindexes from tag form
merge_request:
author: Marcus Amargi
type: changed
---
title: Hide link to issues/MRs from labels list if issues/MRs are disabled.
merge_request: 15863
author: Sophie Herold
type: fixed
---
title: Make mail notifications of discussion notes In-Reply-To of each other
merge_request: 14289
author:
type: changed
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
# If you come up with a fun one, please feel free to contribute it to GitLab! # If you come up with a fun one, please feel free to contribute it to GitLab!
# https://about.gitlab.com/contributing/ # https://about.gitlab.com/contributing/
--- ---
- Good job! Looks like you don't have any todos left. - Good job! Looks like you don't have any todos left
- Isn't an empty todo list beautiful? - Isn't an empty todo list beautiful?
- Give yourself a pat on the back! - Give yourself a pat on the back!
- Nothing left to do, high five! - Nothing left to do, high five!
- Henceforth you shall be known as "Todo Destroyer". - Henceforth you shall be known as "Todo Destroyer"
...@@ -4,6 +4,12 @@ class AddNewProjectGuidelinesToAppearances < ActiveRecord::Migration ...@@ -4,6 +4,12 @@ class AddNewProjectGuidelinesToAppearances < ActiveRecord::Migration
DOWNTIME = false DOWNTIME = false
def change def change
# Clears the current Appearance cache otherwise it breaks since
# new_project_guidelines_html would be missing. See
# https://gitlab.com/gitlab-org/gitlab-ce/issues/41041
# We're not using Appearance#flush_redis_cache on purpose here.
Rails.cache.delete('current_appearance')
change_table :appearances do |t| change_table :appearances do |t|
t.text :new_project_guidelines t.text :new_project_guidelines
t.text :new_project_guidelines_html t.text :new_project_guidelines_html
......
...@@ -23,6 +23,7 @@ Learn how to install, configure, update, and maintain your GitLab instance. ...@@ -23,6 +23,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- **(EEP)** [GitLab GEO](../gitlab-geo/README.md): Replicate your GitLab instance to other geographical locations as a read-only fully operational version. - **(EEP)** [GitLab GEO](../gitlab-geo/README.md): Replicate your GitLab instance to other geographical locations as a read-only fully operational version.
- **(EEP)** [Pivotal Tile](../install/pivotal/index.md): Deploy GitLab as a pre-configured appliance using Ops Manager (BOSH) for Pivotal Cloud Foundry. - **(EEP)** [Pivotal Tile](../install/pivotal/index.md): Deploy GitLab as a pre-configured appliance using Ops Manager (BOSH) for Pivotal Cloud Foundry.
- [High Availability](high_availability/README.md): Configure multiple servers for scaling or high availability. - [High Availability](high_availability/README.md): Configure multiple servers for scaling or high availability.
- [High Availability on AWS](../university/high-availability/aws/README.md): Set up GitLab HA on Amazon AWS.
### Configuring GitLab ### Configuring GitLab
...@@ -44,6 +45,13 @@ Learn how to install, configure, update, and maintain your GitLab instance. ...@@ -44,6 +45,13 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Welcome message](../customization/welcome_message.md): Add a custom welcome message to the sign-in page. - [Welcome message](../customization/welcome_message.md): Add a custom welcome message to the sign-in page.
- ["New Project" page](../customization/new_project_page.md): Customize the text to be displayed on the page that opens whenever your users create a new project. - ["New Project" page](../customization/new_project_page.md): Customize the text to be displayed on the page that opens whenever your users create a new project.
#### Customizing GitLab's appearance
- [Header logo](../customization/branded_page_and_email_header.md): Change the logo on all pages and email headers.
- [Branded login page](../customization/branded_login_page.md): Customize the login page with your own logo, title, and description.
- [Welcome message](../customization/welcome_message.md): Add a custom welcome message to the sign-in page.
- ["New Project" page](../customization/new_project_page.md): Customize the text to be displayed on the page that opens whenever your users create a new project.
### Maintaining GitLab ### Maintaining GitLab
- [Raketasks](../raketasks/README.md): Perform various tasks for maintenance, backups, automatic webhooks setup, etc. - [Raketasks](../raketasks/README.md): Perform various tasks for maintenance, backups, automatic webhooks setup, etc.
......
...@@ -221,3 +221,22 @@ sudo gitlab-rake gitlab:shell:create_hooks ...@@ -221,3 +221,22 @@ sudo gitlab-rake gitlab:shell:create_hooks
cd /home/git/gitlab cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:shell:create_hooks RAILS_ENV=production sudo -u git -H bundle exec rake gitlab:shell:create_hooks RAILS_ENV=production
``` ```
## Check TCP connectivity to a remote site
Sometimes you need to know if your GitLab installation can connect to a TCP
service on another machine - perhaps a PostgreSQL or HTTPS server. A rake task
is included to help you with this:
**Omnibus Installation**
```
sudo gitlab-rake gitlab:tcp_check[example.com,80]
```
**Source Installation**
```
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:tcp_check[example.com,80] RAILS_ENV=production
```
...@@ -89,9 +89,11 @@ email address in order to sign up. ...@@ -89,9 +89,11 @@ email address in order to sign up.
If you also host a public-facing GitLab instance at `hooli.com` and set your If you also host a public-facing GitLab instance at `hooli.com` and set your
incoming email domain to `hooli.com`, an attacker could abuse the "Create new incoming email domain to `hooli.com`, an attacker could abuse the "Create new
issue by email" feature by using a project's unique address as the email when issue by email" or
signing up for Slack, which would send a confirmation email, which would create "[Create new merge request by email](../user/project/merge_requests/index.md#create-new-merge-requests-by-email)"
a new issue on the project owned by the attacker, allowing them to click the features by using a project's unique address as the email when signing up for
Slack, which would send a confirmation email, which would create a new issue or
merge request on the project owned by the attacker, allowing them to click the
confirmation link and validate their account on your company's private Slack confirmation link and validate their account on your company's private Slack
instance. instance.
......
...@@ -520,9 +520,9 @@ PUT /projects/:id/issues/:issue_iid ...@@ -520,9 +520,9 @@ PUT /projects/:id/issues/:issue_iid
| `title` | string | no | The title of an issue | | `title` | string | no | The title of an issue |
| `description` | string | no | The description of an issue | | `description` | string | no | The description of an issue |
| `confidential` | boolean | no | Updates an issue to be confidential | | `confidential` | boolean | no | Updates an issue to be confidential |
| `assignee_ids` | Array[integer] | no | The ID of the users to assign the issue to | | `assignee_ids` | Array[integer] | no | The ID of the user(s) to assign the issue to. Set to `0` or provide an empty value to unassign all assignees. |
| `milestone_id` | integer | no | The ID of a milestone to assign the issue to | | `milestone_id` | integer | no | The ID of a milestone to assign the issue to. Set to `0` or provide an empty value to unassign a milestone.|
| `labels` | string | no | Comma-separated label names for an issue | | `labels` | string | no | Comma-separated label names for an issue. Set to an empty string to unassign all labels. |
| `state_event` | string | no | The state event of an issue. Set `close` to close the issue and `reopen` to reopen it | | `state_event` | string | no | The state event of an issue. Set `close` to close the issue and `reopen` to reopen it |
| `updated_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) | | `updated_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) |
| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` | | `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` |
......
...@@ -547,11 +547,11 @@ PUT /projects/:id/merge_requests/:merge_request_iid ...@@ -547,11 +547,11 @@ PUT /projects/:id/merge_requests/:merge_request_iid
| `merge_request_iid` | integer | yes | The ID of a merge request | | `merge_request_iid` | integer | yes | The ID of a merge request |
| `target_branch` | string | no | The target branch | | `target_branch` | string | no | The target branch |
| `title` | string | no | Title of MR | | `title` | string | no | Title of MR |
| `assignee_id` | integer | no | Assignee user ID | | `assignee_id` | integer | no | The ID of the user to assign the merge request to. Set to `0` or provide an empty value to unassign all assignees. |
| `milestone_id` | integer | no | The ID of a milestone to assign the merge request to. Set to `0` or provide an empty value to unassign a milestone.|
| `labels` | string | no | Comma-separated label names for an merge request. Set to an empty string to unassign all labels. |
| `description` | string | no | Description of MR | | `description` | string | no | Description of MR |
| `state_event` | string | no | New state (close/reopen) | | `state_event` | string | no | New state (close/reopen) |
| `labels` | string | no | Labels for MR as a comma-separated list |
| `milestone_id` | integer | no | The ID of a milestone |
| `remove_source_branch` | boolean | no | Flag indicating if a merge request should remove the source branch when merging | | `remove_source_branch` | boolean | no | Flag indicating if a merge request should remove the source branch when merging |
| `squash` | boolean| no | Squash commits into a single commit when merging | | `squash` | boolean| no | Squash commits into a single commit when merging |
| `discussion_locked` | boolean | no | Flag indicating if the merge request's discussion is locked. If the discussion is locked only project members can add, edit or resolve comments. | | `discussion_locked` | boolean | no | Flag indicating if the merge request's discussion is locked. If the discussion is locked only project members can add, edit or resolve comments. |
......
...@@ -182,6 +182,8 @@ GET /projects/:id/repository/contributors ...@@ -182,6 +182,8 @@ GET /projects/:id/repository/contributors
Parameters: Parameters:
- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `order_by` (optional) - Return contributors ordered by `name`, `email`, or `commits` fields. If not given contributors are ordered by commit date.
- `sort` (optional) - Return contributors sorted in `asc` or `desc` order. Default is `asc`
Response: Response:
......
...@@ -12,7 +12,11 @@ GET /projects/:id/repository/tags ...@@ -12,7 +12,11 @@ GET /projects/:id/repository/tags
Parameters: Parameters:
- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string| yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user|
| `order_by` | string | no | Return tags ordered by `name` or `updated` fields. Default is `updated` |
| `sort` | string | no | Return tags sorted in `asc` or `desc` order. Default is `desc` |
```json ```json
[ [
......
...@@ -319,45 +319,62 @@ As you can see, the syntax of `command` is similar to [Dockerfile's `CMD`][cmd]. ...@@ -319,45 +319,62 @@ As you can see, the syntax of `command` is similar to [Dockerfile's `CMD`][cmd].
> Introduced in GitLab and GitLab Runner 9.4. Read more about the [extended > Introduced in GitLab and GitLab Runner 9.4. Read more about the [extended
configuration options](#extended-docker-configuration-options). configuration options](#extended-docker-configuration-options).
Before showing the available entrypoint override methods, let's describe shortly
how the Runner starts and uses a Docker image for the containers used in the
CI jobs:
1. The Runner starts a Docker container using the defined entrypoint (default
from `Dockerfile` that may be overridden in `.gitlab-ci.yml`)
1. The Runner attaches itself to a running container.
1. The Runner prepares a script (the combination of
[`before_script`](../yaml/README.md#before_script),
[`script`](../yaml/README.md#script),
and [`after_script`](../yaml/README.md#after_script)).
1. The Runner sends the script to the container's shell STDIN and receives the
output.
To override the entrypoint of a Docker image, the recommended solution is to
define an empty `entrypoint` in `.gitlab-ci.yml`, so the Runner doesn't start
a useless shell layer. However, that will not work for all Docker versions, and
you should check which one your Runner is using. Specifically:
- If Docker 17.06 or later is used, the `entrypoint` can be set to an empty value.
- If Docker 17.03 or previous versions are used, the `entrypoint` can be set to
`/bin/sh -c`, `/bin/bash -c` or an equivalent shell available in the image.
The syntax of `image:entrypoint` is similar to [Dockerfile's `ENTRYPOINT`][entrypoint].
----
Let's assume you have a `super/sql:experimental` image with some SQL database Let's assume you have a `super/sql:experimental` image with some SQL database
inside it and you would like to use it as a base image for your job because you inside it and you would like to use it as a base image for your job because you
want to execute some tests with this database binary. Let's also assume that want to execute some tests with this database binary. Let's also assume that
this image is configured with `/usr/bin/super-sql run` as an entrypoint. That this image is configured with `/usr/bin/super-sql run` as an entrypoint. That
means, that when starting the container without additional options, it will run means that when starting the container without additional options, it will run
the database's process, while Runner expects that the image will have no the database's process, while Runner expects that the image will have no
entrypoint or at least will start with a shell as its entrypoint. entrypoint or that the entrypoint is prepared to start a shell command.
Before the new extended Docker configuration options, you would need to create
your own image based on the `super/sql:experimental` image, set the entrypoint
to a shell and then use it in job's configuration, like:
```Dockerfile With the extended Docker configuration options, instead of creating your
# my-super-sql:experimental image's Dockerfile own image based on `super/sql:experimental`, setting the `ENTRYPOINT`
to a shell, and then using the new image in your CI job, you can now simply
define an `entrypoint` in `.gitlab-ci.yml`.
FROM super/sql:experimental **For Docker 17.06+:**
ENTRYPOINT ["/bin/sh"]
```
```yaml ```yaml
# .gitlab-ci.yml image:
name: super/sql:experimental
image: my-super-sql:experimental entrypoint: [""]
``` ```
After the new extended Docker configuration options, you can now simply **For Docker =< 17.03:**
set an `entrypoint` in `.gitlab-ci.yml`, like:
```yaml ```yaml
# .gitlab-ci.yml
image: image:
name: super/sql:experimental name: super/sql:experimental
entrypoint: ["/bin/sh"] entrypoint: ["/bin/sh", "-c"]
``` ```
As you can see the syntax of `entrypoint` is similar to
[Dockerfile's `ENTRYPOINT`][entrypoint].
## Define image and services in `config.toml` ## Define image and services in `config.toml`
Look for the `[runners.docker]` section: Look for the `[runners.docker]` section:
......
This diff is collapsed.
...@@ -232,14 +232,15 @@ An example project service that defines deployment variables is ...@@ -232,14 +232,15 @@ An example project service that defines deployment variables is
## Debug tracing ## Debug tracing
> Introduced in GitLab Runner 1.7. > Introduced in GitLab Runner 1.7.
>
> **WARNING:** Enabling debug tracing can have severe security implications. The CAUTION: **Warning:**
output **will** contain the content of all your secret variables and any other Enabling debug tracing can have severe security implications. The
secrets! The output **will** be uploaded to the GitLab server and made visible output **will** contain the content of all your secret variables and any other
in job traces! secrets! The output **will** be uploaded to the GitLab server and made visible
in job traces!
By default, GitLab Runner hides most of the details of what it is doing when By default, GitLab Runner hides most of the details of what it is doing when
processing a job. This behaviour keeps job traces short, and prevents secrets processing a job. This behavior keeps job traces short, and prevents secrets
from being leaked into the trace unless your script writes them to the screen. from being leaked into the trace unless your script writes them to the screen.
If a job isn't working as expected, this can make the problem difficult to If a job isn't working as expected, this can make the problem difficult to
......
...@@ -215,6 +215,9 @@ There is also and alternative method to [translate messages from validation erro ...@@ -215,6 +215,9 @@ There is also and alternative method to [translate messages from validation erro
sprintf(__('Hello %{username}'), { username: 'Joe' }) => 'Hello Joe' sprintf(__('Hello %{username}'), { username: 'Joe' }) => 'Hello Joe'
``` ```
The placeholders should match the code style of the respective source file.
For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript.
### Plurals ### Plurals
- In Ruby/HAML: - In Ruby/HAML:
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* [Tables](#tables) * [Tables](#tables)
* [Blocks](#blocks) * [Blocks](#blocks)
* [Panels](#panels) * [Panels](#panels)
* [Dialog modals](#dialog-modals) * [Modals](#modals)
* [Alerts](#alerts) * [Alerts](#alerts)
* [Forms](#forms) * [Forms](#forms)
* [Search box](#search-box) * [Search box](#search-box)
...@@ -255,18 +255,18 @@ Skeleton loading can replace any existing UI elements for the period in which th ...@@ -255,18 +255,18 @@ Skeleton loading can replace any existing UI elements for the period in which th
--- ---
## Dialog modals ## Modals
Dialog modals are only used for having a conversation and confirmation with the user. The user is not able to access the features on the main page until closing the modal. Modals are only used for having a conversation and confirmation with the user. The user is not able to access the features on the main page until closing the modal.
### Usage ### Usage
* When the action is irreversible, dialog modals provide the details and confirm with the user before they take an advanced action. * When the action is irreversible, modals provide the details and confirm with the user before they take an advanced action.
* When the action will affect privacy or authorization, dialog modals provide advanced information and confirm with the user. * When the action will affect privacy or authorization, modals provide advanced information and confirm with the user.
### Style ### Style
* Dialog modals contain the header, body, and actions. * Modals contain the header, body, and actions.
* **Header(1):** The header title is a question instead of a descriptive phrase. * **Header(1):** The header title is a question instead of a descriptive phrase.
* **Body(2):** The content in body should never be ambiguous and unclear. It provides specific information. * **Body(2):** The content in body should never be ambiguous and unclear. It provides specific information.
* **Actions(3):** Contains a affirmative action, a dismissive action, and an extra action. The order of actions from left to right: Dismissive action → Extra action → Affirmative action * **Actions(3):** Contains a affirmative action, a dismissive action, and an extra action. The order of actions from left to right: Dismissive action → Extra action → Affirmative action
...@@ -277,13 +277,13 @@ Dialog modals are only used for having a conversation and confirmation with the ...@@ -277,13 +277,13 @@ Dialog modals are only used for having a conversation and confirmation with the
### Placement ### Placement
* Dialog modals should always be the center of the screen horizontally and be positioned **72px** from the top. * Modals should always be the center of the screen horizontally and be positioned **72px** from the top.
| Dialog with 2 actions | Dialog with 3 actions | Special confirmation | | Modal with 2 actions | Modal with 3 actions | Special confirmation |
| --------------------- | --------------------- | -------------------- | | --------------------- | --------------------- | -------------------- |
| ![two-actions](img/modals-general-confimation-dialog.png) | ![three-actions](img/modals-three-buttons.png) | ![spcial-confirmation](img/modals-special-confimation-dialog.png) | | ![two-actions](img/modals-general-confimation-dialog.png) | ![three-actions](img/modals-three-buttons.png) | ![spcial-confirmation](img/modals-special-confimation-dialog.png) |
> TODO: Special case for dialog modal. > TODO: Special case for modal.
--- ---
......
...@@ -46,11 +46,11 @@ Avoid using periods in solitary sentences in these elements: ...@@ -46,11 +46,11 @@ Avoid using periods in solitary sentences in these elements:
* Labels * Labels
* Hover text * Hover text
* Bulleted lists * Bulleted lists
* Dialog body text * Modal body text
Periods should be used for: Periods should be used for:
* Lists or dialogs with multiple sentences * Lists or modals with multiple sentences
* Any sentence followed by a link * Any sentence followed by a link
| :white_check_mark: **Do** place periods after sentences followed by a link | :no_entry_sign: **Don’t** place periods after a link if it‘s not followed by a sentence | | :white_check_mark: **Do** place periods after sentences followed by a link | :no_entry_sign: **Don’t** place periods after a link if it‘s not followed by a sentence |
...@@ -80,7 +80,7 @@ Omit punctuation after phrases and labels to create a cleaner and more readable ...@@ -80,7 +80,7 @@ Omit punctuation after phrases and labels to create a cleaner and more readable
| Punctuation mark | Copy and paste | HTML entity | Unicode | Mac shortcut | Windows shortcut | Description | | Punctuation mark | Copy and paste | HTML entity | Unicode | Mac shortcut | Windows shortcut | Description |
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|
| Period | **.** | | | | | Omit for single sentences in affordances like labels, hover text, bulleted lists, and dialog body text.<br><br>Use in lists or dialogs with multiple sentences, and any sentence followed by a link or inline code.<br><br>Place inside quotation marks unless you’re telling the reader what to enter and it’s ambiguous whether to include the period. | | Period | **.** | | | | | Omit for single sentences in affordances like labels, hover text, bulleted lists, and modal body text.<br><br>Use in lists or modals with multiple sentences, and any sentence followed by a link or inline code.<br><br>Place inside quotation marks unless you’re telling the reader what to enter and it’s ambiguous whether to include the period. |
| Comma | **,** | | | | | Place inside quotation marks.<br><br>Use a [serial comma][serial comma] in lists of three or more terms. | | Comma | **,** | | | | | Place inside quotation marks.<br><br>Use a [serial comma][serial comma] in lists of three or more terms. |
| Exclamation point | **!** | | | | | Avoid exclamation points as they tend to come across as shouting. Some exceptions include greetings or congratulatory messages. | | Exclamation point | **!** | | | | | Avoid exclamation points as they tend to come across as shouting. Some exceptions include greetings or congratulatory messages. |
| Colon | **:** | `&#58;` | `\u003A` | | | Omit from labels, for example, in the labels for fields in a form. | | Colon | **:** | `&#58;` | `\u003A` | | | Omit from labels, for example, in the labels for fields in a form. |
...@@ -88,7 +88,7 @@ Omit punctuation after phrases and labels to create a cleaner and more readable ...@@ -88,7 +88,7 @@ Omit punctuation after phrases and labels to create a cleaner and more readable
| Quotation marks | **“**<br><br>**”**<br><br>**‘**<br><br>**’** | `&ldquo;`<br><br>`&rdquo;`<br><br>`&lsquo;`<br><br>`&rsquo;` | `\u201C`<br><br>`\u201D`<br><br>`\u2018`<br><br>`\u2019` | <kbd>⌥ Option</kbd>+<kbd>[</kbd><br><br><kbd>⌥ Option</kbd>+<kbd>⇧ Shift</kbd>+<kbd>[</kbd><br><br><kbd>⌥ Option</kbd>+<kbd>]</kbd><br><br><kbd>⌥ Option</kbd>+<kbd>⇧ Shift</kbd>+<kbd>]</kbd> | <kbd>Alt</kbd>+<kbd>0 1 4 7</kbd><br><br><kbd>Alt</kbd>+<kbd>0 1 4 8</kbd><br><br><kbd>Alt</kbd>+<kbd>0 1 4 5</kbd><br><br><kbd>Alt</kbd>+<kbd>0 1 4 6</kbd> | Use proper quotation marks (also known as smart quotes, curly quotes, or typographer’s quotes) for quotes. Single quotation marks are used for quotes inside of quotes.<br><br>The right single quotation mark symbol is also used for apostrophes.<br><br>Don’t use primes, straight quotes, or free-standing accents for quotation marks. | | Quotation marks | **“**<br><br>**”**<br><br>**‘**<br><br>**’** | `&ldquo;`<br><br>`&rdquo;`<br><br>`&lsquo;`<br><br>`&rsquo;` | `\u201C`<br><br>`\u201D`<br><br>`\u2018`<br><br>`\u2019` | <kbd>⌥ Option</kbd>+<kbd>[</kbd><br><br><kbd>⌥ Option</kbd>+<kbd>⇧ Shift</kbd>+<kbd>[</kbd><br><br><kbd>⌥ Option</kbd>+<kbd>]</kbd><br><br><kbd>⌥ Option</kbd>+<kbd>⇧ Shift</kbd>+<kbd>]</kbd> | <kbd>Alt</kbd>+<kbd>0 1 4 7</kbd><br><br><kbd>Alt</kbd>+<kbd>0 1 4 8</kbd><br><br><kbd>Alt</kbd>+<kbd>0 1 4 5</kbd><br><br><kbd>Alt</kbd>+<kbd>0 1 4 6</kbd> | Use proper quotation marks (also known as smart quotes, curly quotes, or typographer’s quotes) for quotes. Single quotation marks are used for quotes inside of quotes.<br><br>The right single quotation mark symbol is also used for apostrophes.<br><br>Don’t use primes, straight quotes, or free-standing accents for quotation marks. |
| Primes | **′**<br><br>**″** | `&prime;`<br><br>`&Prime;` | `\u2032`<br><br>`\u2033` | | <kbd>Alt</kbd>+<kbd>8 2 4 2</kbd><br><br><kbd>Alt</kbd>+<kbd>8 2 4 3</kbd> | Use prime (′) only in abbreviations for feet, arcminutes, and minutes: 3° 15′<br><br>Use double-prime (″) only in abbreviations for inches, arcseconds, and seconds: 3° 15′ 35″<br><br>Don’t use quotation marks, straight quotes, or free-standing accents for primes. | | Primes | **′**<br><br>**″** | `&prime;`<br><br>`&Prime;` | `\u2032`<br><br>`\u2033` | | <kbd>Alt</kbd>+<kbd>8 2 4 2</kbd><br><br><kbd>Alt</kbd>+<kbd>8 2 4 3</kbd> | Use prime (′) only in abbreviations for feet, arcminutes, and minutes: 3° 15′<br><br>Use double-prime (″) only in abbreviations for inches, arcseconds, and seconds: 3° 15′ 35″<br><br>Don’t use quotation marks, straight quotes, or free-standing accents for primes. |
| Straight quotes and accents | **"**<br><br>**'**<br><br>**`**<br><br>**´** | `&quot;`<br><br>`&#39;`<br><br>`&#96;`<br><br>`&acute;` | `\u0022`<br><br>`\u0027`<br><br>`\u0060`<br><br>`\u00B4` | | | Don’t use straight quotes or free-standing accents for primes or quotation marks.<br><br>Proper typography never uses straight quotes. They are left over from the age of typewriters and their only modern use is for code. | | Straight quotes and accents | **"**<br><br>**'**<br><br>**`**<br><br>**´** | `&quot;`<br><br>`&#39;`<br><br>`&#96;`<br><br>`&acute;` | `\u0022`<br><br>`\u0027`<br><br>`\u0060`<br><br>`\u00B4` | | | Don’t use straight quotes or free-standing accents for primes or quotation marks.<br><br>Proper typography never uses straight quotes. They are left over from the age of typewriters and their only modern use is for code. |
| Ellipsis | **…** | `&hellip;` | | <kbd>⌥ Option</kbd>+<kbd>;</kbd> | <kbd>Alt</kbd>+<kbd>0 1 3 3</kbd> | Use to indicate an action in progress (“Downloading…”) or incomplete or truncated text. No space before the ellipsis.<br><br>Omit from menu items or buttons that open a dialog or start some other process. | | Ellipsis | **…** | `&hellip;` | | <kbd>⌥ Option</kbd>+<kbd>;</kbd> | <kbd>Alt</kbd>+<kbd>0 1 3 3</kbd> | Use to indicate an action in progress (“Downloading…”) or incomplete or truncated text. No space before the ellipsis.<br><br>Omit from menu items or buttons that open a modal or start some other process. |
| Chevrons | **«**<br><br>**»**<br><br>**‹**<br><br>**›**<br><br>**<**<br><br>**>** | `&#171;`<br><br>`&#187;`<br><br>`&#8249;`<br><br>`&#8250;`<br><br>`&lt;`<br><br>`&gt;` | `\u00AB`<br><br>`\u00BB`<br><br>`\u2039`<br><br>`\u203A`<br><br>`\u003C`<br><br>`\u003E`<br><br> | | | Omit from links or buttons that open another page or move to the next or previous step in a process. Also known as angle brackets, angular quote brackets, or guillemets. | | Chevrons | **«**<br><br>**»**<br><br>**‹**<br><br>**›**<br><br>**<**<br><br>**>** | `&#171;`<br><br>`&#187;`<br><br>`&#8249;`<br><br>`&#8250;`<br><br>`&lt;`<br><br>`&gt;` | `\u00AB`<br><br>`\u00BB`<br><br>`\u2039`<br><br>`\u203A`<br><br>`\u003C`<br><br>`\u003E`<br><br> | | | Omit from links or buttons that open another page or move to the next or previous step in a process. Also known as angle brackets, angular quote brackets, or guillemets. |
| Em dash | **—** | `&mdash;` | `\u2014` | <kbd>⌥ Option</kbd>+<kbd>⇧ Shift</kbd>+<kbd>-</kbd> | <kbd>Alt</kbd>+<kbd>0 1 5 1</kbd> | Avoid using dashes to separate text. If you must use dashes for this purpose — like this — use an em dash surrounded by spaces. | | Em dash | **—** | `&mdash;` | `\u2014` | <kbd>⌥ Option</kbd>+<kbd>⇧ Shift</kbd>+<kbd>-</kbd> | <kbd>Alt</kbd>+<kbd>0 1 5 1</kbd> | Avoid using dashes to separate text. If you must use dashes for this purpose — like this — use an em dash surrounded by spaces. |
| En dash | **–** | `&ndash;` | `\u2013` | <kbd>⌥ Option</kbd>+<kbd>-</kbd> | <kbd>Alt</kbd>+<kbd>0 1 5 0</kbd> | Use an en dash without spaces instead of a hyphen to indicate a range of values, such as numbers, times, and dates: “3–5 kg”, “8:00 AM–12:30 PM”, “10–17 Jan” | | En dash | **–** | `&ndash;` | `\u2013` | <kbd>⌥ Option</kbd>+<kbd>-</kbd> | <kbd>Alt</kbd>+<kbd>0 1 5 0</kbd> | Use an en dash without spaces instead of a hyphen to indicate a range of values, such as numbers, times, and dates: “3–5 kg”, “8:00 AM–12:30 PM”, “10–17 Jan” |
...@@ -175,7 +175,7 @@ A **comment** is a written piece of text that users of GitLab can create. Commen ...@@ -175,7 +175,7 @@ A **comment** is a written piece of text that users of GitLab can create. Commen
#### Discussion #### Discussion
A **discussion** is a group of 1 or more comments. A discussion can include subdiscussions. Some discussions have the special capability of being able to be **resolved**. Both the comments in the discussion and the discussion itself can be resolved. A **discussion** is a group of 1 or more comments. A discussion can include subdiscussions. Some discussions have the special capability of being able to be **resolved**. Both the comments in the discussion and the discussion itself can be resolved.
## Confirmation dialogs ## Modals
- Destruction buttons should be clear and always say what they are destroying. - Destruction buttons should be clear and always say what they are destroying.
E.g., `Delete page` instead of just `Delete`. E.g., `Delete page` instead of just `Delete`.
...@@ -184,6 +184,8 @@ A **discussion** is a group of 1 or more comments. A discussion can include subd ...@@ -184,6 +184,8 @@ A **discussion** is a group of 1 or more comments. A discussion can include subd
- Avoid the word `cancel` or `canceled` in the descriptive copy. It can be - Avoid the word `cancel` or `canceled` in the descriptive copy. It can be
confusing when you then see the `Cancel` button. confusing when you then see the `Cancel` button.
see also: guidelines for [modal components](components.md#modals)
--- ---
Portions of this page are modifications based on work created and shared by the [Android Open Source Project][android project] and used according to terms described in the [Creative Commons 2.5 Attribution License][creative commons]. Portions of this page are modifications based on work created and shared by the [Android Open Source Project][android project] and used according to terms described in the [Creative Commons 2.5 Attribution License][creative commons].
......
...@@ -299,9 +299,9 @@ sudo usermod -aG redis git ...@@ -299,9 +299,9 @@ sudo usermod -aG redis git
### Clone the Source ### Clone the Source
# Clone GitLab repository # Clone GitLab repository
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 10-2-stable gitlab sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 10-3-stable gitlab
**Note:** You can change `10-2-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! **Note:** You can change `10-3-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
### Configure It ### Configure It
......
...@@ -61,6 +61,10 @@ We've gathered some resources to help you to get the best from Git with GitLab. ...@@ -61,6 +61,10 @@ We've gathered some resources to help you to get the best from Git with GitLab.
- [Getting Started with Git LFS](https://about.gitlab.com/2017/01/30/getting-started-with-git-lfs-tutorial/) - [Getting Started with Git LFS](https://about.gitlab.com/2017/01/30/getting-started-with-git-lfs-tutorial/)
- [Towards a production quality open source Git LFS server](https://about.gitlab.com/2015/08/13/towards-a-production-quality-open-source-git-lfs-server/) - [Towards a production quality open source Git LFS server](https://about.gitlab.com/2015/08/13/towards-a-production-quality-open-source-git-lfs-server/)
## Troubleshooting
- Learn a few [Git troubleshooting](troubleshooting_git.md) techniques to help you out.
## General information ## General information
- **Articles:** - **Articles:**
......
# Troubleshooting Git
Sometimes things don't work the way they should or as you might expect when
you're using Git. Here are some tips on troubleshooting and resolving issues
with Git.
## Broken pipe errors on git push
'Broken pipe' errors can occur when attempting to push to a remote repository.
When pushing you will usually see:
```
Write failed: Broken pipe
fatal: The remote end hung up unexpectedly
```
To fix this issue, here are some possible solutions.
### Increase the POST buffer size in Git
**If pushing over HTTP**, you can try increasing the POST buffer size in Git's
configuration. Open a terminal and enter:
```sh
git config http.postBuffer 52428800
```
The value is specified in bytes, so in the above case the buffer size has been
set to 50MB. The default is 1MB.
### Check your SSH configuration
**If pushing over SSH**, first check your SSH configuration as 'Broken pipe'
errors can sometimes be caused by underlying issues with SSH (such as
authentication). Make sure that SSH is correctly configured by following the
instructions in the [SSH troubleshooting] docs.
There's another option where you can prevent session timeouts by configuring
SSH 'keep alive' either on the client or on the server (if you are a GitLab
admin and have access to the server).
NOTE: **Note:** configuring *both* the client and the server is unnecessary.
**To configure SSH on the client side**:
- On UNIX, edit `~/.ssh/config` (create the file if it doesn’t exist) and
add or edit:
```
Host your-gitlab-instance-url.com
ServerAliveInterval 60
ServerAliveCountMax 5
```
- On Windows, if you are using PuTTY, go to your session properties, then
navigate to "Connection" and under "Sending of null packets to keep
session active", set "Seconds between keepalives (0 to turn off)" to `60`.
**To configure SSH on the server side**, edit `/etc/ssh/sshd_config` and add:
```
ClientAliveInterval 60
ClientAliveCountMax 5
```
### Running a git repack
**If 'pack-objects' type errors are also being displayed**, you can try to
run a `git repack` before attempting to push to the remote repository again:
```sh
git repack
git push
```
### Upgrade your Git client
In case you're running an older version of Git (< 2.9), consider upgrading
to >= 2.9 (see [Broken pipe when pushing to Git repository][Broken-Pipe]).
[SSH troubleshooting]: ../../ssh/README.md#troubleshooting "SSH Troubleshooting"
[Broken-Pipe]: https://stackoverflow.com/questions/19120120/broken-pipe-when-pushing-to-git-repository/36971469#36971469 "StackOverflow: 'Broken pipe when pushing to Git repository'"
This diff is collapsed.
...@@ -207,11 +207,11 @@ username, you can create a new group and transfer projects to it. ...@@ -207,11 +207,11 @@ username, you can create a new group and transfer projects to it.
Changing a group's path can have unintended side effects. Changing a group's path can have unintended side effects.
* Existing web URLs for the group and anything under it (i.e. projects) will * Existing web URLs for the group and anything under it (i.e. projects) will
redirect to the new URLs redirect to the new URLs.
* Existing Git remote URLs for projects under the group will no longer work, but * Existing Git remote URLs for projects under the group will redirect to the new remote URL, and they
Git responses will show an error with the new remote URL will show a warning with the new remote URL.
* The original namespace can be claimed again by any group or user, which will * The redirect to the new URL is permanent, that implies the original namespace
destroy web redirects and Git remote warnings can't be claimed again by any group or user.
* If you are vacating the path so it can be claimed by another group or user, * If you are vacating the path so it can be claimed by another group or user,
you may need to rename the group name as well since both names and paths must be you may need to rename the group name as well since both names and paths must be
unique unique
......
...@@ -196,12 +196,23 @@ With inline diffs tags you can display {+ additions +} or [- deletions -]. ...@@ -196,12 +196,23 @@ With inline diffs tags you can display {+ additions +} or [- deletions -].
The wrapping tags can be either curly braces or square brackets [+ additions +] or {- deletions -}. The wrapping tags can be either curly braces or square brackets [+ additions +] or {- deletions -}.
Examples:
```
- {+ additions +}
- [+ additions +]
- {- deletions -}
- [- deletions -]
```
However the wrapping tags cannot be mixed as such: However the wrapping tags cannot be mixed as such:
```
- {+ additions +] - {+ additions +]
- [+ additions +} - [+ additions +}
- {- deletions -] - {- deletions -]
- [- deletions -} - [- deletions -}
```
### Emoji ### Emoji
......
...@@ -45,11 +45,10 @@ Alternatively, you can follow [this detailed procedure from the GitLab Team Hand ...@@ -45,11 +45,10 @@ Alternatively, you can follow [this detailed procedure from the GitLab Team Hand
Changing your username can have unintended side effects. Changing your username can have unintended side effects.
* Existing web URLs for the user and anything under it (i.e. projects) will * Existing web URLs for the user and anything under it (i.e. projects) will
redirect to the new URLs redirect to the new URLs.
* Existing Git remote URLs for projects under the user will no longer work, but * Existing Git remote URLs for projects under the user will redirect to the new remote URL. Git responses
Git responses will show an error with the new remote URL will show a warning with the new remote URL.
* The original namespace can be claimed again by any group or user, which will * The redirect to the new URL is permanent, that implies the original namespace can't be claimed again by any group or user.
destroy any web redirects and Git remote warnings
> It is currently not possible to rename a namespace if it contains a > It is currently not possible to rename a namespace if it contains a
project with container registry tags, because the project cannot be moved. project with container registry tags, because the project cannot be moved.
......
...@@ -27,7 +27,7 @@ With GitLab merge requests, you can: ...@@ -27,7 +27,7 @@ With GitLab merge requests, you can:
- [Resolve merge conflicts from the UI](#resolve-conflicts) - [Resolve merge conflicts from the UI](#resolve-conflicts)
- Enable [fast-forward merge requests](#fast-forward-merge-requests) - Enable [fast-forward merge requests](#fast-forward-merge-requests)
- Enable [semi-linear history merge requests](#semi-linear-history-merge-requests) as another security layer to guarantee the pipeline is passing in the target branch - Enable [semi-linear history merge requests](#semi-linear-history-merge-requests) as another security layer to guarantee the pipeline is passing in the target branch
- [Create new merge requests by email](#create_by_email) - [Create new merge requests by email](#create-new-merge-requests-by-email)
With **[GitLab Enterprise Edition][ee]**, you can also: With **[GitLab Enterprise Edition][ee]**, you can also:
...@@ -145,7 +145,13 @@ You can create a new merge request by sending an email to a user-specific email ...@@ -145,7 +145,13 @@ You can create a new merge request by sending an email to a user-specific email
address. The address can be obtained on the merge requests page by clicking on address. The address can be obtained on the merge requests page by clicking on
a **Email a new merge request to this project** button. The subject will be a **Email a new merge request to this project** button. The subject will be
used as the source branch name for the new merge request and the target branch used as the source branch name for the new merge request and the target branch
will be the default branch for the project. will be the default branch for the project. The message body (if not empty)
will be used as the merge request description. You need
["Reply by email"](../../../administration/reply_by_email.md) enabled to use
this feature. If it's not enabled to your instance, you may ask your GitLab
administrator to do so.
![Create new merge requests by email](img/create_from_email.png)
## Revert changes ## Revert changes
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment