Graphite

Cursor Cloud Agents are now in Graphite. Create, review, and ship without leaving your PR.

Read more

The new standard for developer infrastructure

Graphite CLI

Streamline Git commands and seamlessly stack pull requests from your terminal.

Pull request inbox

Stay on top of every PR and review request in one unified inbox.

Graphite Chat

Get immediate, actionable feedback on every pull request with Graphite Chat.

Merge Queue

Eliminate merge conflicts and keep your main branch green—whether you're a team of 10 or 10,000.

Insights and reports

Accelerate your team with powerful, real-time developer metrics.

Start a stack

Create the first branch in your stack with gt create.

Keep stacking

Run gt create again to stack another branch on top of your previous changes without waiting for them to merge into main.

Visualize your stack

Get a bird's eye view of your stack with gt log.

Publish your stack

Create or update PRs for every branch in your stack with gt submit.

Respond to feedback

Update changes across your stack with gt modify. Graphite handles all of the recursive rebasing for you.

Ship, sync, repeat

Automatically sync your local stack with remote changes, and clean up stale branches with gt sync.

Every change in one place

Stay on top of your team's pull requests from one dashboard. See reviews, CI status, stack info, and everything else you need to know about your PRs.

Fully customizable

Customize each inbox section to match your workflow. Filter PRs based on author, CI status, reviews, labels, and much, much more.

As fast as you are

Keyboard shortcuts, at-a-glance statuses, and real-time GitHub sync help you stay up-to-date and take action on things that need your attention.

Pull requests the way they should be

File diffs, version history, comments, and CI in one intuitive interface. Code review has never been this enjoyable.

42+export const updateBaseBranchIfNecessary = async ({

43+ pr,

44+ newMergeBase,

45+ actor,

46+ serverContext,

47+}: {

48+ pr: PrToRebase;

49+ newMergeBase: string;

50+ actor: GithubCachedActorWithHost;

51+ serverContext: TServerContext;

52+}) => {

53+ const { owner, repo, number } = pr;

54

55+ const skipUpdateBaseBranchIfUnchanged =

56+ await serverContext.clients.statsig.checkOrgBasedFlagDeprecated({

57+ configName: "skip_update_base_branch_if_unchanged",

58+ orgGithubLogins: [owner],

59+ splog: serverContext.splog,

60+ });

61

62+ if (skipUpdateBaseBranchIfUnchanged) {

63+ const freshPr =

64+ await serverContext.clients.githubCache.pullRequests.getFreshPrAndCache({

65+ githubClient,

66+ owner,

67+ repo,

68+ number,

69+ source: "REBASE_UPDATE_BASE_BRANCH",

70+ config: {

71+ await: true,

72+ },

73+ });

74

75+ if (freshPr && freshPr.baseRef.name === newMergeBase) {

76+ return;

77+ }

78+ }

79

80+ const sleepSeconds = await determineSleepTime({ owner, serverContext });

81+ await sleep({ seconds: sleepSeconds });

82

83+ serverContext.splog.verbose({

84+ message: `Updating PR base branch after rebase`,

85+ tags: { pr, newMergeBase },

86+ });

87

88+ await updatePrBase({

89+ owner,

90+ repo,

91+ prNumber: pr.number,

92+ base: newMergeBase,

93+ githubClient,

94+ context: serverContext,

95+ });

96+};

97

98+export async function rebasePullRequest({

99+ pr,

100+ actor,

101+ newMergeBase,

102+ stackJobId,

103+ gitClient,

104+ serverContext,

105+}: {

106+ pr: PrToRebase;

107+ actor: GithubCachedActorWithHost;

108+ newMergeBase: string;

109+ stackJobId: string;

110+ gitClient: GitClient;

111+ serverContext: TServerContext;

112+}): Promise<RebaseResult> {

113+ const rebaseStartTime = DateTime.now();

114+ const rebaseResult = await gitClient.rebaseUnmergedRange({

115+ headBranch: pr.headBranch,

116+ trunkBranch: newMergeBase,

117+ });

118

119+ const durationMs = startTime

120+ .diff(DateTime.now())

121+ .as("milliseconds");

122

123+ serverContext.splog.verbose({

124+ message: `Rebase completed in ${rebaseDurationMs}ms`,

125+ tags: {

126+ rebaseDurationMs,

127+ pr,

128+ newMergeBase,

129+ },

130+ });

131

132+ if (rebaseResult !== "SUCCESS") {

133+ serverContext.splog.warn({

134+ message: `Failed to rebase ${pr.owner}/${pr.repo}#${pr.number}`,

135+ tags: {

136+ pr,

137+ newMergeBase,

138+ rebaseResult,

139+ },

140+ });

141+ return { result: rebaseResult };

142+ }

Graphite Chat automatically scans opened PRs for bugs, logical errors, and other technical pitfalls so reviewers can focus on the big picture.

Graphite Chat ensures that every piece of feedback makes sense in the context of your codebase.

Define and enforce custom patterns with AI prompts and regex.

Beyond vanity

Visualize and track data-driven metrics that are proven to enhance developer productivity.

Transparency

Graphite Insights empowers every member of your team with data—regardless of their role.

A historical record

Graphite Insights measures developer trends over time, allowing you to identify and fix bottlenecks in your engineering workflow.

Keep changes flowing

Graphite Merge Queue puts your merge process on autopilot, keeping your engineers unblocked.

Merge from anywhere

Merge PRs from Graphite, GitHub, or even your terminal.

Save money and CI time

Powerful CI optimizations skip redundant tests, saving you time and money.

Read the original on graphite.com ↗