Skip to content

[JENKINS-70303] Trim leading/trailing whitespace from refspecs - #3989

Open
Racknaraock wants to merge 2 commits into
jenkinsci:masterfrom
Racknaraock:JENKINS-70303-trim-refspec
Open

[JENKINS-70303] Trim leading/trailing whitespace from refspecs#3989
Racknaraock wants to merge 2 commits into
jenkinsci:masterfrom
Racknaraock:JENKINS-70303-trim-refspec

Conversation

@Racknaraock

@Racknaraock Racknaraock commented Jul 24, 2026

Copy link
Copy Markdown

[JENKINS-70303] Trim leading/trailing whitespace from refspecs

Problem

When a user-supplied refspec has a leading space (e.g. " +refs/heads/master:refs/remotes/origin/master"), JGit's RefSpec parser fails to recognize the + force-update marker because the space hides it, and the checkout fails with "Remote does not have available for fetch." Command-line git tolerates this kind of extra whitespace; JGit does not.

Reported in JENKINS-70303 against Jenkins 2.375.1 / git plugin 4.14.3 / git client plugin 3.13.1 and jenkinsci/git-client-plugin#1663

Related prior work

Both prior attempts targeted git-client-plugin (the lower-level git client abstraction), not git-plugin:

  • git-client-plugin#1095 — a small patch to JGitAPIImpl.java only. Closed for inactivity after review feedback asking for: a link to the issue, an automated test, and fixing a new spotbugs warning it introduced. None of that was addressed before it went stale.
  • git-client-plugin#1096 — a much more thorough attempt, trimming refspecs across GitAPI.java, CliGitAPIImpl.java, JGitAPIImpl.java, LegacyCompatibleGitAPIImpl.java and RemoteGitImpl.java, with tests, and with maintainer (Mark Waite) commits directly on the branch. Still open as of this writing, opened January 2024, no activity since March 2024 — stalled despite being close to mergeable.

This PR takes a different, narrower approach: instead of patching the git-client abstraction (CLI and/or JGit implementations), it trims the refspec at the two points in git-plugin where a user-supplied refspec string is first turned into a RefSpec/config value, before it ever reaches git-client:

  • UserRemoteConfig constructor (classic Freestyle GitSCM / data-bound form submission)
  • GitSCMBuilder.asRefSpecs() (multibranch GitSCMSource)

This covers both entry points with a much smaller diff, doesn't touch the JGit/CLI client layer at all (so it doesn't depend on #1096 landing), and avoids the spotbugs issue that sank #1095.

Changes

  • UserRemoteConfig.java: use fixEmptyAndTrim(refspec) instead of fixEmpty(refspec) in the constructor.
  • GitSCMBuilder.java: call refSpec.trim() before constructing each RefSpec in asRefSpecs().

Testing

  • New unit tests covering both fixed entry points:

    • UserRemoteConfigRefSpecTest.constructorTrimsLeadingAndTrailingWhitespaceFromRefspec
    • GitSCMBuilderTest.withRefSpecLeadingAndTrailingWhitespace
  • Targeted test run (UserRemoteConfigRefSpecTest, GitSCMBuilderTest): green.

  • Full mvn compile test-compile: clean, no errors.

  • Coverage (mvn -P enable-jacoco test jacoco:report): both modified lines are fully exercised (0 missed instructions) — UserRemoteConfig.java:60 and GitSCMBuilder.java:442. File-level: GitSCMBuilder.java 96.4% instruction / 96.5% line coverage; UserRemoteConfig.java 26.0% instruction / 27.1% line coverage (this class has many unrelated getters/validators not exercised by this slice of the suite).

  • Manual verification on a local mvn hpi:run Jenkins instance: configured a Freestyle job against a local repo with a refspec containing leading/trailing spaces. Confirmed in the saved config.xml that the stored refspec is trimmed (+refs/heads/feature-branch:refs/remotes/origin/feature-branch, no surrounding whitespace), and the checkout completed successfully.

Checklist (per CONTRIBUTING.adoc)

  • Read CONTRIBUTING.adoc
  • Referenced the Jira issue in commit messages
  • Added tests that verify the change
  • Unit tests pass locally
  • Interactively tested the change

A refspec with a leading space is not recognized as a force-update
spec by JGit's RefSpec parser (the leading space hides the '+'),
and the untrimmed spec can also be split into a spurious empty
refspec by GitSCM's config-based fetch refspec handling. Trim the
refspec at the two points where user-supplied refspec strings are
first converted into RefSpec/config values.
Covers both fixed entry points: UserRemoteConfig's constructor
(classic GitSCM / Freestyle) and GitSCMBuilder.asRefSpecs()
(multibranch GitSCMSource).
@Racknaraock
Racknaraock requested a review from a team as a code owner July 24, 2026 17:55
@github-actions github-actions Bot added the tests Automated test addition or improvement label Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests Automated test addition or improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant