Software companies
Rejected pull requests: why abandoned code changes are valuable
By SourceX Editorial · Updated
Short answer
Rejected pull requests are valuable because each one pairs a plausible code change with a reviewer's reason for turning it down, the kind of judgment coding agents need to learn. A closed, unmerged PR is worth keeping when its thread explains the rejection and points to what shipped instead; one closed silently by a stale bot adds little.
Key takeaways
- A rejected pull request with a written reason is a negative example with its explanation attached.
- Pairs of rejected and merged changes for the same issue are more useful than either one alone.
- Not every closed, unmerged PR is a rejection; classify closures before counting them.
- Abandoned branches are where secrets, debug code and customer test data tend to hide, so they need their own scan.
Why would anyone want code that never shipped?#
Code that never shipped is useful because the record of a reviewer rejecting it explains what a correct change must avoid. Coding agents are good at producing changes that look plausible; what they lack is an experienced reviewer's sense of why a plausible change is still wrong for this codebase.
A rejected pull request captures that judgment where it happened. The diff shows the attempt, the review comments name the problem, and the follow-up shows the accepted approach. For evaluation, the same record becomes a test: can a model spot the issue the human reviewer spotted?
Few teams think of this history as worth keeping. It sits in the code host as closed, unmerged pull requests, and it is easy to lose during cleanups and migrations.
Not every closed pull request is a rejection#
Closed pull requests fall into several types, and only some of them record a decision. Classifying them first keeps an inventory from padding its counts with noise and tells a buyer exactly what each slice contains.
The classification can usually be done from metadata: who closed the PR, whether reviews requested changes, whether a later PR references it, and whether a bot was involved.
| Closure type | How to recognize it | Value to AI teams |
|---|---|---|
| Rejected with reasons | Review requested changes or explained a problem, then the PR was closed | High |
| Superseded | Closed with a link to a replacement PR that merged | High, especially as a pair |
| Reverted after merge | Merged, then undone by a revert PR with an explanation | High: the failure surfaced after shipping |
| Exploratory draft | Draft or spike label, closed after discussion | Moderate: shows options considered |
| Duplicate | Closed with a reference to another PR | Low |
| Abandoned by author | No reviews, closed by a stale bot | Low |
| Automated dependency update | Opened and closed by a bot | Usually excluded |
What makes a rejection reason useful?#
A rejection reason is useful when it names the specific problem and, ideally, points to the evidence. A comment such as not now or please rework tells a model nothing; a comment saying the change breaks retries because the handler is not idempotent, with a link to the failing test, tells it a great deal.
Reasons gain value when they connect to something outside the thread: the issue the PR was meant to fix, a design doc that set the rule being enforced, a CI run that failed, or the later PR that took the reviewer's advice. Those links turn a comment into a traceable decision. Tagging each rejection with a reason category also helps a buyer find the slices it needs.
- Correctness: the change fails an edge case or breaks existing behavior.
- Architecture: the fix sits in the wrong layer or bypasses an agreed pattern.
- Performance: the change adds a slow query or an unbounded loop.
- Security: the change exposes data, weakens validation or adds an unsafe dependency.
- Product: the behavior conflicts with a product decision or falls outside scope.
- Convention: the change ignores team standards for tests, naming or error handling.
Illustrative: one rejected pull request, start to finish#
Illustrative: a fictional shipment tracking software company receives a support ticket from a customer whose dashboard shows some deliveries twice. An engineer opens a Jira issue and, soon after, a pull request. The sequence below follows that work to the end.
Kept together, that thread is a complete lesson: a plausible fix, a precise reason it was wrong, the governing design rule and the correct change. If the first pull request is deleted, only the merged change survives, along with the false impression that the right answer was obvious from the start.
- Pull request one filters duplicate delivery events out of the dashboard query.
- A senior reviewer requests changes: the duplicates come from carrier webhooks retried on timeout, so API customers still receive them, and the fix belongs at ingestion.
- The reviewer links the design doc that requires idempotency keys on all inbound webhooks.
- The author closes pull request one with a comment pointing to the new approach.
- Pull request two adds an idempotency key check to the webhook handler and a test that replays the same event twice.
- Pull request two is approved and merged, ships in the next release, and support replies to the customer with the release note.
Where do rejected pull requests get lost?#
Rejected pull requests get lost in three common ways: branch cleanups, history rewrites and moves between code hosts. The pull request page and its comments usually stay on the host, but whether the diff and its commits survive a deleted branch, a force-push or a repository cleanup depends on the host and how it stores pull request references.
Migrations carry the bigger risk. Moving from one code host to another, or from a self-managed server to a cloud service, may carry merged history faithfully while leaving closed pull requests, review threads or deleted branches behind. Migration tools differ, so check what yours carries before the old host is retired, and take these steps first.
- Export closed pull requests with their review comments and events, not only merged ones.
- Preserve the commits behind each closed PR, for example by fetching the host's pull request references or archiving branch heads before branches are pruned.
- Record the link between each closed PR, its issue and any replacement PR.
- Store the export with the date taken and the host and version it came from.
What to check before including rejected changes#
Rejected changes need a closer check than merged code, because abandoned branches rarely went through the cleanup that a merge brings. Debug output, hard-coded credentials and real customer records used as quick test fixtures are more common in work that was never finished.
Secret scanning is the first pass. Gitleaks, an MIT-licensed scanner, looks for passwords, API keys and tokens in git repositories; its maintainer has since declared it feature complete, with future releases limited to security patches, so check the status of any scanner before standardizing on it. Any secret found should be rotated, not just removed from the export.
| Check | Why it matters | Typical action |
|---|---|---|
| Secrets in abandoned commits | Credentials may still be live | Scan every closed PR, rotate and remove |
| Customer data in test fixtures | Quick fixes often copy real records | Replace with synthetic values or exclude |
| Personal remarks in reviews | Blunt comments about named colleagues | Pseudonymize names and drop personal remarks |
| Contractor and outside contributions | Ownership may sit with someone else | Confirm assignment terms with counsel |
| Open-source and vendored code | License terms travel with the code | Exclude it or follow the license conditions |
| Security vulnerability threads | Details could expose live systems | Exclude, or hold until fixed and reviewed |
How SourceX treats rejected changes in a code history package#
SourceX treats closed pull requests as decision records rather than leftovers. In the SourceX Enterprise Data Value Framework, human-generated signal and domain expertise are both value drivers, and a reviewer's written reason for turning down a change is both, so a package that keeps rejected and superseded PRs beside the merged ones usually tells a buyer more than merged code alone.
In the Supply step of the SourceX five-step transaction, the fit check asks only for metadata, such as which hosts and repositories exist and whether closed PRs and review threads are retained. Preparation then covers secrets, fixtures and names, and the SourceX Evidence Packet records which closure types were included and what was removed.
Frequently asked questions
Should we include pull requests closed by stale bots?
Usually not as a main record type. A stale-bot closure records that nobody acted, not that anyone decided. These PRs can be listed in the inventory for completeness, but a package should lead with closures that carry a human reason.
Does a rejected pull request need a linked issue?
It helps but is not essential. A clear review reason and a visible replacement PR can carry the lesson alone. A linked issue adds the original problem statement, which lets a buyer test whether a model can reach the right fix starting from the report.
Are reverted commits the same as rejected pull requests?
No. A revert means the change merged and later caused trouble, so it records a failure that review did not catch. Both are useful, but they teach different things and should be labeled separately in the manifest.
What about pull requests from former employees?
Employment agreements commonly assign work product to the company, but the terms vary, so confirm with counsel. Former employees' names should be pseudonymized like everyone else's, and their review comments kept where they carry useful reasons.
Can we license rejected pull requests without the merged code?
In principle, yes, but the value drops sharply, because a rejection is easiest to learn from next to the change that replaced it. If a repository cannot be included, its review threads and issue links may still be scoped as a smaller record family.
Sources
- Gitleaks is an MIT-licensed tool for detecting secrets such as passwords, API keys and tokens in git repositories, files and stdin; on May 21, 2026, its README was updated to state that Gitleaks is feature complete and future releases will be security patches only. Source
Related resources
- InsightCan engineering firms sell their data to AI companies?
- InsightMetals service centers: AI use cases and licensable records
- InsightHow assignees value and sell intangible assets in an ABC
- IndustryBPO & contact centers data
- IndustryRecruiting & staffing data
- QuestionDo AI companies buy private business data?
See if your company qualifies
A short company assessment. No data uploads are needed.