diff options
Diffstat (limited to 'src/com')
-rw-r--r-- | src/com/gitblit/GitBlit.java | 13 | ||||
-rw-r--r-- | src/com/gitblit/models/RepositoryModel.java | 4 | ||||
-rw-r--r-- | src/com/gitblit/utils/JGitUtils.java | 86 | ||||
-rw-r--r-- | src/com/gitblit/wicket/GitBlitWebApp.properties | 2 | ||||
-rw-r--r-- | src/com/gitblit/wicket/pages/EditRepositoryPage.html | 26 | ||||
-rw-r--r-- | src/com/gitblit/wicket/pages/EditRepositoryPage.java | 19 |
6 files changed, 83 insertions, 67 deletions
diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index b6bf7bf9..72161263 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -69,7 +69,6 @@ import com.gitblit.models.FederationModel; import com.gitblit.models.FederationProposal;
import com.gitblit.models.FederationSet;
import com.gitblit.models.Metric;
-import com.gitblit.models.RefModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.ServerSettings;
import com.gitblit.models.ServerStatus;
@@ -787,10 +786,8 @@ public class GitBlit implements ServletContextListener { model.mailingLists = new ArrayList<String>(Arrays.asList(config.getStringList(
"gitblit", null, "mailingList")));
}
- model.defaultHead = JGitUtils.getDefaultHead(r);
- model.availableHeads = new ArrayList<RefModel>();
- model.availableHeads.addAll(JGitUtils.getLocalBranches(r, true, -1));
- model.availableHeads.addAll(JGitUtils.getTags(r, true, -1));
+ model.defaultHead = JGitUtils.getSymbolicHeadTarget(r);
+ model.availableHeads = JGitUtils.getAvailableHeadTargets(r);
r.close();
return model;
}
@@ -986,8 +983,10 @@ public class GitBlit implements ServletContextListener { // update settings
if (r != null) {
updateConfiguration(r, repository);
- if (repository.defaultHead != null) {
- JGitUtils.setDefaultHead(r, repository.defaultHead.reference);
+ // only update symbolic head if it changes
+ if (!StringUtils.isEmpty(repository.defaultHead) &&
+ !repository.defaultHead.equals(JGitUtils.getSymbolicHeadTarget(r))) {
+ JGitUtils.setSymbolicHeadTarget(r, repository.defaultHead);
}
r.close();
}
diff --git a/src/com/gitblit/models/RepositoryModel.java b/src/com/gitblit/models/RepositoryModel.java index d3e91588..e7a0880d 100644 --- a/src/com/gitblit/models/RepositoryModel.java +++ b/src/com/gitblit/models/RepositoryModel.java @@ -58,8 +58,8 @@ public class RepositoryModel implements Serializable, Comparable<RepositoryModel public List<String> preReceiveScripts;
public List<String> postReceiveScripts;
public List<String> mailingLists;
- public RefModel defaultHead;
- public List<RefModel> availableHeads;
+ public String defaultHead;
+ public List<String> availableHeads;
private String displayName;
diff --git a/src/com/gitblit/utils/JGitUtils.java b/src/com/gitblit/utils/JGitUtils.java index 05c0852c..6470634c 100644 --- a/src/com/gitblit/utils/JGitUtils.java +++ b/src/com/gitblit/utils/JGitUtils.java @@ -1156,49 +1156,60 @@ public class JGitUtils { }
/**
- * Returns the default HEAD for a repository. Normally returns the ref HEAD points to, but if HEAD points to nothing
- * it returns null.
+ * Returns the target of the symbolic HEAD reference for a repository.
+ * Normally returns a branch reference name, but when HEAD is detached,
+ * the commit is matched against the known tags. The most recent matching
+ * tag ref name will be returned if it references the HEAD commit. If
+ * no match is found, the SHA1 is returned.
*
* @param repository
- * @return the refmodel for HEAD or null
+ * @return the ref name or the SHA1 for detached HEADs
*/
- public static RefModel getDefaultHead(Repository repository) {
- RefModel ref = null;
+ public static String getSymbolicHeadTarget(Repository repository) {
+ String target = null;
try {
- Ref head = repository.getRef(Constants.HEAD);
- if (head != null) {
- Ref target = head.getTarget();
- RevWalk rw = new RevWalk(repository);
- ObjectId targetId = target.getObjectId();
- if (targetId != null) {
- RevObject object = rw.parseAny(targetId);
- ref = new RefModel(target.getName(), target, object);
+ target = repository.getFullBranch();
+ if (!target.startsWith(Constants.R_HEADS)) {
+ // refers to an actual commit, probably a tag
+ // find latest tag that matches the commit, if any
+ List<RefModel> tagModels = getTags(repository, true, -1);
+ if (tagModels.size() > 0) {
+ RefModel tag = null;
+ Date lastDate = new Date(0);
+ for (RefModel tagModel : tagModels) {
+ if (tagModel.getReferencedObjectId().getName().equals(target) &&
+ tagModel.getDate().after(lastDate)) {
+ tag = tagModel;
+ lastDate = tag.getDate();
+ }
+ }
+ target = tag.getName();
}
- rw.dispose();
}
} catch (Throwable t) {
- LOGGER.error("Failed to get default head!", t);
+ error(t, repository, "{0} failed to get symbolic HEAD target");
}
- return ref;
+ return target;
}
-
+
/**
- * Sets the default HEAD symbolic ref for a repository.
+ * Sets the HEAD symbolic ref name for a repository. The HEAD will
+ * be detached if the name does not reference a branch.
*
* @param repository
- * @param ref
+ * @param name
*/
- public static void setDefaultHead(Repository repository, Ref ref) {
+ public static void setSymbolicHeadTarget(Repository repository, String name) {
try {
- boolean detach = !ref.getName().startsWith(Constants.R_HEADS); // detach if not a branch
+ boolean detach = !name.startsWith(Constants.R_HEADS); // detach if not a branch
RefUpdate.Result result;
RefUpdate head = repository.updateRef(Constants.HEAD, detach);
if (detach) { // Tag
- RevCommit commit = getCommit(repository, ref.getObjectId().getName());
+ RevCommit commit = getCommit(repository, name);
head.setNewObjectId(commit.getId());
result = head.forceUpdate();
} else {
- result = head.link(ref.getName());
+ result = head.link(name);
}
switch (result) {
case NEW:
@@ -1207,12 +1218,35 @@ public class JGitUtils { case FAST_FORWARD:
break;
default:
- LOGGER.error(MessageFormat.format("{0} failed to set default head to {1} ({2})",
- repository.getDirectory().getAbsolutePath(), ref.getName(), result));
+ LOGGER.error(MessageFormat.format("{0} symbolic HEAD update to {1} returned result {2}",
+ repository.getDirectory().getAbsolutePath(), name, result));
}
} catch (Throwable t) {
- error(t, repository, "{0} failed to set default head to {1}", ref.getName());
+ error(t, repository, "{0} failed to set symbolic HEAD to {1}", name);
+ }
+ }
+
+ /**
+ * Get the full branch and tag ref names for any potential symbolic head targets.
+ *
+ * @param repository
+ * @return a list of ref names
+ */
+ public static List<String> getAvailableHeadTargets(Repository repository) {
+ List<String> targets = new ArrayList<String>();
+ List<RefModel> branchModels = JGitUtils.getLocalBranches(repository, true, -1);
+ if (branchModels.size() > 0) {
+ for (RefModel branchModel : branchModels) {
+ targets.add(branchModel.getName());
+ }
+ }
+ List<RefModel> tagModels = JGitUtils.getTags(repository, true, -1);
+ if (tagModels.size() > 0) {
+ for (RefModel tagModel : tagModels) {
+ targets.add(tagModel.getName());
+ }
}
+ return targets;
}
/**
diff --git a/src/com/gitblit/wicket/GitBlitWebApp.properties b/src/com/gitblit/wicket/GitBlitWebApp.properties index b6e45236..f039a36a 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp.properties @@ -131,7 +131,7 @@ gb.registrations = federation registrations gb.sendProposal propose
gb.status = status
gb.origin = origin
-gb.defaultHead = default head
+gb.defaultHead = default HEAD
gb.defaultHeadDescription = current branch after clone. e.g. refs/heads/master
gb.federationStrategy = federation strategy
gb.federationRegistration = federation registration
diff --git a/src/com/gitblit/wicket/pages/EditRepositoryPage.html b/src/com/gitblit/wicket/pages/EditRepositoryPage.html index 98789304..9bd8c515 100644 --- a/src/com/gitblit/wicket/pages/EditRepositoryPage.html +++ b/src/com/gitblit/wicket/pages/EditRepositoryPage.html @@ -14,27 +14,27 @@ <tr><th><wicket:message key="gb.name"></wicket:message></th><td class="edit"><input class="span6" type="text" wicket:id="name" id="name" size="40" tabindex="1" /> <span class="help-inline"><wicket:message key="gb.nameDescription"></wicket:message></span></td></tr>
<tr><th><wicket:message key="gb.description"></wicket:message></th><td class="edit"><input class="span6" type="text" wicket:id="description" size="40" tabindex="2" /></td></tr>
<tr><th><wicket:message key="gb.origin"></wicket:message></th><td class="edit"><input class="span7" type="text" wicket:id="origin" size="80" tabindex="3" /></td></tr>
- <tr><th><wicket:message key="gb.defaultHead"></wicket:message></th><td class="edit"><select wicket:id="defaultHead" /> <span class="help-inline"><wicket:message key="gb.defaultHeadDescription"></wicket:message></span></td></tr>
- <tr><th><wicket:message key="gb.owner"></wicket:message></th><td class="edit"><select wicket:id="owner" tabindex="4" /> <span class="help-inline"><wicket:message key="gb.ownerDescription"></wicket:message></span></td></tr>
- <tr><th><wicket:message key="gb.enableTickets"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="useTickets" tabindex="5" /> <span class="help-inline"><wicket:message key="gb.useTicketsDescription"></wicket:message></span></td></tr>
- <tr><th><wicket:message key="gb.enableDocs"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="useDocs" tabindex="6" /> <span class="help-inline"><wicket:message key="gb.useDocsDescription"></wicket:message></span></td></tr>
- <tr><th><wicket:message key="gb.showRemoteBranches"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="showRemoteBranches" tabindex="7" /> <span class="help-inline"><wicket:message key="gb.showRemoteBranchesDescription"></wicket:message></span></td></tr>
- <tr><th><wicket:message key="gb.showReadme"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="showReadme" tabindex="8" /> <span class="help-inline"><wicket:message key="gb.showReadmeDescription"></wicket:message></span></td></tr>
- <tr><th><wicket:message key="gb.skipSizeCalculation"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="skipSizeCalculation" tabindex="9" /> <span class="help-inline"><wicket:message key="gb.skipSizeCalculationDescription"></wicket:message></span></td></tr>
- <tr><th><wicket:message key="gb.skipSummaryMetrics"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="skipSummaryMetrics" tabindex="10" /> <span class="help-inline"><wicket:message key="gb.skipSummaryMetricsDescription"></wicket:message></span></td></tr>
- <tr><th><wicket:message key="gb.isFrozen"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="isFrozen" tabindex="11" /> <span class="help-inline"><wicket:message key="gb.isFrozenDescription"></wicket:message></span></td></tr>
- <tr><th><wicket:message key="gb.mailingLists"></wicket:message></th><td class="edit"><input class="span14" type="text" wicket:id="mailingLists" size="40" tabindex="12" /></td></tr>
+ <tr><th><wicket:message key="gb.defaultHead"></wicket:message></th><td class="edit"><select wicket:id="defaultHead" tabindex="4" /> <span class="help-inline"><wicket:message key="gb.defaultHeadDescription"></wicket:message></span></td></tr>
+ <tr><th><wicket:message key="gb.owner"></wicket:message></th><td class="edit"><select wicket:id="owner" tabindex="5" /> <span class="help-inline"><wicket:message key="gb.ownerDescription"></wicket:message></span></td></tr>
+ <tr><th><wicket:message key="gb.enableTickets"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="useTickets" tabindex="6" /> <span class="help-inline"><wicket:message key="gb.useTicketsDescription"></wicket:message></span></td></tr>
+ <tr><th><wicket:message key="gb.enableDocs"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="useDocs" tabindex="7" /> <span class="help-inline"><wicket:message key="gb.useDocsDescription"></wicket:message></span></td></tr>
+ <tr><th><wicket:message key="gb.showRemoteBranches"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="showRemoteBranches" tabindex="8" /> <span class="help-inline"><wicket:message key="gb.showRemoteBranchesDescription"></wicket:message></span></td></tr>
+ <tr><th><wicket:message key="gb.showReadme"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="showReadme" tabindex="9" /> <span class="help-inline"><wicket:message key="gb.showReadmeDescription"></wicket:message></span></td></tr>
+ <tr><th><wicket:message key="gb.skipSizeCalculation"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="skipSizeCalculation" tabindex="10" /> <span class="help-inline"><wicket:message key="gb.skipSizeCalculationDescription"></wicket:message></span></td></tr>
+ <tr><th><wicket:message key="gb.skipSummaryMetrics"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="skipSummaryMetrics" tabindex="11" /> <span class="help-inline"><wicket:message key="gb.skipSummaryMetricsDescription"></wicket:message></span></td></tr>
+ <tr><th><wicket:message key="gb.isFrozen"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="isFrozen" tabindex="12" /> <span class="help-inline"><wicket:message key="gb.isFrozenDescription"></wicket:message></span></td></tr>
+ <tr><th><wicket:message key="gb.mailingLists"></wicket:message></th><td class="edit"><input class="span14" type="text" wicket:id="mailingLists" size="40" tabindex="13" /></td></tr>
<tr><td colspan="2" style="padding-top:15px"><h3><wicket:message key="gb.accessPermissions"></wicket:message> <small><wicket:message key="gb.accessPermissionsDescription"></wicket:message></small></h3></td></tr>
- <tr><th><wicket:message key="gb.accessRestriction"></wicket:message></th><td class="edit"><select class="span6" wicket:id="accessRestriction" tabindex="13" /></td></tr>
+ <tr><th><wicket:message key="gb.accessRestriction"></wicket:message></th><td class="edit"><select class="span6" wicket:id="accessRestriction" tabindex="14" /></td></tr>
<tr><th style="vertical-align: top;"><wicket:message key="gb.permittedUsers"></wicket:message></th><td style="padding:2px;"><span wicket:id="users"></span></td></tr>
<tr><th style="vertical-align: top;"><wicket:message key="gb.permittedTeams"></wicket:message></th><td style="padding:2px;"><span wicket:id="teams"></span></td></tr>
<tr><td colspan="2"><h3><wicket:message key="gb.federation"></wicket:message> <small><wicket:message key="gb.federationRepositoryDescription"></wicket:message></small></h3></td></tr>
- <tr><th><wicket:message key="gb.federationStrategy"></wicket:message></th><td class="edit"><select class="span6" wicket:id="federationStrategy" tabindex="14" /></td></tr>
+ <tr><th><wicket:message key="gb.federationStrategy"></wicket:message></th><td class="edit"><select class="span6" wicket:id="federationStrategy" tabindex="15" /></td></tr>
<tr><th style="vertical-align: top;"><wicket:message key="gb.federationSets"></wicket:message></th><td style="padding:2px;"><span wicket:id="federationSets"></span></td></tr>
<tr><td colspan="2"><h3><wicket:message key="gb.hookScripts"></wicket:message> <small><wicket:message key="gb.hookScriptsDescription"></wicket:message></small></h3></td></tr>
<tr><th style="vertical-align: top;"><wicket:message key="gb.preReceiveScripts"></wicket:message><p></p><span wicket:id="inheritedPreReceive"></span></th><td style="padding:2px;"><span wicket:id="preReceiveScripts"></span></td></tr>
<tr><th style="vertical-align: top;"><wicket:message key="gb.postReceiveScripts"></wicket:message><p></p><span wicket:id="inheritedPostReceive"></span></th><td style="padding:2px;"><span wicket:id="postReceiveScripts"></span></td></tr>
- <tr><td colspan='2'><div class="actions" "><input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="15" /> <input class="btn primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="16" /></div></td></tr>
+ <tr><td colspan='2'><div class="actions" "><input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="16" /> <input class="btn primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="16" /></div></td></tr>
</tbody>
</table>
</form>
diff --git a/src/com/gitblit/wicket/pages/EditRepositoryPage.java b/src/com/gitblit/wicket/pages/EditRepositoryPage.java index 6c042497..a16d7e40 100644 --- a/src/com/gitblit/wicket/pages/EditRepositoryPage.java +++ b/src/com/gitblit/wicket/pages/EditRepositoryPage.java @@ -45,7 +45,6 @@ import com.gitblit.Constants.FederationStrategy; import com.gitblit.GitBlit;
import com.gitblit.GitBlitException;
import com.gitblit.Keys;
-import com.gitblit.models.RefModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.ArrayUtils;
@@ -273,8 +272,7 @@ public class EditRepositoryPage extends RootSubPage { // TODO enable origin definition
form.add(new TextField<String>("origin").setEnabled(false/* isCreate */));
// enable alteration of the default branch after clone
- form.add(new DropDownChoice<RefModel>("defaultHead", repositoryModel.availableHeads,
- new RefModelRenderer()).setEnabled(GitBlitWebSession.get().canAdmin()));
+ form.add(new DropDownChoice<String>("defaultHead", repositoryModel.availableHeads));
// federation strategies - remove ORIGIN choice if this repository has
// no origin.
@@ -365,21 +363,6 @@ public class EditRepositoryPage extends RootSubPage { }
}
- private class RefModelRenderer implements IChoiceRenderer<RefModel> {
-
- private static final long serialVersionUID = 1L;
-
- @Override
- public String getDisplayValue(RefModel type) {
- return type.displayName;
- }
-
- @Override
- public String getIdValue(RefModel type, int index) {
- return type.getName();
- }
- }
-
private class AccessRestrictionRenderer implements IChoiceRenderer<AccessRestrictionType> {
private static final long serialVersionUID = 1L;
|