Browse Source

Moved the fork mechanism from a javascript link to a separate page

tags/v1.2.0
James Moger 11 years ago
parent
commit
1f52c8b5f1

BIN
resources/git-black.png View File


+ 32
- 31
src/com/gitblit/GitBlit.java View File

@@ -2637,44 +2637,45 @@ public class GitBlit implements ServletContextListener {
*
* @param repository
* @param user
* @return true, if successful
* @return the repository model of the fork, if successful
* @throws GitBlitException
*/
public boolean fork(RepositoryModel repository, UserModel user) {
public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException {
String cloneName = MessageFormat.format("~{0}/{1}.git", user.username, StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name)));
String fromUrl = MessageFormat.format("file://{0}/{1}", repositoriesFolder.getAbsolutePath(), repository.name);
// clone the repository
try {
// clone the repository
JGitUtils.cloneRepository(repositoriesFolder, cloneName, fromUrl, true, null);
// create a Gitblit repository model for the clone
RepositoryModel cloneModel = repository.cloneAs(cloneName);
cloneModel.owner = user.username;
updateRepositoryModel(cloneName, cloneModel, false);
if (AuthorizationControl.NAMED.equals(cloneModel.authorizationControl)) {
// add the owner of the source repository to the clone's access list
if (!StringUtils.isEmpty(repository.owner)) {
UserModel owner = getUserModel(repository.owner);
if (owner != null) {
owner.repositories.add(cloneName);
updateUserModel(owner.username, owner, false);
}
} catch (Exception e) {
throw new GitBlitException(e);
}
// create a Gitblit repository model for the clone
RepositoryModel cloneModel = repository.cloneAs(cloneName);
cloneModel.owner = user.username;
updateRepositoryModel(cloneName, cloneModel, false);
if (AuthorizationControl.NAMED.equals(cloneModel.authorizationControl)) {
// add the owner of the source repository to the clone's access list
if (!StringUtils.isEmpty(repository.owner)) {
UserModel owner = getUserModel(repository.owner);
if (owner != null) {
owner.repositories.add(cloneName);
updateUserModel(owner.username, owner, false);
}
// inherit origin's access lists
List<String> users = getRepositoryUsers(repository);
setRepositoryUsers(cloneModel, users);
List<String> teams = getRepositoryTeams(repository);
setRepositoryTeams(cloneModel, teams);
}
// add this clone to the cached model
addToCachedRepositoryList(cloneModel.name, cloneModel);
return true;
} catch (Exception e) {
logger.error("failed to fork", e);
// inherit origin's access lists
List<String> users = getRepositoryUsers(repository);
setRepositoryUsers(cloneModel, users);
List<String> teams = getRepositoryTeams(repository);
setRepositoryTeams(cloneModel, teams);
}
return false;
// add this clone to the cached model
addToCachedRepositoryList(cloneModel.name, cloneModel);
return cloneModel;
}
}

+ 3
- 0
src/com/gitblit/models/RepositoryModel.java View File

@@ -145,7 +145,10 @@ public class RepositoryModel implements Serializable, Comparable<RepositoryModel
public RepositoryModel cloneAs(String cloneName) {
RepositoryModel clone = new RepositoryModel();
clone.originRepository = name;
clone.name = cloneName;
clone.projectPath = StringUtils.getFirstPathElement(cloneName);
clone.isBare = true;
clone.description = description;
clone.accessRestriction = accessRestriction;
clone.authorizationControl = authorizationControl;

+ 2
- 0
src/com/gitblit/wicket/GitBlitWebApp.java View File

@@ -34,6 +34,7 @@ import com.gitblit.wicket.pages.CommitDiffPage;
import com.gitblit.wicket.pages.CommitPage;
import com.gitblit.wicket.pages.DocsPage;
import com.gitblit.wicket.pages.FederationRegistrationPage;
import com.gitblit.wicket.pages.ForkPage;
import com.gitblit.wicket.pages.ForksPage;
import com.gitblit.wicket.pages.GitSearchPage;
import com.gitblit.wicket.pages.GravatarProfilePage;
@@ -120,6 +121,7 @@ public class GitBlitWebApp extends WebApplication {
mount("/projects", ProjectsPage.class);
mount("/user", UserPage.class, "user");
mount("/forks", ForksPage.class, "r");
mount("/fork", ForkPage.class, "r");
}
private void mount(String location, Class<? extends WebPage> clazz, String... parameters) {

+ 5
- 2
src/com/gitblit/wicket/GitBlitWebApp.properties View File

@@ -323,7 +323,7 @@ gb.fork = fork
gb.forks = forks
gb.forkRepository = fork {0}?
gb.repositoryForked = {0} has been forked
gb.repositoryForkFailed= failed to fork {1}
gb.repositoryForkFailed= fork has failed
gb.personalRepositories = personal repositories
gb.allowForks = allow forks
gb.allowForksDescription = allow authorized users to fork this repository
@@ -333,4 +333,7 @@ gb.canForkDescription = user is permitted to fork authorized repositories
gb.myFork = view my fork
gb.forksProhibited = forks prohibited
gb.forksProhibitedWarning = this repository forbids forks
gb.noForks = {0} has no forks
gb.noForks = {0} has no forks
gb.forkNotAuthorized = sorry, you are not authorized to fork {0}
gb.forkInProgress = fork in progress
gb.preparingFork = Gitblit is preparing your fork

+ 12
- 0
src/com/gitblit/wicket/GitBlitWebSession.java View File

@@ -17,6 +17,7 @@ package com.gitblit.wicket;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.wicket.Page;
import org.apache.wicket.PageParameters;
@@ -42,8 +43,11 @@ public final class GitBlitWebSession extends WebSession {
private String requestUrl;
private AtomicBoolean isForking;
public GitBlitWebSession(Request request) {
super(request);
isForking = new AtomicBoolean();
}
public void invalidate() {
@@ -134,6 +138,14 @@ public final class GitBlitWebSession extends WebSession {
errorMessage = null;
return msg;
}
public boolean isForking() {
return isForking.get();
}
public void isForking(boolean val) {
isForking.set(val);
}
public static GitBlitWebSession get() {
return (GitBlitWebSession) Session.get();

+ 40
- 0
src/com/gitblit/wicket/pages/ForkPage.html View File

@@ -0,0 +1,40 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"
xml:lang="en"
lang="en">
<body>
<wicket:head>
<noscript>
<meta http-equiv="refresh" content="5"></meta>
</noscript>
<script type="text/javascript"">
function doLoad() { setTimeout( "refresh()", 5*1000 ); }
function refresh() { window.location.reload(); }
</script>
</wicket:head>
<wicket:extend>
<!-- need to specify body.onload -->
<body onload="doLoad()">
<div class="row">
<div class="span6 offset3">
<div wicket:id="forkText" class="pageTitle project" style="border:0;font-weight:bold; text-align:center;">[fork text]</div>
</div>
<div class="span4 offset4">
<div class="progress progress-striped active">
<div class="bar" style="width: 100%;"></div>
</div>
</div>
<div class="span6 offset3">
<div style="opacity:0.2;">
<center><img style="padding:10px" src="git-black.png"></img></center>
</div>
</div>
</div>
</body>
</wicket:extend>
</body>
</html>

+ 107
- 0
src/com/gitblit/wicket/pages/ForkPage.java View File

@@ -0,0 +1,107 @@
/*
* Copyright 2012 gitblit.com.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gitblit.wicket.pages;
import java.text.MessageFormat;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.slf4j.LoggerFactory;
import com.gitblit.GitBlit;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.GitblitRedirectException;
import com.gitblit.wicket.WicketUtils;
public class ForkPage extends RepositoryPage {
public ForkPage(PageParameters params) {
super(params);
setVersioned(false);
GitBlitWebSession session = GitBlitWebSession.get();
RepositoryModel repository = getRepositoryModel();
UserModel user = session.getUser();
boolean canFork = user.canForkRepository(repository);
if (!canFork) {
// redirect to the summary page if this repository is not empty
GitBlitWebSession.get().cacheErrorMessage(
MessageFormat.format(getString("gb.forkNotAuthorized"), repository.name));
throw new GitblitRedirectException(SummaryPage.class, WicketUtils.newRepositoryParameter(repository.name));
}
String fork = GitBlit.self().getFork(user.username, repository.name);
if (fork != null) {
// redirect to user's fork
throw new GitblitRedirectException(SummaryPage.class, WicketUtils.newRepositoryParameter(fork));
}
add(new Label("forkText", getString("gb.preparingFork")));
if (!session.isForking()) {
// prepare session
session.isForking(true);
// fork it
ForkThread forker = new ForkThread(repository, session);
forker.start();
}
}
@Override
protected boolean allowForkControls() {
return false;
}
@Override
protected String getPageName() {
return "fork";
}
/**
* ForkThread does the work of working the repository in a background
* thread. The completion status is tracked through a session variable and
* monitored by this page.
*/
private static class ForkThread extends Thread {
private final RepositoryModel repository;
private final GitBlitWebSession session;
public ForkThread(RepositoryModel repository, GitBlitWebSession session) {
this.repository = repository;
this.session = session;
}
@Override
public void run() {
UserModel user = session.getUser();
try {
GitBlit.self().fork(repository, user);
} catch (Exception e) {
LoggerFactory.getLogger(ForkPage.class).error(MessageFormat.format("Failed to fork {0} for {1}", repository.name, user.username), e);
} finally {
session.isForking(false);
}
}
}
}

+ 7
- 23
src/com/gitblit/wicket/pages/RepositoryPage.java View File

@@ -28,12 +28,10 @@ import java.util.Set;
import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.RedirectException;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
@@ -62,7 +60,6 @@ import com.gitblit.wicket.PageRegistration;
import com.gitblit.wicket.PageRegistration.OtherPageLink;
import com.gitblit.wicket.SessionlessForm;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.BasePanel.JavascriptEventConfirmation;
import com.gitblit.wicket.panels.LinkPanel;
import com.gitblit.wicket.panels.NavigationPanel;
import com.gitblit.wicket.panels.RefsPanel;
@@ -171,6 +168,10 @@ public abstract class RepositoryPage extends BasePage {
}
return pages;
}
protected boolean allowForkControls() {
return true;
}
@Override
protected void setupPage(String repositoryName, String pageName) {
@@ -230,7 +231,7 @@ public abstract class RepositoryPage extends BasePage {
}
// fork controls
if (user == null) {
if (!allowForkControls() || user == null) {
// must be logged-in to fork, hide all fork controls
add(new ExternalLink("forkLink", "").setVisible(false));
add(new ExternalLink("myForkLink", "").setVisible(false));
@@ -268,25 +269,8 @@ public abstract class RepositoryPage extends BasePage {
// can fork and we do not have one
add(new Label("forksProhibitedIndicator").setVisible(false));
add(new ExternalLink("myForkLink", "").setVisible(false));
Link<Void> forkLink = new Link<Void>("forkLink") {
private static final long serialVersionUID = 1L;
@Override
public void onClick() {
UserModel user = GitBlitWebSession.get().getUser();
RepositoryModel model = getRepositoryModel();
String asFork = MessageFormat.format("~{0}/{1}.git", user.username, StringUtils.stripDotGit(StringUtils.getLastPathElement(model.name)));
if (GitBlit.self().fork(model, GitBlitWebSession.get().getUser())) {
throw new RedirectException(SummaryPage.class, WicketUtils.newRepositoryParameter(asFork));
} else {
error(MessageFormat.format(getString("gb.repositoryForkFailed"), model));
}
}
};
forkLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format(
getString("gb.forkRepository"), getRepositoryModel())));
add(forkLink);
String url = getRequestCycle().urlFor(ForkPage.class, WicketUtils.newRepositoryParameter(model.name)).toString();
add(new ExternalLink("forkLink", url));
}
}

+ 0
- 2
src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java View File

@@ -22,7 +22,6 @@ import java.util.Map;
import org.apache.wicket.Component;
import org.apache.wicket.Localizer;
import org.apache.wicket.Page;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
@@ -153,7 +152,6 @@ public class ProjectRepositoryPanel extends BasePanel {
@Override
public void onClick() {
if (GitBlit.self().deleteRepositoryModel(entry)) {
info(MessageFormat.format(getString("gb.repositoryDeleted"), entry));
// redirect to the owning page
if (entry.isPersonalRepository()) {
setResponsePage(getPage().getClass(), WicketUtils.newUsernameParameter(entry.projectPath.substring(1)));

+ 2
- 2
src/com/gitblit/wicket/panels/RepositoriesPanel.java View File

@@ -305,11 +305,11 @@ public class RepositoriesPanel extends BasePanel {
@Override
public void onClick() {
if (GitBlit.self().deleteRepositoryModel(entry)) {
info(MessageFormat.format(getString("gb.repositoryDeleted"), entry));
if (dp instanceof SortableRepositoriesProvider) {
info(MessageFormat.format(getString("gb.repositoryDeleted"), entry));
((SortableRepositoriesProvider) dp).remove(entry);
} else {
((RepositoriesProvider) dp).remove(entry);
setResponsePage(getPage().getClass(), getPage().getPageParameters());
}
} else {
error(MessageFormat.format(getString("gb.repositoryDeleteFailed"), entry));

Loading…
Cancel
Save