Skip to content

Commit

Permalink
Improve hg revset used by jest-changed-files
Browse files Browse the repository at this point in the history
The old revset is `ancestor(.^, min(branch(.) and not min(branch(default)), max(public()))`.
It can select public commits unintentionally in some cases.

In the following two examples, commit A would be selected by the old code path
as the "from revision". The new revset would select commit C instead, which
is better because the developer won't want to test commits in the `B::C` range.

Example 1 - Multiple named branches:

  E default (named branch), public
  :
  | D stable (named branch), draft (only commit the developer cases about)
  | |
  | C stable (named branch), public
  | :
  | |
  | B stable (named branch), public
  |/
  A

Example 2 - Multiple heads in the "default" named branch:

  E default (named branch), public, has a bigger revision number than C.
  :
  | D default (named branch), draft (only commit the developer cases about)
  | |
  | C default (named branch), public
  | :
  | |
  | B default (named branch), public
  |/
  A


Explanation of the `min(!public() & ::.)^` revset:

With modern Mercurial, `!public()` is the way to select local commits that
do not exist on other developer's repos. `& ::.` limits commits to only the
current "feature branch" (branch in terms of the commit DAG, not hg named
branches).  `min` selects the first commit in the non-public feature branch,
and `^` selects its immediate parent. Note: it's `!public() & ::.` instead
of `::. & !public()` intentionally, because the former has a fast path [1].

[1]: See https://www.mercurial-scm.org/repo/hg/rev/c6c8a52e28c9077580dd2f0552eb2bd6d5e0d13c
  • Loading branch information
quark-zju committed Feb 13, 2019
1 parent 9ba62ad commit 8a9b713
Showing 1 changed file with 1 addition and 12 deletions.
13 changes: 1 addition & 12 deletions packages/jest-changed-files/src/hg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,6 @@ import {Path, Options, SCMAdapter} from './types';

const env = {...process.env, HGPLAIN: '1'};

const ANCESTORS = [
// Parent commit to this one.
'.^',

// The first commit of my branch, only if we are not on the default branch.
'min(branch(.)) and not min(branch(default))',

// Latest public commit.
'max(public())',
];

const adapter: SCMAdapter = {
findChangedFiles: async (
cwd: string,
Expand All @@ -33,7 +22,7 @@ const adapter: SCMAdapter = {

const args = ['status', '-amnu'];
if (options && options.withAncestor) {
args.push('--rev', `ancestor(${ANCESTORS.join(', ')})`);
args.push('--rev', `min(!public() & ::.)^`);
} else if (options && options.changedSince) {
args.push('--rev', `ancestor(., ${options.changedSince})`);
} else if (options && options.lastCommit === true) {
Expand Down

0 comments on commit 8a9b713

Please sign in to comment.