From 1e1b85270f93b3bca624c99b478f3a9a23be2395 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Sat, 29 Sep 2012 23:40:46 -0400 Subject: [PATCH] Preliminary implementation of server-side forking (issue 137) --- src/com/gitblit/wicket/pages/RepositoryPage.java | 123 ++++++++++++++++++++++++++++++++++++---- 1 files changed, 110 insertions(+), 13 deletions(-) diff --git a/src/com/gitblit/wicket/pages/RepositoryPage.java b/src/com/gitblit/wicket/pages/RepositoryPage.java index eb8536c..a85d21e 100644 --- a/src/com/gitblit/wicket/pages/RepositoryPage.java +++ b/src/com/gitblit/wicket/pages/RepositoryPage.java @@ -28,10 +28,12 @@ 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; @@ -47,8 +49,10 @@ import com.gitblit.Keys; import com.gitblit.PagesServlet; import com.gitblit.SyndicationServlet; +import com.gitblit.models.ProjectModel; import com.gitblit.models.RepositoryModel; import com.gitblit.models.SubmoduleModel; +import com.gitblit.models.UserModel; import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.StringUtils; @@ -58,6 +62,7 @@ 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; @@ -81,10 +86,11 @@ public RepositoryPage(PageParameters params) { super(params); repositoryName = WicketUtils.getRepositoryName(params); - if (repositoryName.indexOf('/') > -1) { - projectName = repositoryName.substring(0, repositoryName.indexOf('/')); - } else { + String root =StringUtils.getFirstPathElement(repositoryName); + if (StringUtils.isEmpty(root)) { projectName = GitBlit.getString(Keys.web.repositoryRootGroupName, "main"); + } else { + projectName = root; } objectId = WicketUtils.getObject(params); @@ -125,7 +131,6 @@ // standard links pages.put("repositories", new PageRegistration("gb.repositories", RepositoriesPage.class)); - pages.put("project", new PageRegistration("gb.project", ProjectPage.class, WicketUtils.newProjectParameter(projectName))); pages.put("summary", new PageRegistration("gb.summary", SummaryPage.class, params)); pages.put("log", new PageRegistration("gb.log", LogPage.class, params)); pages.put("branches", new PageRegistration("gb.branches", BranchesPage.class, params)); @@ -136,6 +141,17 @@ Repository r = getRepository(); RepositoryModel model = getRepositoryModel(); + // forks list button + if (StringUtils.isEmpty(model.originRepository)) { + if (!ArrayUtils.isEmpty(model.forks)) { + // this origin repository has forks + pages.put("forks", new PageRegistration("gb.forks", ForksPage.class, params)); + } + } else { + // this is a fork of another repository + pages.put("forks", new PageRegistration("gb.forks", ForksPage.class, params)); + } + // per-repository extra page links if (model.useTickets && TicgitUtils.getTicketsBranch(r) != null) { pages.put("tickets", new PageRegistration("gb.tickets", TicketsPage.class, params)); @@ -168,19 +184,100 @@ @Override protected void setupPage(String repositoryName, String pageName) { - add(new LinkPanel("repositoryName", null, StringUtils.stripDotGit(repositoryName), - SummaryPage.class, WicketUtils.newRepositoryParameter(repositoryName))); - add(new Label("pageName", pageName).setRenderBodyOnly(true)); - if (getRepositoryModel().isBare) { - add(new Label("workingCopy").setVisible(false)); + String projectName = StringUtils.getFirstPathElement(repositoryName); + ProjectModel project = GitBlit.self().getProjectModel(projectName); + if (project.isUserProject()) { + // user-as-project + add(new LinkPanel("projectTitle", null, project.getDisplayName(), + UserPage.class, WicketUtils.newUsernameParameter(project.name.substring(1)))); } else { - Fragment fragment = new Fragment("workingCopy", "workingCopyFragment", this); + // project + add(new LinkPanel("projectTitle", null, project.name, + ProjectPage.class, WicketUtils.newProjectParameter(project.name))); + } + + String name = StringUtils.stripDotGit(repositoryName); + if (!StringUtils.isEmpty(projectName) && name.startsWith(projectName)) { + name = name.substring(projectName.length() + 1); + } + add(new LinkPanel("repositoryName", null, name, SummaryPage.class, + WicketUtils.newRepositoryParameter(repositoryName))); + add(new Label("pageName", pageName).setRenderBodyOnly(true)); + + // indicate origin repository + RepositoryModel model = getRepositoryModel(); + if (StringUtils.isEmpty(model.originRepository)) { + add(new Label("originRepository").setVisible(false)); + } else { + Fragment forkFrag = new Fragment("originRepository", "originFragment", this); + forkFrag.add(new LinkPanel("originRepository", null, StringUtils.stripDotGit(model.originRepository), + SummaryPage.class, WicketUtils.newRepositoryParameter(model.originRepository))); + add(forkFrag); + } + + if (getRepositoryModel().isBare) { + add(new Label("workingCopyIndicator").setVisible(false)); + } else { + Fragment wc = new Fragment("workingCopyIndicator", "workingCopyFragment", this); Label lbl = new Label("workingCopy", getString("gb.workingCopy")); WicketUtils.setHtmlTooltip(lbl, getString("gb.workingCopyWarning")); - fragment.add(lbl); - add(fragment); + wc.add(lbl); + add(wc); } + + if (getRepositoryModel().allowForks) { + add(new Label("forksProhibitedIndicator").setVisible(false)); + } else { + Fragment wc = new Fragment("forksProhibitedIndicator", "forksProhibitedFragment", this); + Label lbl = new Label("forksProhibited", getString("gb.forksProhibited")); + WicketUtils.setHtmlTooltip(lbl, getString("gb.forksProhibitedWarning")); + wc.add(lbl); + add(wc); + } + + UserModel user = GitBlitWebSession.get().getUser(); + + // fork button + if (user != null) { + final String clonedRepo = MessageFormat.format("~{0}/{1}.git", user.username, StringUtils.stripDotGit(StringUtils.getLastPathElement(model.name))); + boolean hasClone = GitBlit.self().hasRepository(clonedRepo) && !getRepositoryModel().name.equals(clonedRepo); + if (user.canForkRepository(model) && !hasClone) { + Link<Void> forkLink = new Link<Void>("forkLink") { + private static final long serialVersionUID = 1L; + + @Override + public void onClick() { + RepositoryModel model = getRepositoryModel(); + if (GitBlit.self().fork(model, GitBlitWebSession.get().getUser())) { + throw new RedirectException(SummaryPage.class, WicketUtils.newRepositoryParameter(clonedRepo)); + } else { + error(MessageFormat.format(getString("gb.repositoryForkFailed"), model)); + } + } + }; + forkLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format( + getString("gb.forkRepository"), getRepositoryModel()))); + add(forkLink); + } else { + // user not allowed to fork or fork already exists or repo forbids forking + add(new ExternalLink("forkLink", "").setVisible(false)); + } + + if (hasClone) { + // user has clone + String url = getRequestCycle().urlFor(SummaryPage.class, WicketUtils.newRepositoryParameter(clonedRepo)).toString(); + add(new ExternalLink("myForkLink", url)); + } else { + // user does not have clone + add(new ExternalLink("myForkLink", "").setVisible(false)); + } + } else { + // server prohibits forking + add(new ExternalLink("forkLink", "").setVisible(false)); + add(new ExternalLink("myForkLink", "").setVisible(false)); + } + super.setupPage(repositoryName, pageName); } @@ -312,7 +409,7 @@ } protected void addRefs(Repository r, RevCommit c) { - add(new RefsPanel("refsPanel", repositoryName, c, JGitUtils.getAllRefs(r))); + add(new RefsPanel("refsPanel", repositoryName, c, JGitUtils.getAllRefs(r, getRepositoryModel().showRemoteBranches))); } protected void addFullText(String wicketId, String text, boolean substituteRegex) { -- Gitblit v1.9.1