From 6b18b0761b726fd9aef1ebcc21b760378f7d4b5c Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Mon, 16 Jun 2014 17:36:12 -0400
Subject: [PATCH] Merge release 1.6.0

---
 src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java |  372 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 372 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java b/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java
new file mode 100644
index 0000000..4687716
--- /dev/null
+++ b/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java
@@ -0,0 +1,372 @@
+/*
+ * Copyright 2014 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.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.wicket.behavior.SimpleAttributeModifier;
+import org.apache.wicket.markup.html.form.Button;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheBuilder;
+import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.jgit.lib.CommitBuilder;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.RefUpdate.Result;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+
+import com.gitblit.Constants;
+import com.gitblit.Constants.AccessRestrictionType;
+import com.gitblit.Constants.AuthorizationControl;
+import com.gitblit.GitBlitException;
+import com.gitblit.Keys;
+import com.gitblit.models.RepositoryModel;
+import com.gitblit.models.UserModel;
+import com.gitblit.utils.ArrayUtils;
+import com.gitblit.utils.FileUtils;
+import com.gitblit.utils.StringUtils;
+import com.gitblit.wicket.GitBlitWebSession;
+import com.gitblit.wicket.WicketUtils;
+import com.gitblit.wicket.panels.AccessPolicyPanel;
+import com.gitblit.wicket.panels.BooleanChoiceOption;
+import com.gitblit.wicket.panels.BooleanOption;
+import com.gitblit.wicket.panels.RepositoryNamePanel;
+
+public class NewRepositoryPage extends RootSubPage {
+
+	private final RepositoryModel repositoryModel;
+	private IModel<Boolean> addReadmeModel;
+	private Model<String> gitignoreModel;
+	private IModel<Boolean> addGitflowModel;
+	private IModel<Boolean> addGitignoreModel;
+	private AccessPolicyPanel accessPolicyPanel;
+	private RepositoryNamePanel namePanel;
+
+	public NewRepositoryPage() {
+		// create constructor
+		super();
+		repositoryModel = new RepositoryModel();
+
+		setupPage(getString("gb.newRepository"), "");
+
+		setStatelessHint(false);
+		setOutputMarkupId(true);
+	}
+
+	@Override
+	protected boolean requiresPageMap() {
+		return true;
+	}
+
+	@Override
+	protected Class<? extends BasePage> getRootNavPageClass() {
+		return RepositoriesPage.class;
+	}
+
+	@Override
+	protected void onInitialize() {
+		super.onInitialize();
+
+		CompoundPropertyModel<RepositoryModel> rModel = new CompoundPropertyModel<>(repositoryModel);
+		Form<RepositoryModel> form = new Form<RepositoryModel>("editForm", rModel) {
+
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			protected void onSubmit() {
+				try {
+					if (!namePanel.updateModel(repositoryModel)) {
+						return;
+					}
+					accessPolicyPanel.updateModel(repositoryModel);
+
+					repositoryModel.owners = new ArrayList<String>();
+					repositoryModel.owners.add(GitBlitWebSession.get().getUsername());
+
+					// setup branch defaults
+					boolean useGitFlow = addGitflowModel.getObject();
+
+					repositoryModel.HEAD = Constants.R_MASTER;
+					repositoryModel.mergeTo = Constants.MASTER;
+					if (useGitFlow) {
+						// tickets normally merge to develop unless they are hotfixes
+						repositoryModel.mergeTo = Constants.DEVELOP;
+					}
+
+					repositoryModel.allowForks = app().settings().getBoolean(Keys.web.allowForking, true);
+
+					// optionally generate an initial commit
+					boolean addReadme = addReadmeModel.getObject();
+					String gitignore = null;
+					boolean addGitignore = addGitignoreModel.getObject();
+					if (addGitignore) {
+						gitignore = gitignoreModel.getObject();
+						if (StringUtils.isEmpty(gitignore)) {
+							throw new GitBlitException(getString("gb.pleaseSelectGitIgnore"));
+						}
+					}
+
+					// init the repository
+					app().gitblit().updateRepositoryModel(repositoryModel.name, repositoryModel, true);
+
+					// optionally create an initial commit
+					initialCommit(repositoryModel, addReadme, gitignore, useGitFlow);
+
+				} catch (GitBlitException e) {
+					error(e.getMessage());
+					return;
+				}
+				setRedirect(true);
+				setResponsePage(SummaryPage.class, WicketUtils.newRepositoryParameter(repositoryModel.name));
+			}
+		};
+
+		// do not let the browser pre-populate these fields
+		form.add(new SimpleAttributeModifier("autocomplete", "off"));
+
+		namePanel = new RepositoryNamePanel("namePanel", repositoryModel);
+		form.add(namePanel);
+
+		// prepare the default access controls
+		AccessRestrictionType defaultRestriction = AccessRestrictionType.fromName(
+				app().settings().getString(Keys.git.defaultAccessRestriction, AccessRestrictionType.PUSH.name()));
+		if (AccessRestrictionType.NONE == defaultRestriction) {
+			defaultRestriction = AccessRestrictionType.PUSH;
+		}
+		AuthorizationControl defaultControl = AuthorizationControl.fromName(
+				app().settings().getString(Keys.git.defaultAuthorizationControl, AuthorizationControl.NAMED.name()));
+
+		if (AuthorizationControl.AUTHENTICATED == defaultControl) {
+			defaultRestriction = AccessRestrictionType.PUSH;
+		}
+
+		repositoryModel.authorizationControl = defaultControl;
+		repositoryModel.accessRestriction = defaultRestriction;
+
+		accessPolicyPanel = new AccessPolicyPanel("accessPolicyPanel", repositoryModel);
+		form.add(accessPolicyPanel);
+
+		//
+		// initial commit options
+		//
+
+		// add README
+		addReadmeModel = Model.of(false);
+		form.add(new BooleanOption("addReadme",
+				getString("gb.initWithReadme"),
+				getString("gb.initWithReadmeDescription"),
+				addReadmeModel));
+
+		// add .gitignore
+		File gitignoreDir = app().runtime().getFileOrFolder(Keys.git.gitignoreFolder, "${baseFolder}/gitignore");
+		File [] files = gitignoreDir.listFiles();
+		if (files == null) {
+			files = new File[0];
+		}
+		List<String> gitignores = new ArrayList<String>();
+		for (File file : files) {
+			if (file.isFile() && file.getName().endsWith(".gitignore")) {
+				gitignores.add(StringUtils.stripFileExtension(file.getName()));
+			}
+		}
+		Collections.sort(gitignores);
+
+		gitignoreModel = Model.of("");
+		addGitignoreModel = Model.of(false);
+		form.add(new BooleanChoiceOption<String>("addGitIgnore",
+				getString("gb.initWithGitignore"),
+				getString("gb.initWithGitignoreDescription"),
+				addGitignoreModel,
+				gitignoreModel,
+				gitignores).setVisible(gitignores.size() > 0));
+
+		// TODO consider gitflow at creation (ticket-55)
+		addGitflowModel = Model.of(false);
+		form.add(new BooleanOption("addGitFlow",
+				"Include a .gitflow file",
+				"This will generate a config file which guides Git clients in setting up Gitflow branches.",
+				addGitflowModel).setVisible(false));
+
+		form.add(new Button("create"));
+
+		add(form);
+	}
+
+	/**
+	 * Prepare the initial commit for the repository.
+	 *
+	 * @param repository
+	 * @param addReadme
+	 * @param gitignore
+	 * @param addGitFlow
+	 * @return true if an initial commit was created
+	 */
+	protected boolean initialCommit(RepositoryModel repository, boolean addReadme, String gitignore,
+			boolean addGitFlow) {
+		boolean initialCommit = addReadme || !StringUtils.isEmpty(gitignore) || addGitFlow;
+		if (!initialCommit) {
+			return false;
+		}
+
+		// build an initial commit
+		boolean success = false;
+		Repository db = app().repositories().getRepository(repositoryModel.name);
+		ObjectInserter odi = db.newObjectInserter();
+		try {
+
+			UserModel user = GitBlitWebSession.get().getUser();
+			PersonIdent author = new PersonIdent(user.getDisplayName(), user.emailAddress);
+
+			DirCache newIndex = DirCache.newInCore();
+			DirCacheBuilder indexBuilder = newIndex.builder();
+
+			if (addReadme) {
+				// insert a README
+				String title = StringUtils.stripDotGit(StringUtils.getLastPathElement(repositoryModel.name));
+				String description = repositoryModel.description == null ? "" : repositoryModel.description;
+				String readme = String.format("## %s\n\n%s\n\n", title, description);
+				byte [] bytes = readme.getBytes(Constants.ENCODING);
+
+				DirCacheEntry entry = new DirCacheEntry("README.md");
+				entry.setLength(bytes.length);
+				entry.setLastModified(System.currentTimeMillis());
+				entry.setFileMode(FileMode.REGULAR_FILE);
+				entry.setObjectId(odi.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, bytes));
+
+				indexBuilder.add(entry);
+			}
+
+			if (!StringUtils.isEmpty(gitignore)) {
+				// insert a .gitignore file
+				File dir = app().runtime().getFileOrFolder(Keys.git.gitignoreFolder, "${baseFolder}/gitignore");
+				File file = new File(dir, gitignore + ".gitignore");
+				if (file.exists() && file.length() > 0) {
+					byte [] bytes = FileUtils.readContent(file);
+					if (!ArrayUtils.isEmpty(bytes)) {
+						DirCacheEntry entry = new DirCacheEntry(".gitignore");
+						entry.setLength(bytes.length);
+						entry.setLastModified(System.currentTimeMillis());
+						entry.setFileMode(FileMode.REGULAR_FILE);
+						entry.setObjectId(odi.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, bytes));
+
+						indexBuilder.add(entry);
+					}
+				}
+			}
+
+			if (addGitFlow) {
+				// insert a .gitflow file
+				Config config = new Config();
+				config.setString("gitflow", null, "masterBranch", Constants.MASTER);
+				config.setString("gitflow", null, "developBranch", Constants.DEVELOP);
+				config.setString("gitflow", null, "featureBranchPrefix", "feature/");
+				config.setString("gitflow", null, "releaseBranchPrefix", "release/");
+				config.setString("gitflow", null, "hotfixBranchPrefix", "hotfix/");
+				config.setString("gitflow", null, "supportBranchPrefix", "support/");
+				config.setString("gitflow", null, "versionTagPrefix", "");
+
+				byte [] bytes = config.toText().getBytes(Constants.ENCODING);
+
+				DirCacheEntry entry = new DirCacheEntry(".gitflow");
+				entry.setLength(bytes.length);
+				entry.setLastModified(System.currentTimeMillis());
+				entry.setFileMode(FileMode.REGULAR_FILE);
+				entry.setObjectId(odi.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, bytes));
+
+				indexBuilder.add(entry);
+			}
+
+			indexBuilder.finish();
+
+			if (newIndex.getEntryCount() == 0) {
+				// nothing to commit
+				return false;
+			}
+
+			ObjectId treeId = newIndex.writeTree(odi);
+
+			// Create a commit object
+			CommitBuilder commit = new CommitBuilder();
+			commit.setAuthor(author);
+			commit.setCommitter(author);
+			commit.setEncoding(Constants.ENCODING);
+			commit.setMessage("Initial commit");
+			commit.setTreeId(treeId);
+
+			// Insert the commit into the repository
+			ObjectId commitId = odi.insert(commit);
+			odi.flush();
+
+			// set the branch refs
+			RevWalk revWalk = new RevWalk(db);
+			try {
+				// set the master branch
+				RevCommit revCommit = revWalk.parseCommit(commitId);
+				RefUpdate masterRef = db.updateRef(Constants.R_MASTER);
+				masterRef.setNewObjectId(commitId);
+				masterRef.setRefLogMessage("commit: " + revCommit.getShortMessage(), false);
+				Result masterRC = masterRef.update();
+				switch (masterRC) {
+				case NEW:
+					success = true;
+					break;
+				default:
+					success = false;
+				}
+
+				if (addGitFlow) {
+					// set the develop branch for git-flow
+					RefUpdate developRef = db.updateRef(Constants.R_DEVELOP);
+					developRef.setNewObjectId(commitId);
+					developRef.setRefLogMessage("commit: " + revCommit.getShortMessage(), false);
+					Result developRC = developRef.update();
+					switch (developRC) {
+					case NEW:
+						success = true;
+						break;
+					default:
+						success = false;
+					}
+				}
+			} finally {
+				revWalk.release();
+			}
+		} catch (UnsupportedEncodingException e) {
+			logger().error(null, e);
+		} catch (IOException e) {
+			logger().error(null, e);
+		} finally {
+			odi.release();
+			db.close();
+		}
+		return success;
+	}
+}

--
Gitblit v1.9.1