import Icon from '~/vue_shared/components/icon.vue';
-import { n__, __, sprintf } from '~/locale';
+import { n__, __, sprintf, s__ } from '~/locale';
import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
+import { DIFF_BASE_INDEX, DIFF_HEAD_INDEX } from '../constants';
export default {
components: {
@@ -40,16 +41,63 @@ export default {
required: false,
default: null,
},
+ headVersionPath: {
+ type: String,
+ required: false,
+ default: null,
+ },
},
computed: {
+ targetBranchVersions() {
+ if (this.mergeRequestVersion) {
+ return [];
+ }
+
+ const versions = [
+ {
+ ...this.targetBranch,
+ id: '_target_base',
+ version_index: DIFF_BASE_INDEX,
+ targetHref: this.baseVersionPath,
+ targetName: sprintf(s__('DiffsCompareBaseBranch|%{branchName} (base)'), {
+ branchName: this.targetBranch.branchName,
+ }),
+ },
+ ];
+
+ if (this.headVersionPath) {
+ versions.push({
+ ...this.targetBranch,
+ id: '_target_head',
+ version_index: DIFF_HEAD_INDEX,
+ targetHref: this.headVersionPath,
+ targetName: sprintf(s__('DiffsCompareBaseBranch|%{branchName} (HEAD)'), {
+ branchName: this.targetBranch.branchName,
+ }),
+ });
+ }
+
+ return versions;
+ },
targetVersions() {
+ return [...this.otherVersions, ...this.targetBranchVersions];
+ },
+ selectedVersionIndex() {
if (this.mergeRequestVersion) {
- return this.otherVersions;
+ return this.mergeRequestVersion.version_index;
+ }
+
+ if (this.startVersion) {
+ return this.startVersion.version_index;
}
- return [...this.otherVersions, this.targetBranch];
+
+ const diffHead = parseBoolean(getParameterByName('diff_head'));
+
+ return diffHead ? DIFF_HEAD_INDEX : DIFF_BASE_INDEX;
},
selectedVersionName() {
- const selectedVersion = this.startVersion || this.targetBranch || this.mergeRequestVersion;
+ const selectedVersion = this.targetVersions.find(x => this.isActive(x));
+
return this.versionName(selectedVersion);
},
},
@@ -58,8 +106,8 @@ export default {
return n__(`%d commit,`, `%d commits,`, version.commits_count);
},
href(version) {
- if (this.isBase(version)) {
- return this.baseVersionPath;
+ if (version.targetHref) {
+ return version.targetHref;
}
if (this.showCommitCount) {
return version.version_path;
@@ -67,12 +115,14 @@ export default {
return version.compare_path;
},
versionName(version) {
- if (this.isLatest(version)) {
+ if (!version) {
+ return '';
+ } else if (this.isLatest(version)) {
return __('latest version');
+ } else if (version.targetName) {
+ return version.targetName;
}
- if (this.targetBranch && (this.isBase(version) || !version)) {
- return this.targetBranch.branchName;
- }
+
return sprintf(__(`version %{versionIndex}`), { versionIndex: version.version_index });
},
isActive(version) {
@@ -80,23 +130,7 @@ export default {
return false;
}
- if (this.targetBranch) {
- return (
- (this.isBase(version) && !this.startVersion) ||
- (this.startVersion && this.startVersion.version_index === version.version_index)
- );
- }
-
- return version.version_index === this.mergeRequestVersion.version_index;
- },
- isBase(version) {
- if (!version || !this.targetBranch) {
- return false;
- }
- return version.versionIndex === -1;
- },
- isHead() {
- return parseBoolean(getParameterByName('diff_head'));
+ return version.version_index === this.selectedVersionIndex;
},
isLatest(version) {
return (
@@ -125,10 +159,6 @@ export default {
{{ versionName(version) }}
- {{ s__('DiffsCompareBaseBranch|(HEAD)') }}
- {{
- s__('DiffsCompareBaseBranch|(base)')
- }}
diff --git a/app/assets/javascripts/diffs/constants.js b/app/assets/javascripts/diffs/constants.js
index 7521f3c950aa7a3271d8e8815da1b3c93bc0ca95..9e34f4a99c34854211cd27cf4fc98602d2c1c1e9 100644
--- a/app/assets/javascripts/diffs/constants.js
+++ b/app/assets/javascripts/diffs/constants.js
@@ -58,3 +58,6 @@ export const START_RENDERING_INDEX = 200;
export const INLINE_DIFF_LINES_KEY = 'highlighted_diff_lines';
export const PARALLEL_DIFF_LINES_KEY = 'parallel_diff_lines';
export const DIFFS_PER_PAGE = 20;
+
+export const DIFF_BASE_INDEX = -1;
+export const DIFF_HEAD_INDEX = -2;
diff --git a/changelogs/unreleased/id-display-master-head-in-dropdown.yml b/changelogs/unreleased/id-display-master-head-in-dropdown.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e8842c300c804ebd23a2a38611e1a2a76c949c8a
--- /dev/null
+++ b/changelogs/unreleased/id-display-master-head-in-dropdown.yml
@@ -0,0 +1,5 @@
+---
+title: Display master(HEAD) in compare versions dropdown
+merge_request: 26918
+author:
+type: fixed
diff --git a/doc/user/project/merge_requests/img/versions_compare_head_v12_9.png b/doc/user/project/merge_requests/img/versions_compare_head_v12_9.png
new file mode 100644
index 0000000000000000000000000000000000000000..353cf458243d7ca4bde51be8cb78c99aecc4aa32
Binary files /dev/null and b/doc/user/project/merge_requests/img/versions_compare_head_v12_9.png differ
diff --git a/doc/user/project/merge_requests/versions.md b/doc/user/project/merge_requests/versions.md
index ffd0efb365a76fa4167cc5de5e33ae97291092be..53351933b05edaf46dd9d2dee2dde850865d10bf 100644
--- a/doc/user/project/merge_requests/versions.md
+++ b/doc/user/project/merge_requests/versions.md
@@ -46,6 +46,27 @@ This only applies to commits that are in the most recent version of a merge
request - if a commit was in a merge request, then rebased out of that merge
request, they will not be linked.
+## `HEAD` comparison mode for Merge Requests
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/27008) in GitLab 12.9.
+
+Merge Requests, particularly the **Changes** tab, is where source code
+is reviewed and discussed. In circumstances where the target branch was
+merged into the source branch of the merge request, the changes in the
+source and target branch can be shown mixed together making it hard to
+understand which changes are being added and which already exist in the
+target branch.
+
+In GitLab 12.9, we added an **experimental** comparison mode, which
+shows a diff calculated by simulating how it would look like once merged - a more accurate
+representation of the changes rather than using the base of the two
+branches. The new mode is available from the comparison target drop down
+by selecting **master (HEAD)**. In the future it will
+[replace](https://gitlab.com/gitlab-org/gitlab/issues/198458) the
+current default comparison.
+
+
+