import { deprecatedCreateFlash as flash } from '~/flash'; import { addNumericSuffix } from '~/ide/utils'; import { sprintf, __ } from '~/locale'; import { leftSidebarViews } from '../../../constants'; import eventHub from '../../../eventhub'; import { parseCommitError } from '../../../lib/errors'; import service from '../../../services'; import * as rootTypes from '../../mutation_types'; import { createCommitPayload, createNewMergeRequestUrl } from '../../utils'; import { COMMIT_TO_CURRENT_BRANCH } from './constants'; import * as types from './mutation_types'; export const updateCommitMessage = ({ commit }, message) => { commit(types.UPDATE_COMMIT_MESSAGE, message); }; export const discardDraft = ({ commit }) => { commit(types.UPDATE_COMMIT_MESSAGE, ''); }; export const updateCommitAction = ({ commit }, commitAction) => { commit(types.UPDATE_COMMIT_ACTION, { commitAction }); }; export const toggleShouldCreateMR = ({ commit }) => { commit(types.TOGGLE_SHOULD_CREATE_MR); }; export const updateBranchName = ({ commit }, branchName) => { commit(types.UPDATE_NEW_BRANCH_NAME, branchName); }; export const addSuffixToBranchName = ({ commit, state }) => { const newBranchName = addNumericSuffix(state.newBranchName, true); commit(types.UPDATE_NEW_BRANCH_NAME, newBranchName); }; export const setLastCommitMessage = ({ commit, rootGetters }, data) => { const { currentProject } = rootGetters; const commitStats = data.stats ? sprintf(__('with %{additions} additions, %{deletions} deletions.'), { additions: data.stats.additions, deletions: data.stats.deletions, }) : ''; const commitMsg = sprintf( __('Your changes have been committed. Commit %{commitId} %{commitStats}'), { commitId: `${data.short_id}`, commitStats, }, false, ); commit(rootTypes.SET_LAST_COMMIT_MSG, commitMsg, { root: true }); }; export const updateFilesAfterCommit = ({ commit, dispatch, rootState, rootGetters }, { data }) => { const selectedProject = rootGetters.currentProject; const lastCommit = { commit_path: `${selectedProject.web_url}/-/commit/${data.id}`, commit: { id: data.id, message: data.message, authored_date: data.committed_date, author_name: data.committer_name, }, }; commit( rootTypes.SET_BRANCH_WORKING_REFERENCE, { projectId: rootState.currentProjectId, branchId: rootState.currentBranchId, reference: data.id, }, { root: true }, ); rootState.stagedFiles.forEach((file) => { const changedFile = rootState.changedFiles.find((f) => f.path === file.path); commit( rootTypes.UPDATE_FILE_AFTER_COMMIT, { file, lastCommit, }, { root: true }, ); commit( rootTypes.TOGGLE_FILE_CHANGED, { file, changed: false, }, { root: true }, ); dispatch('updateTempFlagForEntry', { file, tempFile: false }, { root: true }); eventHub.$emit(`editor.update.model.content.${file.key}`, { content: file.content, changed: Boolean(changedFile), }); }); }; export const commitChanges = ({ commit, state, getters, dispatch, rootState, rootGetters }) => { // Pull commit options out because they could change // During some of the pre and post commit processing const { shouldCreateMR, shouldHideNewMrOption, isCreatingNewBranch, branchName } = getters; const newBranch = state.commitAction !== COMMIT_TO_CURRENT_BRANCH; const stageFilesPromise = rootState.stagedFiles.length ? Promise.resolve() : dispatch('stageAllChanges', null, { root: true }); commit(types.CLEAR_ERROR); commit(types.UPDATE_LOADING, true); return stageFilesPromise .then(() => { const payload = createCommitPayload({ branch: branchName, newBranch, getters, state, rootState, rootGetters, }); return service.commit(rootState.currentProjectId, payload); }) .catch((e) => { commit(types.UPDATE_LOADING, false); commit(types.SET_ERROR, parseCommitError(e)); throw e; }) .then(({ data }) => { commit(types.UPDATE_LOADING, false); if (!data.short_id) { flash(data.message, 'alert', document, null, false, true); return null; } if (!data.parent_ids.length) { commit( rootTypes.TOGGLE_EMPTY_STATE, { projectPath: rootState.currentProjectId, value: false, }, { root: true }, ); } dispatch('setLastCommitMessage', data); dispatch('updateCommitMessage', ''); return dispatch('updateFilesAfterCommit', { data, branch: branchName, }) .then(() => { commit(rootTypes.CLEAR_STAGED_CHANGES, null, { root: true }); setTimeout(() => { commit(rootTypes.SET_LAST_COMMIT_MSG, '', { root: true }); }, 5000); if (shouldCreateMR && !shouldHideNewMrOption) { const { currentProject } = rootGetters; const targetBranch = isCreatingNewBranch ? rootState.currentBranchId : currentProject.default_branch; dispatch( 'redirectToUrl', createNewMergeRequestUrl(currentProject.web_url, branchName, targetBranch), { root: true }, ); } }) .then(() => { if (rootGetters.lastOpenedFile) { dispatch( 'openPendingTab', { file: rootGetters.lastOpenedFile, }, { root: true }, ) .then((changeViewer) => { if (changeViewer) { dispatch('updateViewer', 'diff', { root: true }); } }) .catch((e) => { throw e; }); } else { dispatch('updateActivityBarView', leftSidebarViews.edit.name, { root: true }); dispatch('updateViewer', 'editor', { root: true }); } }) .then(() => dispatch('updateCommitAction', COMMIT_TO_CURRENT_BRANCH)) .then(() => { if (newBranch) { const path = rootGetters.activeFile ? rootGetters.activeFile.path : ''; return dispatch( 'router/push', `/project/${rootState.currentProjectId}/blob/${branchName}/-/${path}`, { root: true }, ); } return dispatch( 'refreshLastCommitData', { projectId: rootState.currentProjectId, branchId: branchName }, { root: true }, ); }); }); };