jj-octo 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/jj-octo.js +30 -14
  2. package/package.json +1 -1
package/dist/jj-octo.js CHANGED
@@ -18112,7 +18112,7 @@ var layer14 = /* @__PURE__ */ layerMergedContext(/* @__PURE__ */ succeed6(fetch)
18112
18112
  // package.json
18113
18113
  var package_default = {
18114
18114
  name: "jj-octo",
18115
- version: "0.3.0",
18115
+ version: "0.3.1",
18116
18116
  description: "A jj subcommand for working with GitHub that supports stacking",
18117
18117
  license: "MIT",
18118
18118
  repository: {
@@ -18478,6 +18478,10 @@ var PullRequests = responseOf()(ArraySchema(Struct({
18478
18478
  number: PullRequestNumberSchema,
18479
18479
  title: String4
18480
18480
  })));
18481
+ var ClosedPullRequests = responseOf()(ArraySchema(Struct({
18482
+ head: Struct({ sha: String4 }),
18483
+ merged_at: NullOr(String4)
18484
+ })));
18481
18485
  var StackedPullRequest = Struct({
18482
18486
  number: PullRequestNumberSchema,
18483
18487
  state: Literals(["closed", "open"])
@@ -18521,6 +18525,7 @@ var GitHubLive = (repository, connection) => {
18521
18525
  open: stack.pull_requests.filter(({ state }) => state === "open").map(({ number }) => number)
18522
18526
  }))));
18523
18527
  const mergeRequest = (path) => json(MergeResult)(get4(repo(path)));
18528
+ const fromBranch = (branch, state) => repo(`/pulls?state=${state}&head=${repository.owner}:${encodeURIComponent(branch)}`);
18524
18529
  return {
18525
18530
  addToStack: (stack, pullRequests) => send(post(repo(`/stacks/${stack}/add`)).pipe(bodyOf({ pull_requests: [...pullRequests] }))).pipe(asVoid2),
18526
18531
  createPullRequest: ({ base, body, draft, head, title }) => json(CreatedPullRequest)(post(repo("/pulls")).pipe(bodyOf({ base, body, draft, head, title }))).pipe(map7(({ number }) => number)),
@@ -18549,7 +18554,8 @@ var GitHubLive = (repository, connection) => {
18549
18554
  message: `merging #${pullRequest} ended ${settled.status}: ${settled.details.message}`
18550
18555
  });
18551
18556
  }),
18552
- openPullRequest: (branch) => json(PullRequests)(get4(repo(`/pulls?state=open&head=${repository.owner}:${encodeURIComponent(branch)}`))).pipe(map7((found) => map(fromNullishOr(found[0]), ({ base, body, draft, number, title }) => ({
18557
+ mergedHeads: (branch) => json(ClosedPullRequests)(get4(fromBranch(branch, "closed"))).pipe(map7((closed) => closed.filter(({ merged_at }) => merged_at !== null).map(({ head }) => head.sha))),
18558
+ openPullRequest: (branch) => json(PullRequests)(get4(fromBranch(branch, "open"))).pipe(map7((found) => map(fromNullishOr(found[0]), ({ base, body, draft, number, title }) => ({
18553
18559
  base: base.ref,
18554
18560
  body: body ?? "",
18555
18561
  draft: draft ?? false,
@@ -18949,20 +18955,31 @@ var rebaseStack = (root, required) => gen2(function* () {
18949
18955
  yield* error(`left "${name}" and the changes on it where they were: they conflict with the trunk`);
18950
18956
  }
18951
18957
  });
18952
- var sync4 = (required = [], mergedChanges = []) => gen2(function* () {
18958
+ var mergedOnGitHub = (bookmarks) => gen2(function* () {
18959
+ const github = yield* GitHub;
18960
+ const merged = yield* forEach2(bookmarks.filter(({ remote }) => remote !== undefined), ({ change, local, name }) => github.mergedHeads(name).pipe(map7((heads) => heads.includes(local) ? [{ bookmark: name, changeId: change }] : [])), { concurrency: "unbounded" });
18961
+ return merged.flat();
18962
+ });
18963
+ var sync4 = (known = []) => gen2(function* () {
18953
18964
  const jj = yield* Jj;
18954
18965
  const before = yield* bookmarksBeforeFetch;
18966
+ const merged = [
18967
+ ...known,
18968
+ ...yield* mergedOnGitHub(before.filter(({ name }) => known.every(({ bookmark }) => bookmark !== name)))
18969
+ ];
18955
18970
  yield* jj.run(["git", "fetch"]);
18956
- for (const { bookmark } of mergedChanges) {
18971
+ for (const { bookmark } of merged) {
18957
18972
  yield* jj.run(["bookmark", "forget", "--include-remotes", `exact:${bookmark}`]);
18958
18973
  }
18959
- if (mergedChanges.length > 0) {
18960
- const revset = mergedChanges.map(({ changeId }) => `change_id(${changeId})`).join(" | ");
18961
- yield* jj.run(["abandon", `(${revset}) & mutable()`]);
18974
+ const mergedRevset = `(${["none()", ...merged.map(({ changeId }) => `change_id(${changeId})`)].join(" | ")}) & mutable()`;
18975
+ const required = yield* changeIdsAt(`(${mergedRevset}):: ~ (${mergedRevset})`);
18976
+ if (merged.length > 0) {
18977
+ yield* jj.run(["abandon", mergedRevset]);
18978
+ yield* error(`abandoned the changes whose pull requests merged: ${merged.map(({ bookmark }) => bookmark).join(", ")}`);
18962
18979
  }
18963
18980
  const fetched = yield* bookmarkTargets;
18964
18981
  const notCombined = [];
18965
- for (const bookmark of before.filter(({ name }) => mergedChanges.every((change) => change.bookmark !== name))) {
18982
+ for (const bookmark of before.filter(({ name }) => merged.every((change) => change.bookmark !== name))) {
18966
18983
  if (!(yield* combine4(bookmark, fetched.get(bookmark.name)?.origin))) {
18967
18984
  notCombined.push(bookmark.name);
18968
18985
  }
@@ -18970,8 +18987,8 @@ var sync4 = (required = [], mergedChanges = []) => gen2(function* () {
18970
18987
  for (const root of yield* commitsAt(BEHIND_ROOTS)) {
18971
18988
  yield* rebaseStack(root, required);
18972
18989
  }
18973
- const merged = (yield* bookmarksAt("::trunk()")).filter((name) => before.some((bookmark) => bookmark.name === name));
18974
- for (const name of merged) {
18990
+ const onTrunk = (yield* bookmarksAt("::trunk()")).filter((name) => before.some((bookmark) => bookmark.name === name));
18991
+ for (const name of onTrunk) {
18975
18992
  yield* jj.run(["bookmark", "forget", "--include-remotes", `exact:${name}`]);
18976
18993
  }
18977
18994
  if (notCombined.length > 0) {
@@ -18988,7 +19005,7 @@ var sync4 = (required = [], mergedChanges = []) => gen2(function* () {
18988
19005
  var syncCommand = make30("sync", {}, () => asUserError(gen2(function* () {
18989
19006
  yield* checkTrunk(yield* (yield* GitHub).defaultBranch);
18990
19007
  yield* sync4();
18991
- }).pipe(provide3(GitHubFromOrigin)))).pipe(withHelp("Fetch, and rebase every change onto the trunk", "Fetches, then rebases every change that isn't merged yet onto the trunk, keeping each on the changes below it. A change that has merged is empty after the rebase, so it's abandoned and its bookmark forgotten.", "A stack that would conflict with the trunk is left where it was, and named. Rebase it yourself with `jj rebase` when you want to resolve it.", "Commits added to a branch on GitHub are squashed into the branch's local change, whether or not that change was also edited locally. Where GitHub only rebased a branch, the local change is kept.", "Fails before fetching if `trunk()` isn't GitHub's default branch, which `jj gh init` sets.", "Pushes nothing. Run `jj gh submit` to update the pull requests of a change and the ones below it."));
19008
+ }).pipe(provide3(GitHubFromOrigin)))).pipe(withHelp("Fetch, and rebase every change onto the trunk", "Fetches, then rebases every change that isn't merged yet onto the trunk, keeping each on the changes below it. A change whose pull request GitHub merged is abandoned and its bookmark forgotten, unless it was edited after the merge.", "A stack that would conflict with the trunk is left where it was, and named. Rebase it yourself with `jj rebase` when you want to resolve it. The rest of a stack whose changes merged is rebased even where it conflicts, and the conflict is recorded in the change.", "Commits added to a branch on GitHub are squashed into the branch's local change, whether or not that change was also edited locally. Where GitHub only rebased a branch, the local change is kept.", "Fails before fetching if `trunk()` isn't GitHub's default branch, which `jj gh init` sets.", "Pushes nothing. Run `jj gh submit` to update the pull requests of a change and the ones below it."));
18992
19009
 
18993
19010
  // src/cli/gh/merge.ts
18994
19011
  class NotMergeable extends TaggedError2("NotMergeable") {
@@ -19035,12 +19052,11 @@ var merge5 = (revision) => gen2(function* () {
19035
19052
  }
19036
19053
  const pullRequest = yield* openPullRequestOf(top);
19037
19054
  const above = yield* bookmarksAt(upstackRevset(bookmarkRevset(top)));
19038
- const stackChanges = yield* changeIdsAt(stackRevset(revision));
19039
19055
  if ((yield* mergeOnGitHub(pullRequest, trunk)) === "enqueued") {
19040
19056
  yield* error("queued to merge; run `jj gh sync` once it has");
19041
19057
  } else {
19042
19058
  yield* error(`merged up to #${pullRequest.number}`);
19043
- yield* sync4(stackChanges, changes);
19059
+ yield* sync4(changes);
19044
19060
  for (const bookmark of above) {
19045
19061
  if ((yield* commitsAt(bookmarkRevset(bookmark))).length > 0) {
19046
19062
  yield* republish(bookmarkRevset(bookmark));
@@ -19049,7 +19065,7 @@ var merge5 = (revision) => gen2(function* () {
19049
19065
  }
19050
19066
  }
19051
19067
  });
19052
- var mergeCommand = make30("merge", { revision: revisionFlag("The top change to merge") }, ({ revision }) => asUserError(merge5(revision).pipe(provide3(GitHubFromOrigin)))).pipe(withHelp("Merge the pull requests of a change and the ones below it", "Squash-merges them, and prints which before it does. An empty working copy means the change below it. Fails before merging if any of the changes has edits that aren't pushed.", "A pull request in a GitHub stack is merged together with the pull requests below it. Either all of them merge or none does. A pull request outside a stack is merged alone, and only if its base is the trunk.", "Then syncs, as `jj gh sync` does, and pushes what is left of the change's stack again, up to the highest branch already on GitHub. Unlike `jj gh sync`, it abandons the merged changes and forgets their bookmarks, rather than relying on each coming out empty on the trunk, which one doesn't where a change merged above it edited the same lines. It also rebases the rest of the stack even where it conflicts with the trunk, and the conflict is recorded in the change.", "If GitHub queues the merge instead, nothing is synced. Run `jj gh sync` once it has merged."));
19068
+ var mergeCommand = make30("merge", { revision: revisionFlag("The top change to merge") }, ({ revision }) => asUserError(merge5(revision).pipe(provide3(GitHubFromOrigin)))).pipe(withHelp("Merge the pull requests of a change and the ones below it", "Squash-merges them, and prints which before it does. An empty working copy means the change below it. Fails before merging if any of the changes has edits that aren't pushed.", "A pull request in a GitHub stack is merged together with the pull requests below it. Either all of them merge or none does. A pull request outside a stack is merged alone, and only if its base is the trunk.", "Then syncs, as `jj gh sync` does: it abandons the merged changes, forgets their bookmarks, and rebases the rest of the stack onto the trunk even where it conflicts, recording the conflict in the change. Then it pushes what is left of the change's stack again, up to the highest branch already on GitHub.", "If GitHub queues the merge instead, nothing is synced. Run `jj gh sync` once it has merged."));
19053
19069
 
19054
19070
  // src/cli/gh/submit.ts
19055
19071
  var submitCommand = make30("submit", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jj-octo",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "A jj subcommand for working with GitHub that supports stacking",
5
5
  "license": "MIT",
6
6
  "repository": {