diff --git a/src/main/java/hudson/plugins/git/BranchSpec.java b/src/main/java/hudson/plugins/git/BranchSpec.java
index 2c6ce09367..fba6efdaeb 100644
--- a/src/main/java/hudson/plugins/git/BranchSpec.java
+++ b/src/main/java/hudson/plugins/git/BranchSpec.java
@@ -159,6 +159,9 @@ private Pattern getPattern(EnvVars env, String repositoryName) {
String regexSubstring = expandedName.substring(1, expandedName.length());
return Pattern.compile(regexSubstring);
}
+ if (expandedName.startsWith("refs/changes/")) {
+ return Pattern.compile(Pattern.quote(expandedName));
+ }
if (repositoryName != null) {
// remove the "refs/.../" stuff from the branch-spec if necessary
String pattern = cutRefs(expandedName)
diff --git a/src/main/java/jenkins/plugins/git/GitSCMFileSystem.java b/src/main/java/jenkins/plugins/git/GitSCMFileSystem.java
index 2165734450..ca610a65d3 100644
--- a/src/main/java/jenkins/plugins/git/GitSCMFileSystem.java
+++ b/src/main/java/jenkins/plugins/git/GitSCMFileSystem.java
@@ -267,6 +267,9 @@ public boolean supports(SCM source) {
|| gscm.getBranches().get(0).getName().matches(
"^((\\Q" + Constants.R_TAGS + "\\E.*)|([^/]+)|(\\*/[^/*]+(/[^/*]+)*))$"
)
+ || gscm.getBranches().get(0).getName().matches(
+ "^((\\Qrefs/changes/\\E.*)|([^/]+)|(\\*/[^/*]+(/[^/*]+)*))$"
+ )
);
// we only support where the branch spec is obvious and not a wildcard
}
@@ -306,6 +309,8 @@ static HeadNameResult calculate(@NonNull BranchSpec branchSpec,
String prefix = Constants.R_HEADS;
if (branchSpecExpandedName.startsWith(Constants.R_TAGS)) {
prefix = Constants.R_TAGS;
+ } else if (branchSpecExpandedName.startsWith("refs/changes")) {
+ prefix = "refs/changes/";
}
String headName;
diff --git a/src/main/resources/hudson/plugins/git/BranchSpec/help-name.html b/src/main/resources/hudson/plugins/git/BranchSpec/help-name.html
index 7c39aee1fd..3548b4846e 100644
--- a/src/main/resources/hudson/plugins/git/BranchSpec/help-name.html
+++ b/src/main/resources/hudson/plugins/git/BranchSpec/help-name.html
@@ -47,6 +47,10 @@
Tracks/checks out the specified tag.
E.g. refs/tags/git-2.3.0
+
refs/changes/<gerritChange>refs/changes/91/45391/1
+ <commitId>5062ac843f2b947733e6a3b105977056821bd352, 5062ac84, ...
diff --git a/src/test/java/hudson/plugins/git/BranchSpecTest.java b/src/test/java/hudson/plugins/git/BranchSpecTest.java
index 835cf16a5b..27b82e6bac 100644
--- a/src/test/java/hudson/plugins/git/BranchSpecTest.java
+++ b/src/test/java/hudson/plugins/git/BranchSpecTest.java
@@ -149,6 +149,14 @@ void testUsesRefsHeads() {
assertFalse(m.matches("remote/origin/jane"));
}
+ @Test
+ public void testMatchesGerritChangeRef() {
+ BranchSpec spec = new BranchSpec("refs/changes/91/45391/1");
+
+ assertTrue(spec.matches("refs/changes/91/45391/1"));
+ assertFalse(spec.matches("refs/heads/refs/changes/91/45391/1"));
+ }
+
@Test
void testUsesJavaPatternDirectlyIfPrefixedWithColon() {
BranchSpec m = new BranchSpec(":^(?!(origin/prefix)).*");
diff --git a/src/test/java/jenkins/plugins/git/GitSCMFileSystemTest.java b/src/test/java/jenkins/plugins/git/GitSCMFileSystemTest.java
index ffee98ff89..41923f1d3e 100644
--- a/src/test/java/jenkins/plugins/git/GitSCMFileSystemTest.java
+++ b/src/test/java/jenkins/plugins/git/GitSCMFileSystemTest.java
@@ -435,6 +435,29 @@ void create_SCMFileSystem_from_tag() throws Exception {
assertThat(file.contentAsString(), is("modified"));
}
+ @Test
+ public void testSupportsGerritChangeRef() throws Exception {
+ // Create a dummy GitSCM configured with a Gerrit change refspec
+ GitSCM scm = new GitSCM(
+ GitSCM.createRepoList("https://example.com/repo.git", null),
+ Collections.singletonList(new BranchSpec("refs/changes/91/45391/1")),
+ null, null, Collections.emptyList());
+
+ GitSCMFileSystem.BuilderImpl builder = new GitSCMFileSystem.BuilderImpl();
+ assertTrue(builder.supports(scm), "Builder should support refs/changes/ branch specs");
+ }
+
+ @Test
+ public void testHeadNameResultCalculateGerritChange() {
+ BranchSpec spec = new BranchSpec("refs/changes/91/45391/1");
+
+ GitSCMFileSystem.BuilderImpl.HeadNameResult result =
+ GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(spec, null, null);
+
+ assertEquals("refs/changes/", result.prefix);
+ assertEquals("91/45391/1", result.headName);
+ }
+
@Issue("JENKINS-52964")
@Test
void filesystem_supports_descriptor() throws Exception {