diff options
author | James Moger <james.moger@gitblit.com> | 2012-10-02 17:23:16 -0400 |
---|---|---|
committer | James Moger <james.moger@gitblit.com> | 2012-10-02 17:23:16 -0400 |
commit | 1f52c8b5f123b97fc631465479bc2855c12b9ee3 (patch) | |
tree | 6525cf8ffbfebf0a724eb516660180ab021d79c0 /src | |
parent | 9bdf88df00e9abf99442e14a33ed6215b32026b6 (diff) | |
download | gitblit-1f52c8b5f123b97fc631465479bc2855c12b9ee3.tar.gz gitblit-1f52c8b5f123b97fc631465479bc2855c12b9ee3.zip |
Moved the fork mechanism from a javascript link to a separate page
Diffstat (limited to 'src')
-rw-r--r-- | src/com/gitblit/GitBlit.java | 63 | ||||
-rw-r--r-- | src/com/gitblit/models/RepositoryModel.java | 3 | ||||
-rw-r--r-- | src/com/gitblit/wicket/GitBlitWebApp.java | 2 | ||||
-rw-r--r-- | src/com/gitblit/wicket/GitBlitWebApp.properties | 7 | ||||
-rw-r--r-- | src/com/gitblit/wicket/GitBlitWebSession.java | 12 | ||||
-rw-r--r-- | src/com/gitblit/wicket/pages/ForkPage.html | 40 | ||||
-rw-r--r-- | src/com/gitblit/wicket/pages/ForkPage.java | 107 | ||||
-rw-r--r-- | src/com/gitblit/wicket/pages/RepositoryPage.java | 30 | ||||
-rw-r--r-- | src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java | 2 | ||||
-rw-r--r-- | src/com/gitblit/wicket/panels/RepositoriesPanel.java | 4 |
10 files changed, 210 insertions, 60 deletions
diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 51c44f66..4ada7481 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -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;
}
}
diff --git a/src/com/gitblit/models/RepositoryModel.java b/src/com/gitblit/models/RepositoryModel.java index 44aba1d8..3148b5b4 100644 --- a/src/com/gitblit/models/RepositoryModel.java +++ b/src/com/gitblit/models/RepositoryModel.java @@ -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;
diff --git a/src/com/gitblit/wicket/GitBlitWebApp.java b/src/com/gitblit/wicket/GitBlitWebApp.java index b691cea4..245b1e05 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp.java +++ b/src/com/gitblit/wicket/GitBlitWebApp.java @@ -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) {
diff --git a/src/com/gitblit/wicket/GitBlitWebApp.properties b/src/com/gitblit/wicket/GitBlitWebApp.properties index d30f5710..e0bb6692 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp.properties @@ -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
\ No newline at end of file +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
\ No newline at end of file diff --git a/src/com/gitblit/wicket/GitBlitWebSession.java b/src/com/gitblit/wicket/GitBlitWebSession.java index 7ecc05b2..0e1ae512 100644 --- a/src/com/gitblit/wicket/GitBlitWebSession.java +++ b/src/com/gitblit/wicket/GitBlitWebSession.java @@ -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();
diff --git a/src/com/gitblit/wicket/pages/ForkPage.html b/src/com/gitblit/wicket/pages/ForkPage.html new file mode 100644 index 00000000..7d2d2aa5 --- /dev/null +++ b/src/com/gitblit/wicket/pages/ForkPage.html @@ -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>
\ No newline at end of file diff --git a/src/com/gitblit/wicket/pages/ForkPage.java b/src/com/gitblit/wicket/pages/ForkPage.java new file mode 100644 index 00000000..082dab51 --- /dev/null +++ b/src/com/gitblit/wicket/pages/ForkPage.java @@ -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);
+ }
+ }
+ }
+}
diff --git a/src/com/gitblit/wicket/pages/RepositoryPage.java b/src/com/gitblit/wicket/pages/RepositoryPage.java index 8ca2b335..879c4321 100644 --- a/src/com/gitblit/wicket/pages/RepositoryPage.java +++ b/src/com/gitblit/wicket/pages/RepositoryPage.java @@ -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));
}
}
diff --git a/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java b/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java index 6f693ee0..0a6bc623 100644 --- a/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java +++ b/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java @@ -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)));
diff --git a/src/com/gitblit/wicket/panels/RepositoriesPanel.java b/src/com/gitblit/wicket/panels/RepositoriesPanel.java index 4c9ed280..1967b501 100644 --- a/src/com/gitblit/wicket/panels/RepositoriesPanel.java +++ b/src/com/gitblit/wicket/panels/RepositoriesPanel.java @@ -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));
|