mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-10 15:35:49 +01:00
Add repository-specific non-ff disallowed option (#1579)
Co-authored-by: René Pfeuffer <rene.pfeuffer@cloudogu.com>
This commit is contained in:
BIN
docs/de/user/repo/assets/repository-settings-general-git.png
Normal file
BIN
docs/de/user/repo/assets/repository-settings-general-git.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -11,6 +11,9 @@ Unter dem Eintrag "Generell" kann man die Zusatzinformationen zum Repository edi
|
|||||||
Git Repository handelt, kann ebenfalls der Standard-Branch für dieses Repository gesetzt werden. Der Standard-Branch
|
Git Repository handelt, kann ebenfalls der Standard-Branch für dieses Repository gesetzt werden. Der Standard-Branch
|
||||||
sorgt dafür, dass beim Arbeiten mit diesem Repository dieser Branch vorrangig geöffnet wird, falls kein expliziter
|
sorgt dafür, dass beim Arbeiten mit diesem Repository dieser Branch vorrangig geöffnet wird, falls kein expliziter
|
||||||
Branch ausgewählt wurde.
|
Branch ausgewählt wurde.
|
||||||
|
Außerdem können Git Pushes auf Repository-Ebene abgelehnt werden, die nicht "fast-forward" sind.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
Innerhalb der Gefahrenzone unten auf der Seite gibt es mit entsprechenden Rechten die Möglichkeit das Repository
|
Innerhalb der Gefahrenzone unten auf der Seite gibt es mit entsprechenden Rechten die Möglichkeit das Repository
|
||||||
umzubenennen, zu löschen oder als archiviert zu markieren. Wenn in der globalen SCM-Manager Konfiguration die Namespace
|
umzubenennen, zu löschen oder als archiviert zu markieren. Wenn in der globalen SCM-Manager Konfiguration die Namespace
|
||||||
|
|||||||
BIN
docs/en/user/repo/assets/repository-settings-general-git.png
Normal file
BIN
docs/en/user/repo/assets/repository-settings-general-git.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 96 KiB |
@@ -10,6 +10,9 @@ can be considerably more items.
|
|||||||
The "General" item allows you to edit the additional information of the repository. Git repositories for example also
|
The "General" item allows you to edit the additional information of the repository. Git repositories for example also
|
||||||
have the option to change the default branch here. The default branch is the one that is used when working with the
|
have the option to change the default branch here. The default branch is the one that is used when working with the
|
||||||
repository if no specific branch is selected.
|
repository if no specific branch is selected.
|
||||||
|
In addition, Git pushes which are non fast-forward can be rejected at the repository level.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
In the danger zone at the bottom you may rename the repository, delete it or mark it as archived. If the namespace
|
In the danger zone at the bottom you may rename the repository, delete it or mark it as archived. If the namespace
|
||||||
strategy in the global SCM-Manager config is set to `custom` you may even rename the repository namespace. If a
|
strategy in the global SCM-Manager config is set to `custom` you may even rename the repository namespace. If a
|
||||||
|
|||||||
2
gradle/changelog/repository_fastforward.yaml
Normal file
2
gradle/changelog/repository_fastforward.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
- type: added
|
||||||
|
description: Add repository-specific non-fast-forward disallowed option ([#1579](https://github.com/scm-manager/scm-manager/issues/1579))
|
||||||
@@ -40,6 +40,8 @@ public class GitRepositoryConfigDto extends HalRepresentation implements UpdateG
|
|||||||
|
|
||||||
private String defaultBranch;
|
private String defaultBranch;
|
||||||
|
|
||||||
|
private boolean nonFastForwardDisallowed;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("squid:S1185") // We want to have this method available in this package
|
@SuppressWarnings("squid:S1185") // We want to have this method available in this package
|
||||||
protected HalRepresentation add(Links links) {
|
protected HalRepresentation add(Links links) {
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ public class GitRepositoryConfigResource {
|
|||||||
schema = @Schema(implementation = UpdateGitRepositoryConfigDto.class),
|
schema = @Schema(implementation = UpdateGitRepositoryConfigDto.class),
|
||||||
examples = @ExampleObject(
|
examples = @ExampleObject(
|
||||||
name = "Overwrites current configuration with this one.",
|
name = "Overwrites current configuration with this one.",
|
||||||
value = "{\n \"defaultBranch\":\"main\"\n}",
|
value = "{\n \"defaultBranch\":\"main\"\n \"nonFastForwardDisallowed\":false,\n}",
|
||||||
summary = "Simple update configuration"
|
summary = "Simple update configuration"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -42,7 +42,22 @@ public class GitRepositoryConfigStoreProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ConfigurationStore<GitRepositoryConfig> get(Repository repository) {
|
public ConfigurationStore<GitRepositoryConfig> get(Repository repository) {
|
||||||
return new StoreWrapper(configurationStoreFactory.withType(GitRepositoryConfig.class).withName("gitConfig").forRepository(repository).build(), repository);
|
return new StoreWrapper(createStore(repository.getId()), repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GitRepositoryConfig getGitRepositoryConfig(String repositoryId) {
|
||||||
|
return getFronStore(createStore(repositoryId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GitRepositoryConfig getFronStore(ConfigurationStore<GitRepositoryConfig> store) {
|
||||||
|
return store.getOptional().orElse(new GitRepositoryConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigurationStore<GitRepositoryConfig> createStore(String id) {
|
||||||
|
return configurationStoreFactory
|
||||||
|
.withType(GitRepositoryConfig.class)
|
||||||
|
.withName("gitConfig")
|
||||||
|
.forRepository(id).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class StoreWrapper implements ConfigurationStore<GitRepositoryConfig> {
|
private static class StoreWrapper implements ConfigurationStore<GitRepositoryConfig> {
|
||||||
@@ -57,11 +72,7 @@ public class GitRepositoryConfigStoreProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GitRepositoryConfig get() {
|
public GitRepositoryConfig get() {
|
||||||
GitRepositoryConfig config = delegate.get();
|
return getFronStore(delegate);
|
||||||
if (config == null) {
|
|
||||||
return new GitRepositoryConfig();
|
|
||||||
}
|
|
||||||
return config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -26,4 +26,5 @@ package sonia.scm.api.v2.resources;
|
|||||||
|
|
||||||
interface UpdateGitRepositoryConfigDto {
|
interface UpdateGitRepositoryConfigDto {
|
||||||
String getDefaultBranch();
|
String getDefaultBranch();
|
||||||
|
boolean isNonFastForwardDisallowed();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ import org.eclipse.jgit.transport.ReceivePack;
|
|||||||
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
|
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
|
||||||
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
||||||
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
||||||
|
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
|
||||||
import sonia.scm.repository.GitChangesetConverterFactory;
|
import sonia.scm.repository.GitChangesetConverterFactory;
|
||||||
|
import sonia.scm.repository.GitRepositoryConfig;
|
||||||
import sonia.scm.repository.GitRepositoryHandler;
|
import sonia.scm.repository.GitRepositoryHandler;
|
||||||
import sonia.scm.web.CollectingPackParserListener;
|
import sonia.scm.web.CollectingPackParserListener;
|
||||||
import sonia.scm.web.GitHookEventFacade;
|
import sonia.scm.web.GitHookEventFacade;
|
||||||
@@ -39,16 +41,21 @@ public abstract class BaseReceivePackFactory<T> implements ReceivePackFactory<T>
|
|||||||
|
|
||||||
private final GitRepositoryHandler handler;
|
private final GitRepositoryHandler handler;
|
||||||
private final GitReceiveHook hook;
|
private final GitReceiveHook hook;
|
||||||
|
private final GitRepositoryConfigStoreProvider storeProvider;
|
||||||
|
|
||||||
protected BaseReceivePackFactory(GitChangesetConverterFactory converterFactory, GitRepositoryHandler handler, GitHookEventFacade hookEventFacade) {
|
protected BaseReceivePackFactory(GitChangesetConverterFactory converterFactory,
|
||||||
|
GitRepositoryHandler handler,
|
||||||
|
GitHookEventFacade hookEventFacade,
|
||||||
|
GitRepositoryConfigStoreProvider storeProvider) {
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
|
this.storeProvider = storeProvider;
|
||||||
this.hook = new GitReceiveHook(converterFactory, hookEventFacade, handler);
|
this.hook = new GitReceiveHook(converterFactory, hookEventFacade, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ReceivePack create(T connection, Repository repository) throws ServiceNotAuthorizedException, ServiceNotEnabledException {
|
public final ReceivePack create(T connection, Repository repository) throws ServiceNotAuthorizedException, ServiceNotEnabledException {
|
||||||
ReceivePack receivePack = createBasicReceivePack(connection, repository);
|
ReceivePack receivePack = createBasicReceivePack(connection, repository);
|
||||||
receivePack.setAllowNonFastForwards(isNonFastForwardAllowed());
|
receivePack.setAllowNonFastForwards(isNonFastForwardAllowed(repository));
|
||||||
|
|
||||||
receivePack.setPreReceiveHook(hook);
|
receivePack.setPreReceiveHook(hook);
|
||||||
receivePack.setPostReceiveHook(hook);
|
receivePack.setPostReceiveHook(hook);
|
||||||
@@ -61,7 +68,9 @@ public abstract class BaseReceivePackFactory<T> implements ReceivePackFactory<T>
|
|||||||
protected abstract ReceivePack createBasicReceivePack(T request, Repository repository)
|
protected abstract ReceivePack createBasicReceivePack(T request, Repository repository)
|
||||||
throws ServiceNotEnabledException, ServiceNotAuthorizedException;
|
throws ServiceNotEnabledException, ServiceNotAuthorizedException;
|
||||||
|
|
||||||
private boolean isNonFastForwardAllowed() {
|
private boolean isNonFastForwardAllowed(Repository repository) {
|
||||||
return ! handler.getConfig().isNonFastForwardDisallowed();
|
String repositoryId = handler.getRepositoryId(repository.getConfig());
|
||||||
|
GitRepositoryConfig gitRepositoryConfig = storeProvider.getGitRepositoryConfig(repositoryId);
|
||||||
|
return !(handler.getConfig().isNonFastForwardDisallowed() || gitRepositoryConfig.isNonFastForwardDisallowed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ package sonia.scm.protocolcommand.git;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.transport.ReceivePack;
|
import org.eclipse.jgit.transport.ReceivePack;
|
||||||
|
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
|
||||||
import sonia.scm.protocolcommand.RepositoryContext;
|
import sonia.scm.protocolcommand.RepositoryContext;
|
||||||
import sonia.scm.repository.GitChangesetConverterFactory;
|
import sonia.scm.repository.GitChangesetConverterFactory;
|
||||||
import sonia.scm.repository.GitRepositoryHandler;
|
import sonia.scm.repository.GitRepositoryHandler;
|
||||||
@@ -35,8 +36,11 @@ import sonia.scm.web.GitHookEventFacade;
|
|||||||
public class ScmReceivePackFactory extends BaseReceivePackFactory<RepositoryContext> {
|
public class ScmReceivePackFactory extends BaseReceivePackFactory<RepositoryContext> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ScmReceivePackFactory(GitChangesetConverterFactory converterFactory, GitRepositoryHandler handler, GitHookEventFacade hookEventFacade) {
|
public ScmReceivePackFactory(GitChangesetConverterFactory converterFactory,
|
||||||
super(converterFactory, handler, hookEventFacade);
|
GitRepositoryHandler handler,
|
||||||
|
GitHookEventFacade hookEventFacade,
|
||||||
|
GitRepositoryConfigStoreProvider gitRepositoryConfigStoreProvider) {
|
||||||
|
super(converterFactory, handler, hookEventFacade, gitRepositoryConfigStoreProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public class GitRepositoryConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String defaultBranch;
|
private String defaultBranch;
|
||||||
|
private boolean nonFastForwardDisallowed;
|
||||||
|
|
||||||
public String getDefaultBranch() {
|
public String getDefaultBranch() {
|
||||||
return defaultBranch;
|
return defaultBranch;
|
||||||
@@ -48,4 +49,10 @@ public class GitRepositoryConfig {
|
|||||||
public void setDefaultBranch(String defaultBranch) {
|
public void setDefaultBranch(String defaultBranch) {
|
||||||
this.defaultBranch = defaultBranch;
|
this.defaultBranch = defaultBranch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isNonFastForwardDisallowed() { return nonFastForwardDisallowed; }
|
||||||
|
|
||||||
|
public void setNonFastForwardDisallowed(boolean nonFastForwardDisallowed) {
|
||||||
|
this.nonFastForwardDisallowed = nonFastForwardDisallowed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.eclipse.jgit.transport.ReceivePack;
|
|||||||
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
|
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
|
||||||
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
||||||
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
||||||
|
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
|
||||||
import sonia.scm.protocolcommand.git.BaseReceivePackFactory;
|
import sonia.scm.protocolcommand.git.BaseReceivePackFactory;
|
||||||
import sonia.scm.repository.GitChangesetConverterFactory;
|
import sonia.scm.repository.GitChangesetConverterFactory;
|
||||||
import sonia.scm.repository.GitRepositoryHandler;
|
import sonia.scm.repository.GitRepositoryHandler;
|
||||||
@@ -53,8 +54,11 @@ public class GitReceivePackFactory extends BaseReceivePackFactory<HttpServletReq
|
|||||||
private ReceivePackFactory<HttpServletRequest> wrapped;
|
private ReceivePackFactory<HttpServletRequest> wrapped;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public GitReceivePackFactory(GitChangesetConverterFactory converterFactory, GitRepositoryHandler handler, GitHookEventFacade hookEventFacade) {
|
public GitReceivePackFactory(GitChangesetConverterFactory converterFactory,
|
||||||
super(converterFactory, handler, hookEventFacade);
|
GitRepositoryHandler handler,
|
||||||
|
GitHookEventFacade hookEventFacade,
|
||||||
|
GitRepositoryConfigStoreProvider gitRepositoryConfigStoreProvider) {
|
||||||
|
super(converterFactory, handler, hookEventFacade, gitRepositoryConfigStoreProvider);
|
||||||
this.wrapped = new DefaultReceivePackFactory();
|
this.wrapped = new DefaultReceivePackFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import { Branch, Repository, Link } from "@scm-manager/ui-types";
|
|||||||
import {
|
import {
|
||||||
apiClient,
|
apiClient,
|
||||||
BranchSelector,
|
BranchSelector,
|
||||||
|
Checkbox,
|
||||||
ErrorPage,
|
ErrorPage,
|
||||||
Loading,
|
Loading,
|
||||||
Subtitle,
|
Subtitle,
|
||||||
@@ -45,8 +46,10 @@ type State = {
|
|||||||
error?: Error;
|
error?: Error;
|
||||||
branches: Branch[];
|
branches: Branch[];
|
||||||
selectedBranchName: string;
|
selectedBranchName: string;
|
||||||
defaultBranchChanged: boolean;
|
nonFastForwardDisallowed: boolean;
|
||||||
|
changesSubmitted: boolean;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
changed: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const GIT_CONFIG_CONTENT_TYPE = "application/vnd.scmm-gitConfig+json";
|
const GIT_CONFIG_CONTENT_TYPE = "application/vnd.scmm-gitConfig+json";
|
||||||
@@ -61,15 +64,16 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
submitPending: false,
|
submitPending: false,
|
||||||
branches: [],
|
branches: [],
|
||||||
selectedBranchName: "",
|
selectedBranchName: "",
|
||||||
defaultBranchChanged: false,
|
nonFastForwardDisallowed: false,
|
||||||
disabled: true
|
changesSubmitted: false,
|
||||||
|
disabled: true,
|
||||||
|
changed: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { repository } = this.props;
|
const { repository } = this.props;
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
|
||||||
loadingBranches: true
|
loadingBranches: true
|
||||||
});
|
});
|
||||||
const branchesLink = repository._links.branches as Link;
|
const branchesLink = repository._links.branches as Link;
|
||||||
@@ -79,21 +83,18 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
.then(payload => payload._embedded.branches)
|
.then(payload => payload._embedded.branches)
|
||||||
.then(branches =>
|
.then(branches =>
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
|
||||||
branches,
|
branches,
|
||||||
loadingBranches: false
|
loadingBranches: false
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.catch(error =>
|
.catch(error =>
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
|
||||||
error
|
error
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const configurationLink = repository._links.configuration as Link;
|
const configurationLink = repository._links.configuration as Link;
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
|
||||||
loadingDefaultBranch: true
|
loadingDefaultBranch: true
|
||||||
});
|
});
|
||||||
apiClient
|
apiClient
|
||||||
@@ -101,15 +102,15 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(payload =>
|
.then(payload =>
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
|
||||||
selectedBranchName: payload.defaultBranch,
|
selectedBranchName: payload.defaultBranch,
|
||||||
|
nonFastForwardDisallowed: payload.nonFastForwardDisallowed,
|
||||||
disabled: !payload._links.update,
|
disabled: !payload._links.update,
|
||||||
loadingDefaultBranch: false
|
loadingDefaultBranch: false,
|
||||||
|
changed: false
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.catch(error =>
|
.catch(error =>
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
|
||||||
error
|
error
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -118,28 +119,36 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
branchSelected = (branch?: Branch) => {
|
branchSelected = (branch?: Branch) => {
|
||||||
if (!branch) {
|
if (!branch) {
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
|
||||||
selectedBranchName: "",
|
selectedBranchName: "",
|
||||||
defaultBranchChanged: false
|
changesSubmitted: false,
|
||||||
|
changed: true
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
|
||||||
selectedBranchName: branch.name,
|
selectedBranchName: branch.name,
|
||||||
defaultBranchChanged: false
|
changesSubmitted: false,
|
||||||
|
changed: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onNonFastForwardDisallowed = (value: boolean) => {
|
||||||
|
this.setState({
|
||||||
|
nonFastForwardDisallowed: value,
|
||||||
|
changed: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
submit = (event: FormEvent) => {
|
submit = (event: FormEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const { repository } = this.props;
|
const { repository } = this.props;
|
||||||
|
const { selectedBranchName, nonFastForwardDisallowed } = this.state;
|
||||||
const newConfig = {
|
const newConfig = {
|
||||||
defaultBranch: this.state.selectedBranchName
|
defaultBranch: selectedBranchName,
|
||||||
|
nonFastForwardDisallowed
|
||||||
};
|
};
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
|
||||||
submitPending: true
|
submitPending: true
|
||||||
});
|
});
|
||||||
const configurationLink = repository._links.configuration as Link;
|
const configurationLink = repository._links.configuration as Link;
|
||||||
@@ -147,14 +156,13 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
.put(configurationLink.href, newConfig, GIT_CONFIG_CONTENT_TYPE)
|
.put(configurationLink.href, newConfig, GIT_CONFIG_CONTENT_TYPE)
|
||||||
.then(() =>
|
.then(() =>
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
|
||||||
submitPending: false,
|
submitPending: false,
|
||||||
defaultBranchChanged: true
|
changesSubmitted: true,
|
||||||
|
changed: false
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.catch(error =>
|
.catch(error =>
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
|
||||||
error
|
error
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -162,13 +170,13 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { t } = this.props;
|
const { t } = this.props;
|
||||||
const { loadingBranches, loadingDefaultBranch, submitPending, error, disabled } = this.state;
|
const { loadingBranches, loadingDefaultBranch, submitPending, error, disabled, changed } = this.state;
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return (
|
return (
|
||||||
<ErrorPage
|
<ErrorPage
|
||||||
title={t("scm-git-plugin.repo-config.error.title")}
|
title={t("scm-git-plugin.repoConfig.error.title")}
|
||||||
subtitle={t("scm-git-plugin.repo-config.error.subtitle")}
|
subtitle={t("scm-git-plugin.repoConfig.error.subtitle")}
|
||||||
error={error}
|
error={error}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -177,27 +185,32 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
const submitButton = disabled ? null : (
|
const submitButton = disabled ? null : (
|
||||||
<Level
|
<Level
|
||||||
right={
|
right={
|
||||||
<SubmitButton
|
<SubmitButton label={t("scm-git-plugin.repoConfig.submit")} loading={submitPending} disabled={!changed} />
|
||||||
label={t("scm-git-plugin.repo-config.submit")}
|
|
||||||
loading={submitPending}
|
|
||||||
disabled={!this.state.selectedBranchName}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!(loadingBranches || loadingDefaultBranch)) {
|
if (!(loadingBranches || loadingDefaultBranch)) {
|
||||||
|
const { branches, selectedBranchName, nonFastForwardDisallowed } = this.state;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<hr />
|
<hr />
|
||||||
<Subtitle subtitle={t("scm-git-plugin.repo-config.title")} />
|
<Subtitle subtitle={t("scm-git-plugin.repoConfig.title")} />
|
||||||
{this.renderBranchChangedNotification()}
|
{this.renderBranchChangedNotification()}
|
||||||
<form onSubmit={this.submit}>
|
<form onSubmit={this.submit}>
|
||||||
<BranchSelector
|
<BranchSelector
|
||||||
label={t("scm-git-plugin.repo-config.default-branch")}
|
label={t("scm-git-plugin.repoConfig.defaultBranch")}
|
||||||
branches={this.state.branches}
|
branches={branches}
|
||||||
onSelectBranch={this.branchSelected}
|
onSelectBranch={this.branchSelected}
|
||||||
selectedBranch={this.state.selectedBranchName}
|
selectedBranch={selectedBranchName}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
name="nonFastForwardDisallowed"
|
||||||
|
label={t("scm-git-plugin.repoConfig.nonFastForwardDisallowed")}
|
||||||
|
helpText={t("scm-git-plugin.repoConfig.nonFastForwardDisallowedHelpText")}
|
||||||
|
checked={nonFastForwardDisallowed}
|
||||||
|
onChange={this.onNonFastForwardDisallowed}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
{submitButton}
|
{submitButton}
|
||||||
@@ -210,19 +223,19 @@ class RepositoryConfig extends React.Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderBranchChangedNotification = () => {
|
renderBranchChangedNotification = () => {
|
||||||
if (this.state.defaultBranchChanged) {
|
if (this.state.changesSubmitted) {
|
||||||
return (
|
return (
|
||||||
<div className="notification is-primary">
|
<div className="notification is-primary">
|
||||||
<button
|
<button
|
||||||
className="delete"
|
className="delete"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
changesSubmitted: false,
|
||||||
defaultBranchChanged: false
|
changed: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{this.props.t("scm-git-plugin.repo-config.success")}
|
{this.props.t("scm-git-plugin.repoConfig.success")}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,16 +31,17 @@
|
|||||||
"disabledHelpText": "Aktiviere oder deaktiviere das Git Plugin",
|
"disabledHelpText": "Aktiviere oder deaktiviere das Git Plugin",
|
||||||
"submit": "Speichern"
|
"submit": "Speichern"
|
||||||
},
|
},
|
||||||
"repo-config": {
|
"repoConfig": {
|
||||||
"link": "Konfiguration",
|
|
||||||
"title": "Git Einstellungen",
|
"title": "Git Einstellungen",
|
||||||
"default-branch": "Standard Branch",
|
"defaultBranch": "Default Branch",
|
||||||
|
"nonFastForwardDisallowed": "Deaktiviere \"Non Fast-Forward\"",
|
||||||
|
"nonFastForwardDisallowedHelpText": "Git Pushes ablehnen, die nicht \"fast-forward\" sind, wie \"--force\".",
|
||||||
"submit": "Speichern",
|
"submit": "Speichern",
|
||||||
"error": {
|
"error": {
|
||||||
"title": "Fehler",
|
"title": "Fehler",
|
||||||
"subtitle": "Ein Fehler ist aufgetreten."
|
"subtitle": "Ein Fehler ist aufgetreten."
|
||||||
},
|
},
|
||||||
"success": "Der standard Branch wurde geändert!"
|
"success": "Einstellungen wurden erfolgreich geändert!"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"permissions": {
|
"permissions": {
|
||||||
|
|||||||
@@ -31,16 +31,17 @@
|
|||||||
"disabledHelpText": "Enable or disable the Git plugin",
|
"disabledHelpText": "Enable or disable the Git plugin",
|
||||||
"submit": "Submit"
|
"submit": "Submit"
|
||||||
},
|
},
|
||||||
"repo-config": {
|
"repoConfig": {
|
||||||
"link": "Configuration",
|
|
||||||
"title": "Git Settings",
|
"title": "Git Settings",
|
||||||
"default-branch": "Default Branch",
|
"defaultBranch": "Default Branch",
|
||||||
|
"nonFastForwardDisallowed": "Disallow Non Fast-Forward",
|
||||||
|
"nonFastForwardDisallowedHelpText": "Reject git pushes which are non fast-forward such as --force.",
|
||||||
"submit": "Submit",
|
"submit": "Submit",
|
||||||
"error": {
|
"error": {
|
||||||
"title": "Error",
|
"title": "Error",
|
||||||
"subtitle": "Something went wrong"
|
"subtitle": "Something went wrong"
|
||||||
},
|
},
|
||||||
"success": "Default branch changed!"
|
"success": "Configuration changed successfully!"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"permissions" : {
|
"permissions" : {
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ import org.junit.rules.TemporaryFolder;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
|
||||||
import sonia.scm.repository.GitConfig;
|
import sonia.scm.repository.GitConfig;
|
||||||
|
import sonia.scm.repository.GitRepositoryConfig;
|
||||||
import sonia.scm.repository.GitRepositoryHandler;
|
import sonia.scm.repository.GitRepositoryHandler;
|
||||||
import sonia.scm.repository.GitTestHelper;
|
import sonia.scm.repository.GitTestHelper;
|
||||||
import sonia.scm.web.CollectingPackParserListener;
|
import sonia.scm.web.CollectingPackParserListener;
|
||||||
@@ -59,17 +61,22 @@ public class BaseReceivePackFactoryTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private GitRepositoryHandler handler;
|
private GitRepositoryHandler handler;
|
||||||
|
|
||||||
private GitConfig config;
|
private GitConfig gitConfig;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private ReceivePackFactory<Object> wrappedReceivePackFactory;
|
private ReceivePackFactory<Object> wrappedReceivePackFactory;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private GitRepositoryConfigStoreProvider gitRepositoryConfigStoreProvider;
|
||||||
|
|
||||||
private BaseReceivePackFactory<Object> factory;
|
private BaseReceivePackFactory<Object> factory;
|
||||||
|
|
||||||
private Object request = new Object();
|
private Object request = new Object();
|
||||||
|
|
||||||
private Repository repository;
|
private Repository repository;
|
||||||
|
|
||||||
|
private GitRepositoryConfig gitRepositoryConfig = new GitRepositoryConfig();
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||||
|
|
||||||
@@ -77,13 +84,16 @@ public class BaseReceivePackFactoryTest {
|
|||||||
public void setUpObjectUnderTest() throws Exception {
|
public void setUpObjectUnderTest() throws Exception {
|
||||||
this.repository = createRepositoryForTesting();
|
this.repository = createRepositoryForTesting();
|
||||||
|
|
||||||
config = new GitConfig();
|
gitConfig = new GitConfig();
|
||||||
when(handler.getConfig()).thenReturn(config);
|
when(handler.getConfig()).thenReturn(gitConfig);
|
||||||
|
when(handler.getRepositoryId(repository.getConfig())).thenReturn("heart-of-gold");
|
||||||
|
|
||||||
ReceivePack receivePack = new ReceivePack(repository);
|
ReceivePack receivePack = new ReceivePack(repository);
|
||||||
when(wrappedReceivePackFactory.create(request, repository)).thenReturn(receivePack);
|
when(wrappedReceivePackFactory.create(request, repository)).thenReturn(receivePack);
|
||||||
|
|
||||||
factory = new BaseReceivePackFactory<Object>(GitTestHelper.createConverterFactory(), handler, null) {
|
when(gitRepositoryConfigStoreProvider.getGitRepositoryConfig("heart-of-gold")).thenReturn(gitRepositoryConfig);
|
||||||
|
|
||||||
|
factory = new BaseReceivePackFactory<Object>(GitTestHelper.createConverterFactory(), handler, null, gitRepositoryConfigStoreProvider) {
|
||||||
@Override
|
@Override
|
||||||
protected ReceivePack createBasicReceivePack(Object request, Repository repository) throws ServiceNotEnabledException, ServiceNotAuthorizedException {
|
protected ReceivePack createBasicReceivePack(Object request, Repository repository) throws ServiceNotEnabledException, ServiceNotAuthorizedException {
|
||||||
return wrappedReceivePackFactory.create(request, repository);
|
return wrappedReceivePackFactory.create(request, repository);
|
||||||
@@ -108,7 +118,14 @@ public class BaseReceivePackFactoryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateWithDisabledNonFastForward() throws Exception {
|
public void testCreateWithDisabledNonFastForward() throws Exception {
|
||||||
config.setNonFastForwardDisallowed(true);
|
gitConfig.setNonFastForwardDisallowed(true);
|
||||||
|
ReceivePack receivePack = factory.create(request, repository);
|
||||||
|
assertFalse(receivePack.isAllowNonFastForwards());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateWithLocalDisabledNonFastForward() throws Exception {
|
||||||
|
gitRepositoryConfig.setNonFastForwardDisallowed(true);
|
||||||
ReceivePack receivePack = factory.create(request, repository);
|
ReceivePack receivePack = factory.create(request, repository);
|
||||||
assertFalse(receivePack.isAllowNonFastForwards());
|
assertFalse(receivePack.isAllowNonFastForwards());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user