James Moger
2013-05-30 79d3240ea489067f3eb1af5e535b3687c507a249
Added simple star/unstar function
2 files added
8 files modified
8490 ■■■■ changed files
releases.moxie 1 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/ConfigUserService.java 21 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/GitBlit.java 7312 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/IStoredSettings.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/gitblit/models/UserModel.java 8 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/models/UserPreferences.java 91 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/models/UserRepositoryPreferences.java 40 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/GitBlitWebApp.properties 948 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/RepositoryPage.html 9 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/RepositoryPage.java 58 ●●●●● patch | view | raw | blame | history
releases.moxie
@@ -39,6 +39,7 @@
     - Updated Japanese translation
     
    additions: 
     - Added simple star/unstar function to flag or bookmark interesting repositories
     - Added a ui for the push log introduced in 1.2.1 (issue-177)
     - Added client application menus for Git, SourceTree, Tower, GitHub for Windows, GitHub for Mac, and SparkleShare
     - Added GO http/https connector thread pool size setting
src/main/java/com/gitblit/ConfigUserService.java
@@ -37,6 +37,7 @@
import com.gitblit.Constants.AccessPermission;
import com.gitblit.models.TeamModel;
import com.gitblit.models.UserModel;
import com.gitblit.models.UserRepositoryPreferences;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.DeepCopier;
import com.gitblit.utils.StringUtils;
@@ -88,7 +89,9 @@
    private static final String PRERECEIVE = "preReceiveScript";
    private static final String POSTRECEIVE = "postReceiveScript";
    private static final String STARRED = "starred";
    private final File realmFile;
    private final Logger logger = LoggerFactory.getLogger(ConfigUserService.class);
@@ -879,6 +882,14 @@
                }
                config.setStringList(USER, model.username, REPOSITORY, permissions);
            }
            // user preferences
            if (model.getPreferences() != null) {
                List<String> starred =  model.getPreferences().getStarredRepositories();
                if (starred.size() > 0) {
                    config.setStringList(USER, model.username, STARRED, starred);
                }
            }
        }
        // write teams
@@ -1021,6 +1032,14 @@
                        }
                    }
                    // starred repositories
                    Set<String> starred = new HashSet<String>(Arrays.asList(config
                            .getStringList(USER, username, STARRED)));
                    for (String repository : starred) {
                        UserRepositoryPreferences prefs = user.getPreferences().getRepositoryPreferences(repository);
                        prefs.starred = true;
                    }
                    // update cache
                    users.put(user.username, user);
                    if (!StringUtils.isEmpty(user.cookie)) {
src/main/java/com/gitblit/GitBlit.java
Diff too large
src/main/java/com/gitblit/IStoredSettings.java
@@ -161,7 +161,7 @@
    
    /**
     * Returns an long filesize from a string value such as 50m or 50mb
     * @param name
     * @param n
     * @param defaultValue
     * @return a long filesize or defaultValue if the key does not exist or can
     *         not be parsed
src/main/java/com/gitblit/models/UserModel.java
@@ -75,17 +75,21 @@
    // non-persisted fields
    public boolean isAuthenticated;
    public AccountType accountType;
    public UserPreferences userPreferences;
    
    public UserModel(String username) {
        this.username = username;
        this.isAuthenticated = true;
        this.accountType = AccountType.LOCAL;
        this.userPreferences = new UserPreferences(this.username);
    }
    private UserModel() {
        this.username = "$anonymous";
        this.isAuthenticated = false;
        this.accountType = AccountType.LOCAL;
        this.userPreferences = new UserPreferences(this.username);
    }
    
    public boolean isLocalAccount() {
@@ -602,6 +606,10 @@
        return "~" + username;
    }
    
    public UserPreferences getPreferences() {
        return userPreferences;
    }
    @Override
    public int hashCode() {
        return username.hashCode();
src/main/java/com/gitblit/models/UserPreferences.java
New file
@@ -0,0 +1,91 @@
/*
 * Copyright 2013 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.models;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import com.gitblit.utils.StringUtils;
/**
 * User preferences.
 *
 * @author James Moger
 *
 */
public class UserPreferences implements Serializable {
    private static final long serialVersionUID = 1L;
    public final String username;
    private final Map<String, UserRepositoryPreferences> repositoryPreferences = new TreeMap<String, UserRepositoryPreferences>();
    public UserPreferences(String username) {
        this.username = username;
    }
    public Locale getLocale() {
        if (StringUtils.isEmpty(locale)) {
            return null;
        }
        return new Locale(locale);
    }
    public UserRepositoryPreferences getRepositoryPreferences(String repositoryName) {
        String key = repositoryName.toLowerCase();
        if (!repositoryPreferences.containsKey(key)) {
            // default preferences
            UserRepositoryPreferences prefs = new UserRepositoryPreferences();
            prefs.username = username;
            prefs.repositoryName = repositoryName;
            repositoryPreferences.put(key, prefs);
        }
        return repositoryPreferences.get(key);
    }
    public void setRepositoryPreferences(UserRepositoryPreferences pref) {
        repositoryPreferences.put(pref.repositoryName.toLowerCase(), pref);
    }
    public boolean isStarredRepository(String repository) {
        if (repositoryPreferences == null) {
            return false;
        }
        String key = repository.toLowerCase();
        if (repositoryPreferences.containsKey(key)) {
            UserRepositoryPreferences pref = repositoryPreferences.get(key);
            return pref.starred;
        }
        return false;
    }
    public List<String> getStarredRepositories() {
        List<String> list = new ArrayList<String>();
        for (UserRepositoryPreferences prefs : repositoryPreferences.values()) {
            if (prefs.starred) {
                list.add(prefs.repositoryName);
            }
        }
        Collections.sort(list);
        return list;
    }
}
src/main/java/com/gitblit/models/UserRepositoryPreferences.java
New file
@@ -0,0 +1,40 @@
/*
 * Copyright 2013 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.models;
import java.io.Serializable;
/**
 * User repository preferences.
 *
 * @author James Moger
 *
 */
public class UserRepositoryPreferences implements Serializable {
    private static final long serialVersionUID = 1L;
    public String username;
    public String repositoryName;
    public boolean starred;
    @Override
    public String toString() {
        return username + ":" + repositoryName;
    }
}
src/main/java/com/gitblit/wicket/GitBlitWebApp.properties
@@ -1,474 +1,476 @@
gb.repository = repository
gb.owner = owner
gb.description = description
gb.lastChange = last change
gb.refs = refs
gb.tag = tag
gb.tags = tags
gb.author = author
gb.committer = committer
gb.commit = commit
gb.tree = tree
gb.parent = parent
gb.url = URL
gb.history = history
gb.raw = raw
gb.object = object
gb.ticketId = ticket id
gb.ticketAssigned = assigned
gb.ticketOpenDate = open date
gb.ticketState = state
gb.ticketComments = comments
gb.view = view
gb.local = local
gb.remote = remote
gb.branches = branches
gb.patch = patch
gb.diff = diff
gb.log = log
gb.moreLogs = more commits...
gb.allTags = all tags...
gb.allBranches = all branches...
gb.summary = summary
gb.ticket = ticket
gb.newRepository = new repository
gb.newUser = new user
gb.commitdiff = commitdiff
gb.tickets = tickets
gb.pageFirst = first
gb.pagePrevious prev
gb.pageNext = next
gb.head = HEAD
gb.blame = blame
gb.login = login
gb.logout = logout
gb.username = username
gb.password = password
gb.tagger = tagger
gb.moreHistory = more history...
gb.difftocurrent = diff to current
gb.search = search
gb.searchForAuthor = Search for commits authored by
gb.searchForCommitter = Search for commits committed by
gb.addition = addition
gb.modification = modification
gb.deletion = deletion
gb.rename = rename
gb.metrics = metrics
gb.stats = stats
gb.markdown = markdown
gb.changedFiles = changed files
gb.filesAdded = {0} files added
gb.filesModified = {0} files modified
gb.filesDeleted = {0} files deleted
gb.filesCopied = {0} files copied
gb.filesRenamed = {0} files renamed
gb.missingUsername = Missing Username
gb.edit = edit
gb.searchTypeTooltip = Select Search Type
gb.searchTooltip = Search {0}
gb.delete = delete
gb.docs = docs
gb.accessRestriction = access restriction
gb.name = name
gb.enableTickets = enable tickets
gb.enableDocs = enable docs
gb.save = save
gb.showRemoteBranches = show remote branches
gb.editUsers = edit users
gb.confirmPassword = confirm password
gb.restrictedRepositories = restricted repositories
gb.canAdmin = can admin
gb.notRestricted = anonymous view, clone, & push
gb.pushRestricted = authenticated push
gb.cloneRestricted = authenticated clone & push
gb.viewRestricted = authenticated view, clone, & push
gb.useTicketsDescription = readonly, distributed Ticgit issues
gb.useDocsDescription = enumerates Markdown documentation in repository
gb.showRemoteBranchesDescription = show remote branches
gb.canAdminDescription = can administer Gitblit server
gb.permittedUsers = permitted users
gb.isFrozen = is frozen
gb.isFrozenDescription = deny push operations
gb.zip = zip
gb.showReadme = show readme
gb.showReadmeDescription = show a \"readme\" Markdown file on the summary page
gb.nameDescription = use '/' to group repositories.  e.g. libraries/mycoollib.git
gb.ownerDescription = the owner may edit repository settings
gb.blob = blob
gb.commitActivityTrend = commit activity trend
gb.commitActivityDOW = commit activity by day of week
gb.commitActivityAuthors = primary authors by commit activity
gb.feed = feed
gb.cancel = cancel
gb.changePassword = change password
gb.isFederated = is federated
gb.federateThis = federate this repository
gb.federateOrigin = federate the origin
gb.excludeFromFederation = exclude from federation
gb.excludeFromFederationDescription = block federated Gitblit instances from pulling this account
gb.tokens = federation tokens
gb.tokenAllDescription = all repositories, users, & settings
gb.tokenUnrDescription = all repositories & users
gb.tokenJurDescription = all repositories
gb.federatedRepositoryDefinitions = repository definitions
gb.federatedUserDefinitions = user definitions
gb.federatedSettingDefinitions = setting definitions
gb.proposals = federation proposals
gb.received = received
gb.type = type
gb.token = token
gb.repositories = repositories
gb.proposal = proposal
gb.frequency = frequency
gb.folder = folder
gb.lastPull = last pull
gb.nextPull = next pull
gb.inclusions = inclusions
gb.exclusions = exclusions
gb.registration = registration
gb.registrations = federation registrations
gb.sendProposal = propose
gb.status = status
gb.origin = origin
gb.headRef = default branch (HEAD)
gb.headRefDescription = change the ref that HEAD links to. e.g. refs/heads/master
gb.federationStrategy = federation strategy
gb.federationRegistration = federation registration
gb.federationResults = federation pull results
gb.federationSets = federation sets
gb.message = message
gb.myUrlDescription = the publicly accessible url for your Gitblit instance
gb.destinationUrl = send to
gb.destinationUrlDescription = the url of the Gitblit instance to send your proposal
gb.users = users
gb.federation = federation
gb.error = error
gb.refresh = refresh
gb.browse = browse
gb.clone = clone
gb.filter = filter
gb.create = create
gb.servers = servers
gb.recent = recent
gb.available = available
gb.selected = selected
gb.size = size
gb.downloading = downloading
gb.loading = loading
gb.starting = starting
gb.general = general
gb.settings = settings
gb.manage = manage
gb.lastLogin = last login
gb.skipSizeCalculation = skip size calculation
gb.skipSizeCalculationDescription = do not calculate the repository size (reduces page load time)
gb.skipSummaryMetrics = skip summary metrics
gb.skipSummaryMetricsDescription = do not calculate metrics on the summary page (reduces page load time)
gb.accessLevel = access level
gb.default = default
gb.setDefault = set default
gb.since = since
gb.status = status
gb.bootDate = boot date
gb.servletContainer = servlet container
gb.heapMaximum = maximum heap
gb.heapAllocated = allocated heap
gb.heapUsed = used heap
gb.free = free
gb.version = version
gb.releaseDate = release date
gb.date = date
gb.activity = activity
gb.subscribe = subscribe
gb.branch = branch
gb.maxHits = max hits
gb.recentActivity = recent activity
gb.recentActivityStats = last {0} days / {1} commits by {2} authors
gb.recentActivityNone = last {0} days / none
gb.dailyActivity = daily activity
gb.activeRepositories = active repositories
gb.activeAuthors = active authors
gb.commits = commits
gb.teams = teams
gb.teamName = team name
gb.teamMembers = team members
gb.teamMemberships = team memberships
gb.newTeam = new team
gb.permittedTeams = permitted teams
gb.emptyRepository = empty repository
gb.repositoryUrl = repository url
gb.mailingLists = mailing lists
gb.preReceiveScripts = pre-receive scripts
gb.postReceiveScripts = post-receive scripts
gb.hookScripts = hook scripts
gb.customFields = custom fields
gb.customFieldsDescription = custom fields available to Groovy hooks
gb.accessPermissions = access permissions
gb.filters = filters
gb.generalDescription = common settings
gb.accessPermissionsDescription = restrict access by users and teams
gb.accessPermissionsForUserDescription = set team memberships or grant access to specific restricted repositories
gb.accessPermissionsForTeamDescription = set team members and grant access to specific restricted repositories
gb.federationRepositoryDescription = share this repository with other Gitblit servers
gb.hookScriptsDescription = run Groovy scripts on pushes to this Gitblit server
gb.reset = reset
gb.pages = pages
gb.workingCopy = working copy
gb.workingCopyWarning = this repository has a working copy and can not receive pushes
gb.query = query
gb.queryHelp = Standard query syntax is supported.<p/><p/>Please see <a target="_new" href="http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/queryparsersyntax.html">Lucene Query Parser Syntax</a> for details.
gb.queryResults = results {0} - {1} ({2} hits)
gb.noHits = no hits
gb.authored = authored
gb.committed = committed
gb.indexedBranches = indexed branches
gb.indexedBranchesDescription = select the branches to include in your Lucene index
gb.noIndexedRepositoriesWarning = none of your repositories are configured for Lucene indexing
gb.undefinedQueryWarning = query is undefined!
gb.noSelectedRepositoriesWarning = please select one or more repositories!
gb.luceneDisabled = Lucene indexing is disabled
gb.failedtoRead = Failed to read
gb.isNotValidFile = is not a valid file
gb.failedToReadMessage = Failed to read default message from {0}!
gb.passwordsDoNotMatch = Passwords do not match!
gb.passwordTooShort = Password is too short. Minimum length is {0} characters.
gb.passwordChanged = Password successfully changed.
gb.passwordChangeAborted = Password change aborted.
gb.pleaseSetRepositoryName = Please set repository name!
gb.illegalLeadingSlash = Leading root folder references (/) are prohibited.
gb.illegalRelativeSlash = Relative folder references (../) are prohibited.
gb.illegalCharacterRepositoryName = Illegal character ''{0}'' in repository name!
gb.selectAccessRestriction = Please select access restriction!
gb.selectFederationStrategy = Please select federation strategy!
gb.pleaseSetTeamName = Please enter a teamname!
gb.teamNameUnavailable = Team name ''{0}'' is unavailable.
gb.teamMustSpecifyRepository = A team must specify at least one repository.
gb.teamCreated = New team ''{0}'' successfully created.
gb.pleaseSetUsername = Please enter a username!
gb.usernameUnavailable = Username ''{0}'' is unavailable.
gb.combinedMd5Rename = Gitblit is configured for combined-md5 password hashing. You must enter a new password on account rename.
gb.userCreated = New user ''{0}'' successfully created.
gb.couldNotFindFederationRegistration = Could not find federation registration!
gb.failedToFindGravatarProfile = Failed to find Gravatar profile for {0}
gb.branchStats = {0} commits and {1} tags in {2}
gb.repositoryNotSpecified = Repository not specified!
gb.repositoryNotSpecifiedFor = Repository not specified for {0}!
gb.canNotLoadRepository = Can not load repository
gb.commitIsNull = Commit is null
gb.unauthorizedAccessForRepository = Unauthorized access for repository
gb.failedToFindCommit = Failed to find commit \"{0}\" in {1} for {2} page!
gb.couldNotFindFederationProposal = Could not find federation proposal!
gb.invalidUsernameOrPassword = Invalid username or password!
gb.OneProposalToReview = There is 1 federation proposal awaiting review.
gb.nFederationProposalsToReview = There are {0} federation proposals awaiting review.
gb.couldNotFindTag = Could not find tag {0}
gb.couldNotCreateFederationProposal = Could not create federation proposal!
gb.pleaseSetGitblitUrl = Please enter your Gitblit url!
gb.pleaseSetDestinationUrl = Please enter a destination url for your proposal!
gb.proposalReceived = Proposal successfully received by {0}.
gb.noGitblitFound = Sorry, {0} could not find a Gitblit instance at {1}.
gb.noProposals = Sorry, {0} is not accepting proposals at this time.
gb.noFederation = Sorry, {0} is not configured to federate with any Gitblit instances.
gb.proposalFailed = Sorry, {0} did not receive any proposal data!
gb.proposalError = Sorry, {0} reports that an unexpected error occurred!
gb.failedToSendProposal = Failed to send proposal!
gb.userServiceDoesNotPermitAddUser = {0} does not permit adding a user account!
gb.userServiceDoesNotPermitPasswordChanges = {0} does not permit password changes!
gb.displayName = display name
gb.emailAddress = email address
gb.errorAdminLoginRequired = Administration requires a login
gb.errorOnlyAdminMayCreateRepository = Only an administrator may create a repository
gb.errorOnlyAdminOrOwnerMayEditRepository = Only an administrator or the owner may edit a repository
gb.errorAdministrationDisabled = Administration is disabled
gb.lastNDays = last {0} days
gb.completeGravatarProfile = Complete profile on Gravatar.com
gb.none = none
gb.line = line
gb.content = content
gb.empty = empty
gb.inherited = inherited
gb.deleteRepository = Delete repository \"{0}\"?
gb.repositoryDeleted = Repository ''{0}'' deleted.
gb.repositoryDeleteFailed = Failed to delete repository ''{0}''!
gb.deleteUser = Delete user \"{0}\"?
gb.userDeleted = User ''{0}'' deleted.
gb.userDeleteFailed = Failed to delete user ''{0}''!
gb.time.justNow = just now
gb.time.today = today
gb.time.yesterday = yesterday
gb.time.minsAgo = {0} mins ago
gb.time.hoursAgo = {0} hours ago
gb.time.daysAgo = {0} days ago
gb.time.weeksAgo = {0} weeks ago
gb.time.monthsAgo = {0} months ago
gb.time.oneYearAgo = 1 year ago
gb.time.yearsAgo = {0} years ago
gb.duration.oneDay = 1 day
gb.duration.days = {0} days
gb.duration.oneMonth = 1 month
gb.duration.months = {0} months
gb.duration.oneYear = 1 year
gb.duration.years = {0} years
gb.authorizationControl = authorization control
gb.allowAuthenticatedDescription = grant RW+ permission to all authenticated users
gb.allowNamedDescription = grant fine-grained permissions to named users or teams
gb.markdownFailure = Failed to parse Markdown content!
gb.clearCache = clear cache
gb.projects = projects
gb.project = project
gb.allProjects = all projects
gb.copyToClipboard = copy to clipboard
gb.fork = fork
gb.forks = forks
gb.forkRepository = fork {0}?
gb.repositoryForked = {0} has been forked
gb.repositoryForkFailed= fork has failed
gb.personalRepositories = personal repositories
gb.allowForks = allow forks
gb.allowForksDescription = allow authorized users to fork this repository
gb.forkedFrom = forked from
gb.canFork = can fork
gb.canForkDescription = can fork authorized repositories to personal repositories
gb.myFork = view my fork
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 = preparing your fork...
gb.isFork = is fork
gb.canCreate = can create
gb.canCreateDescription = can create personal repositories
gb.illegalPersonalRepositoryLocation = your personal repository must be located at \"{0}\"
gb.verifyCommitter = verify committer
gb.verifyCommitterDescription = require committer identity to match pushing Gitblt user account
gb.verifyCommitterNote = all merges require "--no-ff" to enforce committer identity
gb.repositoryPermissions = repository permissions
gb.userPermissions = user permissions
gb.teamPermissions = team permissions
gb.add = add
gb.noPermission = DELETE THIS PERMISSION
gb.excludePermission = {0} (exclude)
gb.viewPermission = {0} (view)
gb.clonePermission = {0} (clone)
gb.pushPermission = {0} (push)
gb.createPermission = {0} (push, ref creation)
gb.deletePermission = {0} (push, ref creation+deletion)
gb.rewindPermission = {0} (push, ref creation+deletion+rewind)
gb.permission = permission
gb.regexPermission = this permission is set from regular expression \"{0}\"
gb.accessDenied = access denied
gb.busyCollectingGarbage = sorry, Gitblit is busy collecting garbage in {0}
gb.gcPeriod = GC period
gb.gcPeriodDescription = duration between garbage collections
gb.gcThreshold = GC threshold
gb.gcThresholdDescription = minimum total size of loose objects to trigger early garbage collection
gb.ownerPermission = repository owner
gb.administrator = admin
gb.administratorPermission = Gitblit administrator
gb.team = team
gb.teamPermission = permission set by \"{0}\" team membership
gb.missing = missing!
gb.missingPermission = the repository for this permission is missing!
gb.mutable = mutable
gb.specified = specified
gb.effective = effective
gb.organizationalUnit = organizational unit
gb.organization = organization
gb.locality = locality
gb.stateProvince = state or province
gb.countryCode = country code
gb.properties = properties
gb.issued = issued
gb.expires = expires
gb.expired = expired
gb.expiring = expiring
gb.revoked = revoked
gb.serialNumber = serial number
gb.certificates = certificates
gb.newCertificate = new certificate
gb.revokeCertificate = revoke certificate
gb.sendEmail = send email
gb.passwordHint = password hint
gb.ok = ok
gb.invalidExpirationDate = invalid expiration date!
gb.passwordHintRequired = password hint required!
gb.viewCertificate = view certificate
gb.subject = subject
gb.issuer = issuer
gb.validFrom = valid from
gb.validUntil = valid until
gb.publicKey = public key
gb.signatureAlgorithm = signature algorithm
gb.sha1FingerPrint = SHA-1 Fingerprint
gb.md5FingerPrint = MD5 Fingerprint
gb.reason = reason
gb.revokeCertificateReason = Please select a reason for certificate revocation
gb.unspecified = unspecified
gb.keyCompromise = key compromise
gb.caCompromise = CA compromise
gb.affiliationChanged = affiliation changed
gb.superseded = superseded
gb.cessationOfOperation = cessation of operation
gb.privilegeWithdrawn = privilege withdrawn
gb.time.inMinutes = in {0} mins
gb.time.inHours = in {0} hours
gb.time.inDays = in {0} days
gb.hostname = hostname
gb.hostnameRequired = Please enter a hostname
gb.newSSLCertificate = new server SSL certificate
gb.newCertificateDefaults = new certificate defaults
gb.duration = duration
gb.certificateRevoked = Certificate {0,number,0} has been revoked
gb.clientCertificateGenerated = Successfully generated new client certificate for {0}
gb.sslCertificateGenerated = Successfully generated new server SSL certificate for {0}
gb.newClientCertificateMessage = NOTE:\nThe 'password' is not the user's password, it is the password to protect the user's keystore.  This password is not saved so you must also enter a 'hint' which will be included in the user's README instructions.
gb.certificate = certificate
gb.emailCertificateBundle = email client certificate bundle
gb.pleaseGenerateClientCertificate = Please generate a client certificate for {0}
gb.clientCertificateBundleSent = Client certificate bundle for {0} sent
gb.enterKeystorePassword = Please enter the Gitblit keystore password
gb.warning = warning
gb.jceWarning = Your Java Runtime Environment does not have the \"JCE Unlimited Strength Jurisdiction Policy\" files.\nThis will limit the length of passwords you may use to encrypt your keystores to 7 characters.\nThese policy files are an optional download from Oracle.\n\nWould you like to continue and generate the certificate infrastructure anyway?\n\nAnswering No will direct your browser to Oracle's download page so that you may download the policy files.
gb.maxActivityCommits = max activity commits
gb.maxActivityCommitsDescription = maximum number of commits to contribute to the Activity page
gb.noMaximum = no maximum
gb.attributes = attributes
gb.serveCertificate = serve https with this certificate
gb.sslCertificateGeneratedRestart = Successfully generated new server SSL certificate for {0}.\nYou must restart Gitblit to use the new certificate.\n\nIf you are launching with the '--alias' parameter you will have to set that to ''--alias {0}''.
gb.validity = validity
gb.siteName = site name
gb.siteNameDescription = short, descriptive name of your server
gb.excludeFromActivity = exclude from activity page
gb.isSparkleshared = repository is Sparkleshared
gb.owners = owners
gb.sessionEnded = Session has been closed
gb.closeBrowser = Please close the browser to properly end the session.
gb.repository = repository
gb.owner = owner
gb.description = description
gb.lastChange = last change
gb.refs = refs
gb.tag = tag
gb.tags = tags
gb.author = author
gb.committer = committer
gb.commit = commit
gb.tree = tree
gb.parent = parent
gb.url = URL
gb.history = history
gb.raw = raw
gb.object = object
gb.ticketId = ticket id
gb.ticketAssigned = assigned
gb.ticketOpenDate = open date
gb.ticketState = state
gb.ticketComments = comments
gb.view = view
gb.local = local
gb.remote = remote
gb.branches = branches
gb.patch = patch
gb.diff = diff
gb.log = log
gb.moreLogs = more commits...
gb.allTags = all tags...
gb.allBranches = all branches...
gb.summary = summary
gb.ticket = ticket
gb.newRepository = new repository
gb.newUser = new user
gb.commitdiff = commitdiff
gb.tickets = tickets
gb.pageFirst = first
gb.pagePrevious prev
gb.pageNext = next
gb.head = HEAD
gb.blame = blame
gb.login = login
gb.logout = logout
gb.username = username
gb.password = password
gb.tagger = tagger
gb.moreHistory = more history...
gb.difftocurrent = diff to current
gb.search = search
gb.searchForAuthor = Search for commits authored by
gb.searchForCommitter = Search for commits committed by
gb.addition = addition
gb.modification = modification
gb.deletion = deletion
gb.rename = rename
gb.metrics = metrics
gb.stats = stats
gb.markdown = markdown
gb.changedFiles = changed files
gb.filesAdded = {0} files added
gb.filesModified = {0} files modified
gb.filesDeleted = {0} files deleted
gb.filesCopied = {0} files copied
gb.filesRenamed = {0} files renamed
gb.missingUsername = Missing Username
gb.edit = edit
gb.searchTypeTooltip = Select Search Type
gb.searchTooltip = Search {0}
gb.delete = delete
gb.docs = docs
gb.accessRestriction = access restriction
gb.name = name
gb.enableTickets = enable tickets
gb.enableDocs = enable docs
gb.save = save
gb.showRemoteBranches = show remote branches
gb.editUsers = edit users
gb.confirmPassword = confirm password
gb.restrictedRepositories = restricted repositories
gb.canAdmin = can admin
gb.notRestricted = anonymous view, clone, & push
gb.pushRestricted = authenticated push
gb.cloneRestricted = authenticated clone & push
gb.viewRestricted = authenticated view, clone, & push
gb.useTicketsDescription = readonly, distributed Ticgit issues
gb.useDocsDescription = enumerates Markdown documentation in repository
gb.showRemoteBranchesDescription = show remote branches
gb.canAdminDescription = can administer Gitblit server
gb.permittedUsers = permitted users
gb.isFrozen = is frozen
gb.isFrozenDescription = deny push operations
gb.zip = zip
gb.showReadme = show readme
gb.showReadmeDescription = show a \"readme\" Markdown file on the summary page
gb.nameDescription = use '/' to group repositories.  e.g. libraries/mycoollib.git
gb.ownerDescription = the owner may edit repository settings
gb.blob = blob
gb.commitActivityTrend = commit activity trend
gb.commitActivityDOW = commit activity by day of week
gb.commitActivityAuthors = primary authors by commit activity
gb.feed = feed
gb.cancel = cancel
gb.changePassword = change password
gb.isFederated = is federated
gb.federateThis = federate this repository
gb.federateOrigin = federate the origin
gb.excludeFromFederation = exclude from federation
gb.excludeFromFederationDescription = block federated Gitblit instances from pulling this account
gb.tokens = federation tokens
gb.tokenAllDescription = all repositories, users, & settings
gb.tokenUnrDescription = all repositories & users
gb.tokenJurDescription = all repositories
gb.federatedRepositoryDefinitions = repository definitions
gb.federatedUserDefinitions = user definitions
gb.federatedSettingDefinitions = setting definitions
gb.proposals = federation proposals
gb.received = received
gb.type = type
gb.token = token
gb.repositories = repositories
gb.proposal = proposal
gb.frequency = frequency
gb.folder = folder
gb.lastPull = last pull
gb.nextPull = next pull
gb.inclusions = inclusions
gb.exclusions = exclusions
gb.registration = registration
gb.registrations = federation registrations
gb.sendProposal = propose
gb.status = status
gb.origin = origin
gb.headRef = default branch (HEAD)
gb.headRefDescription = change the ref that HEAD links to. e.g. refs/heads/master
gb.federationStrategy = federation strategy
gb.federationRegistration = federation registration
gb.federationResults = federation pull results
gb.federationSets = federation sets
gb.message = message
gb.myUrlDescription = the publicly accessible url for your Gitblit instance
gb.destinationUrl = send to
gb.destinationUrlDescription = the url of the Gitblit instance to send your proposal
gb.users = users
gb.federation = federation
gb.error = error
gb.refresh = refresh
gb.browse = browse
gb.clone = clone
gb.filter = filter
gb.create = create
gb.servers = servers
gb.recent = recent
gb.available = available
gb.selected = selected
gb.size = size
gb.downloading = downloading
gb.loading = loading
gb.starting = starting
gb.general = general
gb.settings = settings
gb.manage = manage
gb.lastLogin = last login
gb.skipSizeCalculation = skip size calculation
gb.skipSizeCalculationDescription = do not calculate the repository size (reduces page load time)
gb.skipSummaryMetrics = skip summary metrics
gb.skipSummaryMetricsDescription = do not calculate metrics on the summary page (reduces page load time)
gb.accessLevel = access level
gb.default = default
gb.setDefault = set default
gb.since = since
gb.status = status
gb.bootDate = boot date
gb.servletContainer = servlet container
gb.heapMaximum = maximum heap
gb.heapAllocated = allocated heap
gb.heapUsed = used heap
gb.free = free
gb.version = version
gb.releaseDate = release date
gb.date = date
gb.activity = activity
gb.subscribe = subscribe
gb.branch = branch
gb.maxHits = max hits
gb.recentActivity = recent activity
gb.recentActivityStats = last {0} days / {1} commits by {2} authors
gb.recentActivityNone = last {0} days / none
gb.dailyActivity = daily activity
gb.activeRepositories = active repositories
gb.activeAuthors = active authors
gb.commits = commits
gb.teams = teams
gb.teamName = team name
gb.teamMembers = team members
gb.teamMemberships = team memberships
gb.newTeam = new team
gb.permittedTeams = permitted teams
gb.emptyRepository = empty repository
gb.repositoryUrl = repository url
gb.mailingLists = mailing lists
gb.preReceiveScripts = pre-receive scripts
gb.postReceiveScripts = post-receive scripts
gb.hookScripts = hook scripts
gb.customFields = custom fields
gb.customFieldsDescription = custom fields available to Groovy hooks
gb.accessPermissions = access permissions
gb.filters = filters
gb.generalDescription = common settings
gb.accessPermissionsDescription = restrict access by users and teams
gb.accessPermissionsForUserDescription = set team memberships or grant access to specific restricted repositories
gb.accessPermissionsForTeamDescription = set team members and grant access to specific restricted repositories
gb.federationRepositoryDescription = share this repository with other Gitblit servers
gb.hookScriptsDescription = run Groovy scripts on pushes to this Gitblit server
gb.reset = reset
gb.pages = pages
gb.workingCopy = working copy
gb.workingCopyWarning = this repository has a working copy and can not receive pushes
gb.query = query
gb.queryHelp = Standard query syntax is supported.<p/><p/>Please see <a target="_new" href="http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/queryparsersyntax.html">Lucene Query Parser Syntax</a> for details.
gb.queryResults = results {0} - {1} ({2} hits)
gb.noHits = no hits
gb.authored = authored
gb.committed = committed
gb.indexedBranches = indexed branches
gb.indexedBranchesDescription = select the branches to include in your Lucene index
gb.noIndexedRepositoriesWarning = none of your repositories are configured for Lucene indexing
gb.undefinedQueryWarning = query is undefined!
gb.noSelectedRepositoriesWarning = please select one or more repositories!
gb.luceneDisabled = Lucene indexing is disabled
gb.failedtoRead = Failed to read
gb.isNotValidFile = is not a valid file
gb.failedToReadMessage = Failed to read default message from {0}!
gb.passwordsDoNotMatch = Passwords do not match!
gb.passwordTooShort = Password is too short. Minimum length is {0} characters.
gb.passwordChanged = Password successfully changed.
gb.passwordChangeAborted = Password change aborted.
gb.pleaseSetRepositoryName = Please set repository name!
gb.illegalLeadingSlash = Leading root folder references (/) are prohibited.
gb.illegalRelativeSlash = Relative folder references (../) are prohibited.
gb.illegalCharacterRepositoryName = Illegal character ''{0}'' in repository name!
gb.selectAccessRestriction = Please select access restriction!
gb.selectFederationStrategy = Please select federation strategy!
gb.pleaseSetTeamName = Please enter a teamname!
gb.teamNameUnavailable = Team name ''{0}'' is unavailable.
gb.teamMustSpecifyRepository = A team must specify at least one repository.
gb.teamCreated = New team ''{0}'' successfully created.
gb.pleaseSetUsername = Please enter a username!
gb.usernameUnavailable = Username ''{0}'' is unavailable.
gb.combinedMd5Rename = Gitblit is configured for combined-md5 password hashing. You must enter a new password on account rename.
gb.userCreated = New user ''{0}'' successfully created.
gb.couldNotFindFederationRegistration = Could not find federation registration!
gb.failedToFindGravatarProfile = Failed to find Gravatar profile for {0}
gb.branchStats = {0} commits and {1} tags in {2}
gb.repositoryNotSpecified = Repository not specified!
gb.repositoryNotSpecifiedFor = Repository not specified for {0}!
gb.canNotLoadRepository = Can not load repository
gb.commitIsNull = Commit is null
gb.unauthorizedAccessForRepository = Unauthorized access for repository
gb.failedToFindCommit = Failed to find commit \"{0}\" in {1} for {2} page!
gb.couldNotFindFederationProposal = Could not find federation proposal!
gb.invalidUsernameOrPassword = Invalid username or password!
gb.OneProposalToReview = There is 1 federation proposal awaiting review.
gb.nFederationProposalsToReview = There are {0} federation proposals awaiting review.
gb.couldNotFindTag = Could not find tag {0}
gb.couldNotCreateFederationProposal = Could not create federation proposal!
gb.pleaseSetGitblitUrl = Please enter your Gitblit url!
gb.pleaseSetDestinationUrl = Please enter a destination url for your proposal!
gb.proposalReceived = Proposal successfully received by {0}.
gb.noGitblitFound = Sorry, {0} could not find a Gitblit instance at {1}.
gb.noProposals = Sorry, {0} is not accepting proposals at this time.
gb.noFederation = Sorry, {0} is not configured to federate with any Gitblit instances.
gb.proposalFailed = Sorry, {0} did not receive any proposal data!
gb.proposalError = Sorry, {0} reports that an unexpected error occurred!
gb.failedToSendProposal = Failed to send proposal!
gb.userServiceDoesNotPermitAddUser = {0} does not permit adding a user account!
gb.userServiceDoesNotPermitPasswordChanges = {0} does not permit password changes!
gb.displayName = display name
gb.emailAddress = email address
gb.errorAdminLoginRequired = Administration requires a login
gb.errorOnlyAdminMayCreateRepository = Only an administrator may create a repository
gb.errorOnlyAdminOrOwnerMayEditRepository = Only an administrator or the owner may edit a repository
gb.errorAdministrationDisabled = Administration is disabled
gb.lastNDays = last {0} days
gb.completeGravatarProfile = Complete profile on Gravatar.com
gb.none = none
gb.line = line
gb.content = content
gb.empty = empty
gb.inherited = inherited
gb.deleteRepository = Delete repository \"{0}\"?
gb.repositoryDeleted = Repository ''{0}'' deleted.
gb.repositoryDeleteFailed = Failed to delete repository ''{0}''!
gb.deleteUser = Delete user \"{0}\"?
gb.userDeleted = User ''{0}'' deleted.
gb.userDeleteFailed = Failed to delete user ''{0}''!
gb.time.justNow = just now
gb.time.today = today
gb.time.yesterday = yesterday
gb.time.minsAgo = {0} mins ago
gb.time.hoursAgo = {0} hours ago
gb.time.daysAgo = {0} days ago
gb.time.weeksAgo = {0} weeks ago
gb.time.monthsAgo = {0} months ago
gb.time.oneYearAgo = 1 year ago
gb.time.yearsAgo = {0} years ago
gb.duration.oneDay = 1 day
gb.duration.days = {0} days
gb.duration.oneMonth = 1 month
gb.duration.months = {0} months
gb.duration.oneYear = 1 year
gb.duration.years = {0} years
gb.authorizationControl = authorization control
gb.allowAuthenticatedDescription = grant RW+ permission to all authenticated users
gb.allowNamedDescription = grant fine-grained permissions to named users or teams
gb.markdownFailure = Failed to parse Markdown content!
gb.clearCache = clear cache
gb.projects = projects
gb.project = project
gb.allProjects = all projects
gb.copyToClipboard = copy to clipboard
gb.fork = fork
gb.forks = forks
gb.forkRepository = fork {0}?
gb.repositoryForked = {0} has been forked
gb.repositoryForkFailed= fork has failed
gb.personalRepositories = personal repositories
gb.allowForks = allow forks
gb.allowForksDescription = allow authorized users to fork this repository
gb.forkedFrom = forked from
gb.canFork = can fork
gb.canForkDescription = can fork authorized repositories to personal repositories
gb.myFork = view my fork
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 = preparing your fork...
gb.isFork = is fork
gb.canCreate = can create
gb.canCreateDescription = can create personal repositories
gb.illegalPersonalRepositoryLocation = your personal repository must be located at \"{0}\"
gb.verifyCommitter = verify committer
gb.verifyCommitterDescription = require committer identity to match pushing Gitblt user account
gb.verifyCommitterNote = all merges require "--no-ff" to enforce committer identity
gb.repositoryPermissions = repository permissions
gb.userPermissions = user permissions
gb.teamPermissions = team permissions
gb.add = add
gb.noPermission = DELETE THIS PERMISSION
gb.excludePermission = {0} (exclude)
gb.viewPermission = {0} (view)
gb.clonePermission = {0} (clone)
gb.pushPermission = {0} (push)
gb.createPermission = {0} (push, ref creation)
gb.deletePermission = {0} (push, ref creation+deletion)
gb.rewindPermission = {0} (push, ref creation+deletion+rewind)
gb.permission = permission
gb.regexPermission = this permission is set from regular expression \"{0}\"
gb.accessDenied = access denied
gb.busyCollectingGarbage = sorry, Gitblit is busy collecting garbage in {0}
gb.gcPeriod = GC period
gb.gcPeriodDescription = duration between garbage collections
gb.gcThreshold = GC threshold
gb.gcThresholdDescription = minimum total size of loose objects to trigger early garbage collection
gb.ownerPermission = repository owner
gb.administrator = admin
gb.administratorPermission = Gitblit administrator
gb.team = team
gb.teamPermission = permission set by \"{0}\" team membership
gb.missing = missing!
gb.missingPermission = the repository for this permission is missing!
gb.mutable = mutable
gb.specified = specified
gb.effective = effective
gb.organizationalUnit = organizational unit
gb.organization = organization
gb.locality = locality
gb.stateProvince = state or province
gb.countryCode = country code
gb.properties = properties
gb.issued = issued
gb.expires = expires
gb.expired = expired
gb.expiring = expiring
gb.revoked = revoked
gb.serialNumber = serial number
gb.certificates = certificates
gb.newCertificate = new certificate
gb.revokeCertificate = revoke certificate
gb.sendEmail = send email
gb.passwordHint = password hint
gb.ok = ok
gb.invalidExpirationDate = invalid expiration date!
gb.passwordHintRequired = password hint required!
gb.viewCertificate = view certificate
gb.subject = subject
gb.issuer = issuer
gb.validFrom = valid from
gb.validUntil = valid until
gb.publicKey = public key
gb.signatureAlgorithm = signature algorithm
gb.sha1FingerPrint = SHA-1 Fingerprint
gb.md5FingerPrint = MD5 Fingerprint
gb.reason = reason
gb.revokeCertificateReason = Please select a reason for certificate revocation
gb.unspecified = unspecified
gb.keyCompromise = key compromise
gb.caCompromise = CA compromise
gb.affiliationChanged = affiliation changed
gb.superseded = superseded
gb.cessationOfOperation = cessation of operation
gb.privilegeWithdrawn = privilege withdrawn
gb.time.inMinutes = in {0} mins
gb.time.inHours = in {0} hours
gb.time.inDays = in {0} days
gb.hostname = hostname
gb.hostnameRequired = Please enter a hostname
gb.newSSLCertificate = new server SSL certificate
gb.newCertificateDefaults = new certificate defaults
gb.duration = duration
gb.certificateRevoked = Certificate {0,number,0} has been revoked
gb.clientCertificateGenerated = Successfully generated new client certificate for {0}
gb.sslCertificateGenerated = Successfully generated new server SSL certificate for {0}
gb.newClientCertificateMessage = NOTE:\nThe 'password' is not the user's password, it is the password to protect the user's keystore.  This password is not saved so you must also enter a 'hint' which will be included in the user's README instructions.
gb.certificate = certificate
gb.emailCertificateBundle = email client certificate bundle
gb.pleaseGenerateClientCertificate = Please generate a client certificate for {0}
gb.clientCertificateBundleSent = Client certificate bundle for {0} sent
gb.enterKeystorePassword = Please enter the Gitblit keystore password
gb.warning = warning
gb.jceWarning = Your Java Runtime Environment does not have the \"JCE Unlimited Strength Jurisdiction Policy\" files.\nThis will limit the length of passwords you may use to encrypt your keystores to 7 characters.\nThese policy files are an optional download from Oracle.\n\nWould you like to continue and generate the certificate infrastructure anyway?\n\nAnswering No will direct your browser to Oracle's download page so that you may download the policy files.
gb.maxActivityCommits = max activity commits
gb.maxActivityCommitsDescription = maximum number of commits to contribute to the Activity page
gb.noMaximum = no maximum
gb.attributes = attributes
gb.serveCertificate = serve https with this certificate
gb.sslCertificateGeneratedRestart = Successfully generated new server SSL certificate for {0}.\nYou must restart Gitblit to use the new certificate.\n\nIf you are launching with the '--alias' parameter you will have to set that to ''--alias {0}''.
gb.validity = validity
gb.siteName = site name
gb.siteNameDescription = short, descriptive name of your server
gb.excludeFromActivity = exclude from activity page
gb.isSparkleshared = repository is Sparkleshared
gb.owners = owners
gb.sessionEnded = Session has been closed
gb.closeBrowser = Please close the browser to properly end the session.
gb.doesNotExistInTree = {0} does not exist in tree {1}
gb.enableIncrementalPushTags = enable incremental push tags
gb.useIncrementalPushTagsDescription = on push, automatically tag each branch tip with an incremental revision number
gb.incrementalPushTagMessage = Auto-tagged [{0}] branch on push
gb.externalPermissions = {0} access permissions are externally maintained
gb.viewAccess = You do not have Gitblit read or write access
gb.overview = overview
gb.home = home
gb.monthlyActivity = monthly activity
gb.myProfile = my profile
gb.compare = compare
gb.manual = manual
gb.from = from
gb.to = to
gb.at = at
gb.morePushes = all pushes...
gb.pushes = pushes
gb.pushedNCommitsTo = pushed {0} commits to
gb.pushedOneCommitTo = pushed 1 commit to
gb.viewComparison = view comparison of these {0} commits \u00bb
gb.nMoreCommits = {0} more commits \u00bb
gb.oneMoreCommit = 1 more commit \u00bb
gb.pushedNewTag = pushed new tag
gb.deletedTag = deleted tag
gb.pushedNewBranch = pushed new branch
gb.deletedBranch = deleted branch
gb.rewind = REWIND
gb.enableIncrementalPushTags = enable incremental push tags
gb.useIncrementalPushTagsDescription = on push, automatically tag each branch tip with an incremental revision number
gb.incrementalPushTagMessage = Auto-tagged [{0}] branch on push
gb.externalPermissions = {0} access permissions are externally maintained
gb.viewAccess = You do not have Gitblit read or write access
gb.overview = overview
gb.home = home
gb.monthlyActivity = monthly activity
gb.myProfile = my profile
gb.compare = compare
gb.manual = manual
gb.from = from
gb.to = to
gb.at = at
gb.morePushes = all pushes...
gb.pushes = pushes
gb.pushedNCommitsTo = pushed {0} commits to
gb.pushedOneCommitTo = pushed 1 commit to
gb.viewComparison = view comparison of these {0} commits \u00bb
gb.nMoreCommits = {0} more commits \u00bb
gb.oneMoreCommit = 1 more commit \u00bb
gb.pushedNewTag = pushed new tag
gb.deletedTag = deleted tag
gb.pushedNewBranch = pushed new branch
gb.deletedBranch = deleted branch
gb.rewind = REWIND
gb.star = star
gb.unstar = unstar
src/main/java/com/gitblit/wicket/pages/RepositoryPage.html
@@ -38,8 +38,9 @@
                    <div>
                        <div class="hidden-phone btn-group pull-right" style="margin-top:5px;">
                            <!-- future spot for other repo buttons -->
<!--                             <a class="btn"><i class="icon-star-empty" style="padding-right:3px;"></i>star</a> -->
<!--                             <a class="btn"><i class="icon-envelope" style="padding-right:3px;"></i>subscribe</a> -->
                            <a class="btn" wicket:id="starLink"></a>
                            <a class="btn" wicket:id="unstarLink"></a>
                            <a class="btn" wicket:id="myForkLink"><img style="border:0px;vertical-align:middle;" src="fork-black_16x16.png"></img> <wicket:message key="gb.myFork"></wicket:message></a>
                            <a class="btn" wicket:id="forkLink"><img style="border:0px;vertical-align:middle;" src="fork-black_16x16.png"></img> <wicket:message key="gb.fork"></wicket:message></a>
                        </div>
@@ -54,6 +55,10 @@
            <wicket:child />
        </div>
        
        <wicket:fragment wicket:id="toolbarLinkFragment">
            <i wicket:id="icon" style="padding-right:3px;"></i><span wicket:id="label"></span>
        </wicket:fragment>
        <wicket:fragment wicket:id="originFragment">
            <p class="originRepository"><wicket:message key="gb.forkedFrom">[forked from]</wicket:message> <span wicket:id="originRepository">[origin repository]</span></p>
        </wicket:fragment>
src/main/java/com/gitblit/wicket/pages/RepositoryPage.java
@@ -28,6 +28,7 @@
import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.TextField;
@@ -41,9 +42,12 @@
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.Constants;
import com.gitblit.GitBlit;
import com.gitblit.GitBlitException;
import com.gitblit.Keys;
import com.gitblit.PagesServlet;
import com.gitblit.SyndicationServlet;
@@ -52,7 +56,9 @@
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.SubmoduleModel;
import com.gitblit.models.UserModel;
import com.gitblit.models.UserRepositoryPreferences;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.DeepCopier;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.PushLogUtils;
import com.gitblit.utils.StringUtils;
@@ -67,7 +73,11 @@
import com.gitblit.wicket.panels.RefsPanel;
public abstract class RepositoryPage extends RootPage {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    private final String PARAM_STAR = "star";
    protected final String projectName;
    protected final String repositoryName;
    protected final String objectId;
@@ -104,7 +114,7 @@
        if (getRepositoryModel().isCollectingGarbage) {
            error(MessageFormat.format(getString("gb.busyCollectingGarbage"), getRepositoryModel().name), true);
        }
        if (objectId != null) {
            RefModel branch = null;
            if ((branch = JGitUtils.getBranch(getRepository(), objectId)) != null) {
@@ -117,6 +127,22 @@
                                branch.reference.getName());
                if (!canAccess) {
                    error(getString("gb.accessDenied"), true);
                }
            }
        }
        if (params.containsKey(PARAM_STAR)) {
            // set starred state
            boolean star = params.getBoolean(PARAM_STAR);
            UserModel user = GitBlitWebSession.get().getUser();
            if (user != null && user.isAuthenticated) {
                UserRepositoryPreferences prefs = user.getPreferences().getRepositoryPreferences(getRepositoryModel().name);
                prefs.starred = star;
                try {
                    GitBlit.self().updateUserModel(user.username, user, false);
                } catch (GitBlitException e) {
                    logger.error("Failed to update user " + user.username, e);
                    error(getString("gb.failedToUpdateUser"), false);
                }
            }
        }
@@ -260,6 +286,26 @@
            }
        }
        
        // (un)star link allows a user to star someone else's repository
        if (user.isAuthenticated && !model.isOwner(user.username) && !model.isUsersPersonalRepository(user.username)) {
            PageParameters starParams = DeepCopier.copy(getPageParameters());
            starParams.put(PARAM_STAR, !user.getPreferences().isStarredRepository(model.name));
            String toggleStarUrl = getRequestCycle().urlFor(getClass(), starParams).toString();
            if (user.getPreferences().isStarredRepository(model.name)) {
                // show unstar button
                add(new Label("starLink").setVisible(false));
                addToolbarButton("unstarLink", "icon-star-empty", getString("gb.unstar"), toggleStarUrl);
            } else {
                // show star button
                addToolbarButton("starLink", "icon-star", getString("gb.star"), toggleStarUrl);
                add(new Label("unstarLink").setVisible(false));
            }
        } else {
            // anonymous user or the repository owner is browsing the repository
            add(new Label("starLink").setVisible(false));
            add(new Label("unstarLink").setVisible(false));
        }
        // fork controls
        if (!allowForkControls() || user == null || !user.isAuthenticated) {
            // must be logged-in to fork, hide all fork controls
@@ -292,6 +338,16 @@
        
        super.setupPage(repositoryName, pageName);
    }
    protected void addToolbarButton(String wicketId, String iconClass, String label, String url) {
        Fragment button = new Fragment(wicketId, "toolbarLinkFragment", this);
        Label icon = new Label("icon");
        WicketUtils.setCssClass(icon, iconClass);
        button.add(icon);
        button.add(new Label("label", label));
        button.add(new SimpleAttributeModifier("href", url));
        add(button);
    }
    protected void addSyndicationDiscoveryLink() {
        add(WicketUtils.syndicationDiscoveryLink(SyndicationServlet.getTitle(repositoryName,