resources/git-black.png | patch | view | raw | blame | history | |
src/com/gitblit/GitBlit.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/models/RepositoryModel.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/GitBlitWebApp.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/GitBlitWebApp.properties | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/GitBlitWebSession.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/pages/ForkPage.html | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/pages/ForkPage.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/pages/RepositoryPage.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/panels/RepositoriesPanel.java | ●●●●● patch | view | raw | blame | history |
resources/git-black.png
src/com/gitblit/GitBlit.java
@@ -2637,14 +2637,19 @@ * * @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); try { // clone the repository try { JGitUtils.cloneRepository(repositoriesFolder, cloneName, fromUrl, true, null); } catch (Exception e) { throw new GitBlitException(e); } // create a Gitblit repository model for the clone RepositoryModel cloneModel = repository.cloneAs(cloneName); @@ -2671,10 +2676,6 @@ // add this clone to the cached model addToCachedRepositoryList(cloneModel.name, cloneModel); return true; } catch (Exception e) { logger.error("failed to fork", e); } return false; return cloneModel; } } src/com/gitblit/models/RepositoryModel.java
@@ -145,7 +145,10 @@ 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; src/com/gitblit/wicket/GitBlitWebApp.java
@@ -34,6 +34,7 @@ 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 @@ 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) { src/com/gitblit/wicket/GitBlitWebApp.properties
@@ -323,7 +323,7 @@ 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 @@ -334,3 +334,6 @@ gb.forksProhibited = forks prohibited gb.forksProhibitedWarning = this repository forbids 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 src/com/gitblit/wicket/GitBlitWebSession.java
@@ -17,6 +17,7 @@ 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 @@ private String requestUrl; private AtomicBoolean isForking; public GitBlitWebSession(Request request) { super(request); isForking = new AtomicBoolean(); } public void invalidate() { @@ -135,6 +139,14 @@ return msg; } public boolean isForking() { return isForking.get(); } public void isForking(boolean val) { isForking.set(val); } public static GitBlitWebSession get() { return (GitBlitWebSession) Session.get(); } src/com/gitblit/wicket/pages/ForkPage.html
New 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> src/com/gitblit/wicket/pages/ForkPage.java
New 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); } } } } src/com/gitblit/wicket/pages/RepositoryPage.java
@@ -28,12 +28,10 @@ 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.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; @@ -172,6 +169,10 @@ return pages; } protected boolean allowForkControls() { return true; } @Override protected void setupPage(String repositoryName, String pageName) { String projectName = StringUtils.getFirstPathElement(repositoryName); @@ -230,7 +231,7 @@ } // 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 @@ // 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)); } } src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java
@@ -22,7 +22,6 @@ 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 @@ @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))); src/com/gitblit/wicket/panels/RepositoriesPanel.java
@@ -305,11 +305,11 @@ @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));