Support refs/users/self for the GET branch rest endpoint

A user may fetch the magic branch refs/users/self and this branch is
resolved to the user branch of the calling user
> git fetch origin refs/users/self

This change adds support for this magic ref to the GET Branch rest
endpoint. This only works if the repository is All-Users.

Change-Id: I2d56a8896e0b701351e10e22ba6012ed28d53117
This commit is contained in:
Youssef Elghareeb
2020-10-26 19:02:39 +01:00
parent b7dadde0bf
commit a5639fcef6
6 changed files with 26 additions and 7 deletions

View File

@@ -1702,7 +1702,9 @@ List all branches that match regex `t.*1`:
'GET /projects/link:#project-name[\{project-name\}]/branches/link:#branch-id[\{branch-id\}]'
--
Retrieves a branch of a project.
Retrieves a branch of a project. For the "All-Users" repository, the magic
branch "refs/users/self" is automatically resolved to the user branch of the
calling user.
.Request
----

View File

@@ -255,6 +255,10 @@ public class RefNames {
return ref.startsWith(REFS_USERS);
}
public static boolean isRefsUsersSelf(String ref, boolean isAllUsers) {
return isAllUsers && REFS_USERS_SELF.equals(ref);
}
/**
* Whether the ref is a group branch that stores NoteDb data of a group. Returns {@code true} for
* all refs that start with {@code refs/groups/}.

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.server.api.projects;
import static com.google.gerrit.server.api.ApiUtil.asRestApiException;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.api.projects.BranchApi;
import com.google.gerrit.extensions.api.projects.BranchInfo;
import com.google.gerrit.extensions.api.projects.BranchInput;
@@ -126,6 +127,10 @@ public class BranchApiImpl implements BranchApi {
private BranchResource resource()
throws RestApiException, IOException, PermissionBackendException {
return branches.parse(project, IdString.fromDecoded(ref));
String refName = ref;
if (RefNames.isRefsUsersSelf(ref, project.getProjectState().isAllUsers())) {
refName = RefNames.refsUsers(project.getUser().getAccountId());
}
return branches.parse(project, IdString.fromDecoded(refName));
}
}

View File

@@ -21,6 +21,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.flogger.LazyArgs.lazy;
import static com.google.gerrit.entities.RefNames.REFS_CHANGES;
import static com.google.gerrit.entities.RefNames.isConfigRef;
import static com.google.gerrit.entities.RefNames.isRefsUsersSelf;
import static com.google.gerrit.git.ObjectIds.abbreviateName;
import static com.google.gerrit.server.change.HashtagsUtil.cleanupHashtag;
import static com.google.gerrit.server.git.MultiProgressMonitor.UNKNOWN;
@@ -1080,7 +1081,7 @@ class ReceiveCommits {
private ReceiveCommand wrapReceiveCommand(ReceiveCommand cmd, Task progress) {
String refname = cmd.getRefName();
if (projectState.isAllUsers() && RefNames.REFS_USERS_SELF.equals(cmd.getRefName())) {
if (isRefsUsersSelf(cmd.getRefName(), projectState.isAllUsers())) {
refname = RefNames.refsUsers(user.getAccountId());
logger.atFine().log("Swapping out command for %s to %s", RefNames.REFS_USERS_SELF, refname);
}

View File

@@ -143,7 +143,11 @@ public class ListBranches implements RestReadView<ProjectResource> {
BranchInfo toBranchInfo(BranchResource rsrc)
throws IOException, ResourceNotFoundException, PermissionBackendException {
try (Repository db = repoManager.openRepository(rsrc.getNameKey())) {
Ref r = db.exactRef(rsrc.getRef());
String refName = rsrc.getRef();
if (RefNames.isRefsUsersSelf(refName, rsrc.getProjectState().isAllUsers())) {
refName = RefNames.refsUsers(rsrc.getUser().getAccountId());
}
Ref r = db.exactRef(refName);
if (r == null) {
throw new ResourceNotFoundException();
}

View File

@@ -262,9 +262,12 @@ public class GetBranchIT extends AbstractDaemonTest {
requestScopeOperations.setApiUser(user.id());
assertBranchFound(allUsers, RefNames.refsUsers(user.id()));
// TODO: every user can see the own user ref via the magic ref/users/self ref
// requestScopeOperations.setApiUser(user.id());
// assertBranchFound(allUsers, RefNames.REFS_USERS_SELF);
// every user can see the own user ref via the magic ref/users/self ref. For this special case,
// the branch in the request is refs/users/self, but the response contains the actual
// refs/users/$sharded_id/$id
BranchInfo branchInfo =
gApi.projects().name(allUsers.get()).branch(RefNames.REFS_USERS_SELF).get();
assertThat(branchInfo.ref).isEqualTo(RefNames.refsUsers(user.id()));
}
@Test