diff options
Diffstat (limited to 'src/main/distrib')
31 files changed, 3098 insertions, 0 deletions
diff --git a/src/main/distrib/data/certs/authority.conf b/src/main/distrib/data/certs/authority.conf new file mode 100644 index 00000000..575e9b1e --- /dev/null +++ b/src/main/distrib/data/certs/authority.conf @@ -0,0 +1,7 @@ +[new]
+ duration = 365 + organizationalUnit = Gitblit + organization = Gitblit + locality = Gitblit + stateProvince = NY
+ countryCode = US diff --git a/src/main/distrib/data/certs/instructions.tmpl b/src/main/distrib/data/certs/instructions.tmpl new file mode 100644 index 00000000..11ea78ff --- /dev/null +++ b/src/main/distrib/data/certs/instructions.tmpl @@ -0,0 +1,123 @@ +********************************************************************************
+ Gitblit SSL Client Certificate for $serverHostname
+********************************************************************************
+
+ Hello $userDisplayname,
+
+ Your private key, public certificate, and the Gitblit Certificate Authority
+ certificate for $serverHostname are stored in $username.p12, a PKCS#12 certificate
+ store[1], and also in $username.pem, a PEM certificate store.
+
+ Both of these certificate stores are password-protected.
+ Password Hint: $storePasswordHint
+
+
+Git (All) Installation Instructions
+=============================================
+
+ The provided PEM file can be directly used by your git client.
+
+ git config [--global] http.sslCert path/to/$username.pem
+
+ The supplied PEM file is password-protected and you may be prompted for your
+ password multiple times during an exchange with Gitblit. If you desire a
+ password-less git client workflow then you will need to decrypt and export your
+ private key with OpenSSL[2] and then update your git config to use that key.
+
+ openssl rsa -in path/to/$username.pem -out path/to/$username.key
+ git config [--global] http.sslKey path/to/$username.key
+
+ Obviously, you should protect access to any decrypted private key.
+
+ NOTE:
+ Some older git clients may have trouble using the PEM file without explicitly
+ extracting the private key. This has been observed, for example, on Ubuntu 12.04
+ with git 1.7.9.5.
+
+
+Firefox (All) Installation Instructions
+=============================================
+
+ Firefox maintains it's own certificate store which is separate from the operating
+ system.
+
+ 1. Navigate to Options->Advanced->Encryption
+ 2. Click "View Certificates"
+ 3. Switch to the "Your Certificates" tab
+ 4. Click "Import..."
+ 5. Navigate your filesystem and select $username.p12
+ 6. At the password prompt enter the certificate store password
+ You have now imported your private key, public certificate, and the CA certificate
+ but now we must manually set the trust settings of the CA certificate.
+ 7. Switch to the "Authorities" tab
+ 8. Scroll down and find "Gitblit-> Gitblit Certificate Authority"
+ 9. Select it and click "Edit Trust..."
+ 10. Check "This certificate can identify websites" and click OK.
+
+
+Chrome/IE (Windows) Installation Instructions
+=============================================
+
+ On Windows, Chrome and IE share their certificate store so configuring one will
+ automatically apply for both.
+
+ IE
+ ------------------------------------
+ 1. Navigate to Internet Options->Content
+ 2. Click the "Certificates" button
+
+ Chrome
+ ------------------------------------
+ 1. Navigate to Settings->Show Advanced Settings->HTTP/SSL
+ 2. Click the "Manage Certificates..." button
+
+ Both (Windows)
+ ------------------------------------
+ 3. Switch to the "Personal" tab
+ 4. Click the "Import..." button
+ 5. Follow the Import Wizard instructions.
+ You will need to change the selected file filter when navigating to $username.p12
+ 6. At the password prompt enter the certificate store password
+ 7. Because both your personal certificate and the CA certifcate are stored in
+ $username.p12, you must choose "Automatically select the certificate store based on the type of certificate".
+ If you choose the default you will not install the CA certificate.
+
+
+Chrome (Linux) Installation Instructions
+=============================================
+
+ On Linux, Chrome maintains it's own certificate store.
+
+ 1. Navigate to Settings->Show Advanced Settings->HTTP/SSL
+ 2. Click the "Manage Certificates..." button
+ 3. Navigate your filesystem and select $username.p12
+ 4. At the password prompt enter the certificate store password
+ You have now imported your private key, public certificate, and the CA certificate
+ but now we must manually set the trust settings of the CA certificate.
+ 5. Switch to the "Authorities" tab
+ 6. Scroll down and find "Gitblit-> Gitblit Certificate Authority"
+ 7. Select it and click "Edit Trust..."
+ 8. Check "This certificate can identify websites" and click OK.
+
+
+Chrome/Safari (Mac OS X) Installation Instructions
+=============================================
+
+On Mac OS X, Chrome and Safari both use Keychain Access to store certificates
+so configuring one will automatically apply for both.
+
+ 1. Double-click $username.pem
+ 2. At the password prompt enter the certificate store password
+ You have now imported your private key, public certificate, and the CA certificate
+ but now we must manually set the trust settings of the CA certificate.
+ 3. Find the Gitblit Certificate Authority certificate, it should have a red
+ indicator meaning untrusted, and double-click it.
+ 4. Open the "Trust" disclosure triangle and change "When using this certificate"
+ to "Always Trust".
+ 5. Close the certificate view and enter your system password to save the changes
+ to your keychain.
+
+
+[1] PKCS#12 is one of the standard container formats for sharing private keys and
+ public certificates.
+[2] http://www.openssl.org
diff --git a/src/main/distrib/data/certs/mail.tmpl b/src/main/distrib/data/certs/mail.tmpl new file mode 100644 index 00000000..463e124d --- /dev/null +++ b/src/main/distrib/data/certs/mail.tmpl @@ -0,0 +1,7 @@ + Hello $userDisplayname,
+
+ Your private key, public certificate, and the Gitblit Certificate Authority
+ certificate for $serverHostname are bundled together in the attached zip file.
+
+ There are also setup/installation instructions included in the zip for Git and
+ several major browsers to get you started.
\ No newline at end of file diff --git a/src/main/distrib/data/gitblit.properties b/src/main/distrib/data/gitblit.properties new file mode 100644 index 00000000..a05f5d2d --- /dev/null +++ b/src/main/distrib/data/gitblit.properties @@ -0,0 +1,1311 @@ +#
+# Gitblit Settings
+#
+
+# This settings file supports parameterization from the command-line for the
+# following command-line parameters:
+#
+# --baseFolder ${baseFolder} SINCE 1.2.1
+#
+# Settings that support ${baseFolder} parameter substitution are indicated with the
+# BASEFOLDER attribute. If the --baseFolder argument is unspecified, ${baseFolder}
+# and it's trailing / will be discarded from the setting value leaving a relative
+# path that is equivalent to pre-1.2.1 releases.
+#
+# e.g. "${baseFolder}/git" becomes "git", if --baseFolder is unspecified
+#
+# Git Servlet Settings
+#
+
+# Base folder for repositories.
+# This folder may contain bare and non-bare repositories but Gitblit will only
+# allow you to push to bare repositories.
+# Use forward slashes even on Windows!!
+# e.g. c:/gitrepos
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+# BASEFOLDER
+git.repositoriesFolder = ${baseFolder}/git
+
+# Build the available repository list at startup and cache this list for reuse.
+# This reduces disk io when presenting the repositories page, responding to rpcs,
+# etc, but it means that Gitblit will not automatically identify repositories
+# added or deleted by external tools.
+#
+# For this case you can use curl, wget, etc to issue an rpc request to clear the
+# cache (e.g. https://localhost/rpc?req=CLEAR_REPOSITORY_CACHE)
+#
+# SINCE 1.1.0
+git.cacheRepositoryList = true
+
+# Search the repositories folder subfolders for other repositories.
+# Repositories MAY NOT be nested (i.e. one repository within another)
+# but they may be grouped together in subfolders.
+# e.g. c:/gitrepos/libraries/mylibrary.git
+# c:/gitrepos/libraries/myotherlibrary.git
+#
+# SINCE 0.5.0
+git.searchRepositoriesSubfolders = true
+
+# Maximum number of folders to recurse into when searching for repositories.
+# The default value, -1, disables depth limits.
+#
+# SINCE 1.1.0
+git.searchRecursionDepth = -1
+
+# List of regex exclusion patterns to match against folders found in
+# *git.repositoriesFolder*.
+# Use forward slashes even on Windows!!
+# e.g. test/jgit\.git
+#
+# SPACE-DELIMITED
+# CASE-SENSITIVE
+# SINCE 1.1.0
+git.searchExclusions =
+
+# List of regex url patterns for extracting a repository name when locating
+# submodules.
+# e.g. git.submoduleUrlPatterns = .*?://github.com/(.*) will extract
+# *gitblit/gitblit.git* from *git://github.com/gitblit/gitblit.git*
+# If no matches are found then the submodule repository name is assumed to be
+# whatever trails the last / character. (e.g. gitblit.git).
+#
+# SPACE-DELIMITED
+# CASE-SENSITIVE
+# SINCE 1.1.0
+git.submoduleUrlPatterns = .*?://github.com/(.*)
+
+# Allow push/pull over http/https with JGit servlet.
+# If you do NOT want to allow Git clients to clone/push to Gitblit set this
+# to false. You might want to do this if you are only using ssh:// or git://.
+# If you set this false, consider changing the *web.otherUrls* setting to
+# indicate your clone/push urls.
+#
+# SINCE 0.5.0
+git.enableGitServlet = true
+
+# If you want to restrict all git servlet access to those with valid X509 client
+# certificates then set this value to true.
+#
+# SINCE 1.2.0
+git.requiresClientCertificate = false
+
+# Enforce date checks on client certificates to ensure that they are not being
+# used prematurely and that they have not expired.
+#
+# SINCE 1.2.0
+git.enforceCertificateValidity = true
+
+# List of OIDs to extract from a client certificate DN to map a certificate to
+# an account username.
+#
+# e.g. git.certificateUsernameOIDs = CN
+# e.g. git.certificateUsernameOIDs = FirstName LastName
+#
+# SPACE-DELIMITED
+# SINCE 1.2.0
+git.certificateUsernameOIDs = CN
+
+# Only serve/display bare repositories.
+# If there are non-bare repositories in git.repositoriesFolder and this setting
+# is true, they will be excluded from the ui.
+#
+# SINCE 0.9.0
+git.onlyAccessBareRepositories = false
+
+# Allow an authenticated user to create a destination repository on a push if
+# the repository does not already exist.
+#
+# Administrator accounts can create a repository in any project.
+# These repositories are created with the default access restriction and authorization
+# control values. The pushing account is set as the owner.
+#
+# Non-administrator accounts with the CREATE role may create personal repositories.
+# These repositories are created as VIEW restricted for NAMED users.
+# The pushing account is set as the owner.
+#
+# SINCE 1.2.0
+git.allowCreateOnPush = true
+
+# The default access restriction for new repositories.
+# Valid values are NONE, PUSH, CLONE, VIEW
+# NONE = anonymous view, clone, & push
+# PUSH = anonymous view & clone and authenticated push
+# CLONE = anonymous view, authenticated clone & push
+# VIEW = authenticated view, clone, & push
+#
+# SINCE 1.0.0
+git.defaultAccessRestriction = NONE
+
+# The default authorization control for new repositories.
+# Valid values are AUTHENTICATED and NAMED
+# AUTHENTICATED = any authenticated user is granted restricted access
+# NAMED = only named users/teams are granted restricted access
+#
+# SINCE 1.1.0
+git.defaultAuthorizationControl = NAMED
+
+# Enable JGit-based garbage collection. (!!EXPERIMENTAL!!)
+#
+# USE AT YOUR OWN RISK!
+#
+# If enabled, the garbage collection executor scans all repositories once a day
+# at the hour of your choosing. The GC executor will take each repository "offline",
+# one-at-a-time, to check if the repository satisfies it's GC trigger requirements.
+#
+# While the repository is offline it will be inaccessible from the web UI or from
+# any of the other services (git, rpc, rss, etc).
+#
+# Gitblit's GC Executor MAY NOT PLAY NICE with the other Git kids on the block,
+# especially on Windows systems, so if you are using other tools please coordinate
+# their usage with your GC Executor schedule or do not use this feature.
+#
+# The GC algorithm complex and the JGit team advises caution when using their
+# young implementation of GC.
+#
+# http://wiki.eclipse.org/EGit/New_and_Noteworthy/2.1#Garbage_Collector_and_Repository_Storage_Statistics
+#
+# EXPERIMENTAL
+# SINCE 1.2.0
+# RESTART REQUIRED
+git.enableGarbageCollection = false
+
+# Hour of the day for the GC Executor to scan repositories.
+# This value is in 24-hour time.
+#
+# SINCE 1.2.0
+git.garbageCollectionHour = 0
+
+# The default minimum total filesize of loose objects to trigger early garbage
+# collection.
+#
+# You may specify a custom threshold for a repository in the repository's settings.
+# Common unit suffixes of k, m, or g are supported.
+#
+# SINCE 1.2.0
+git.defaultGarbageCollectionThreshold = 500k
+
+# The default period, in days, between GCs for a repository. If the total filesize
+# of the loose object exceeds *git.garbageCollectionThreshold* or the repository's
+# custom threshold, this period will be short-circuited.
+#
+# e.g. if a repository collects 100KB of loose objects every day with a 500KB
+# threshold and a period of 7 days, it will take 5 days for the loose objects to
+# be collected, packed, and pruned.
+#
+# OR
+#
+# if a repository collects 10KB of loose objects every day with a 500KB threshold
+# and a period of 7 days, it will take the full 7 days for the loose objects to be
+# collected, packed, and pruned.
+#
+# You may specify a custom period for a repository in the repository's settings.
+#
+# The minimum value is 1 day since the GC Executor only runs once a day.
+#
+# SINCE 1.2.0
+git.defaultGarbageCollectionPeriod = 7
+
+# Number of bytes of a pack file to load into memory in a single read operation.
+# This is the "page size" of the JGit buffer cache, used for all pack access
+# operations. All disk IO occurs as single window reads. Setting this too large
+# may cause the process to load more data than is required; setting this too small
+# may increase the frequency of read() system calls.
+#
+# Default on JGit is 8 KiB on all platforms.
+#
+# Common unit suffixes of k, m, or g are supported.
+# Documentation courtesy of the Gerrit project.
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+git.packedGitWindowSize = 8k
+
+# Maximum number of bytes to load and cache in memory from pack files. If JGit
+# needs to access more than this many bytes it will unload less frequently used
+# windows to reclaim memory space within the process. As this buffer must be shared
+# with the rest of the JVM heap, it should be a fraction of the total memory available.
+#
+# The JGit team recommends setting this value larger than the size of your biggest
+# repository. This ensures you can serve most requests from memory.
+#
+# Default on JGit is 10 MiB on all platforms.
+#
+# Common unit suffixes of k, m, or g are supported.
+# Documentation courtesy of the Gerrit project.
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+git.packedGitLimit = 10m
+
+# Maximum number of bytes to reserve for caching base objects that multiple deltafied
+# objects reference. By storing the entire decompressed base object in a cache Git
+# is able to avoid unpacking and decompressing frequently used base objects multiple times.
+#
+# Default on JGit is 10 MiB on all platforms. You probably do not need to adjust
+# this value.
+#
+# Common unit suffixes of k, m, or g are supported.
+# Documentation courtesy of the Gerrit project.
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+git.deltaBaseCacheLimit = 10m
+
+# Maximum number of pack files to have open at once. A pack file must be opened
+# in order for any of its data to be available in a cached window.
+#
+# If you increase this to a larger setting you may need to also adjust the ulimit
+# on file descriptors for the host JVM, as Gitblit needs additional file descriptors
+# available for network sockets and other repository data manipulation.
+#
+# Default on JGit is 128 file descriptors on all platforms.
+# Documentation courtesy of the Gerrit project.
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+git.packedGitOpenFiles = 128
+
+# Largest object size, in bytes, that JGit will allocate as a contiguous byte
+# array. Any file revision larger than this threshold will have to be streamed,
+# typically requiring the use of temporary files under $GIT_DIR/objects to implement
+# psuedo-random access during delta decompression.
+#
+# Servers with very high traffic should set this to be larger than the size of
+# their common big files. For example a server managing the Android platform
+# typically has to deal with ~10-12 MiB XML files, so 15 m would be a reasonable
+# setting in that environment. Setting this too high may cause the JVM to run out
+# of heap space when handling very big binary files, such as device firmware or
+# CD-ROM ISO images. Make sure to adjust your JVM heap accordingly.
+#
+# Default is 50 MiB on all platforms.
+#
+# Common unit suffixes of k, m, or g are supported.
+# Documentation courtesy of the Gerrit project.
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+git.streamFileThreshold = 50m
+
+# When true, JGit will use mmap() rather than malloc()+read() to load data from
+# pack files. The use of mmap can be problematic on some JVMs as the garbage
+# collector must deduce that a memory mapped segment is no longer in use before
+# a call to munmap() can be made by the JVM native code.
+#
+# In server applications (such as Gitblit) that need to access many pack files,
+# setting this to true risks artificially running out of virtual address space,
+# as the garbage collector cannot reclaim unused mapped spaces fast enough.
+#
+# Default on JGit is false. Although potentially slower, it yields much more
+# predictable behavior.
+# Documentation courtesy of the Gerrit project.
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+git.packedGitMmap = false
+
+#
+# Groovy Integration
+#
+
+# Location of Groovy scripts to use for Pre and Post receive hooks.
+# Use forward slashes even on Windows!!
+# e.g. c:/groovy
+#
+# RESTART REQUIRED
+# SINCE 0.8.0
+# BASEFOLDER
+groovy.scriptsFolder = ${baseFolder}/groovy
+
+# Specify the directory Grape uses for downloading libraries.
+# http://groovy.codehaus.org/Grape
+#
+# RESTART REQUIRED
+# SINCE 1.0.0
+# BASEFOLDER
+groovy.grapeFolder = ${baseFolder}/groovy/grape
+
+# Scripts to execute on Pre-Receive.
+#
+# These scripts execute after an incoming push has been parsed and validated
+# but BEFORE the changes are applied to the repository. You might reject a
+# push in this script based on the repository and branch the push is attempting
+# to change.
+#
+# Script names are case-sensitive on case-sensitive file systems. You may omit
+# the traditional ".groovy" from this list if your file extension is ".groovy"
+#
+# NOTE:
+# These scripts are only executed when pushing to *Gitblit*, not to other Git
+# tooling you may be using. Also note that these scripts are shared between
+# repositories. These are NOT repository-specific scripts! Within the script
+# you may customize the control-flow for a specific repository by checking the
+# *repository* variable.
+#
+# SPACE-DELIMITED
+# CASE-SENSITIVE
+# SINCE 0.8.0
+groovy.preReceiveScripts =
+
+# Scripts to execute on Post-Receive.
+#
+# These scripts execute AFTER an incoming push has been applied to a repository.
+# You might trigger a continuous-integration build here or send a notification.
+#
+# Script names are case-sensitive on case-sensitive file systems. You may omit
+# the traditional ".groovy" from this list if your file extension is ".groovy"
+#
+# NOTE:
+# These scripts are only executed when pushing to *Gitblit*, not to other Git
+# tooling you may be using. Also note that these scripts are shared between
+# repositories. These are NOT repository-specific scripts! Within the script
+# you may customize the control-flow for a specific repository by checking the
+# *repository* variable.
+#
+# SPACE-DELIMITED
+# CASE-SENSITIVE
+# SINCE 0.8.0
+groovy.postReceiveScripts =
+
+# Repository custom fields for Groovy Hook mechanism
+#
+# List of key=label pairs of custom fields to prompt for in the Edit Repository
+# page. These keys are stored in the repository's git config file in the
+# section [gitblit "customFields"]. Key names are alphanumeric only. These
+# fields are intended to be used for the Groovy hook mechanism where a script
+# can adjust it's execution based on the custom fields stored in the repository
+# config.
+#
+# e.g. "commitMsgRegex=Commit Message Regular Expression" anotherProperty=Another
+#
+# SPACE-DELIMITED
+# SINCE 1.0.0
+groovy.customFields =
+
+#
+# Fanout Settings
+#
+
+# Fanout is a PubSub notification service that can be used by Sparkleshare
+# to eliminate repository change polling. The fanout service runs in a separate
+# thread on a separate port from the Gitblit http/https application.
+# This service is provided so that Sparkleshare may be used with Gitblit in
+# firewalled environments or where reliance on Sparkleshare's default notifications
+# server (notifications.sparkleshare.org) is unwanted.
+#
+# This service maintains an open socket connection from the client to the
+# Fanout PubSub service. This service may not work properly behind a proxy server.
+
+# Specify the interface for Fanout to bind it's service.
+# You may specify an ip or an empty value to bind to all interfaces.
+# Specifying localhost will result in Gitblit ONLY listening to requests to
+# localhost.
+#
+# SINCE 1.2.1
+# RESTART REQUIRED
+fanout.bindInterface = localhost
+
+# port for serving the Fanout PubSub service. <= 0 disables this service.
+# On Unix/Linux systems, ports < 1024 require root permissions.
+# Recommended value: 17000
+#
+# SINCE 1.2.1
+# RESTART REQUIRED
+fanout.port = 0
+
+# Use Fanout NIO service. If false, a multi-threaded socket service will be used.
+# Be advised, the socket implementation spawns a thread per connection plus the
+# connection acceptor thread. The NIO implementation is completely single-threaded.
+#
+# SINCE 1.2.1
+# RESTART REQUIRED
+fanout.useNio = true
+
+# Concurrent connection limit. <= 0 disables concurrent connection throttling.
+# If > 0, only the specified number of concurrent connections will be allowed
+# and all other connections will be rejected.
+#
+# SINCE 1.2.1
+# RESTART REQUIRED
+fanout.connectionLimit = 0
+
+#
+# Authentication Settings
+#
+
+# Require authentication to see everything but the admin pages
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+web.authenticateViewPages = false
+
+# If web.authenticateViewPages=true you may optionally require a client-side
+# basic authentication prompt instead of the standard form-based login.
+#
+# SINCE 1.3.0
+web.enforceHttpBasicAuthentication = false
+
+# Require admin authentication for the admin functions and pages
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+web.authenticateAdminPages = true
+
+# Allow Gitblit to store a cookie in the user's browser for automatic
+# authentication. The cookie is generated by the user service.
+#
+# SINCE 0.5.0
+web.allowCookieAuthentication = true
+
+# Config file for storing project metadata
+#
+# SINCE 1.2.0
+# BASEFOLDER
+web.projectsFile = ${baseFolder}/projects.conf
+
+# Either the full path to a user config file (users.conf)
+# OR the full path to a simple user properties file (users.properties)
+# OR a fully qualified class name that implements the IUserService interface.
+#
+# Alternative user services:
+# com.gitblit.LdapUserService
+# com.gitblit.RedmineUserService
+#
+# Any custom user service implementation must have a public default constructor.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+# BASEFOLDER
+realm.userService = ${baseFolder}/users.conf
+
+# How to store passwords.
+# Valid values are plain, md5, or combined-md5. md5 is the hash of password.
+# combined-md5 is the hash of username.toLowerCase()+password.
+# Default is md5.
+#
+# SINCE 0.5.0
+realm.passwordStorage = md5
+
+# Minimum valid length for a plain text password.
+# Default value is 5. Absolute minimum is 4.
+#
+# SINCE 0.5.0
+realm.minPasswordLength = 5
+
+#
+# Gitblit Web Settings
+#
+# If blank Gitblit is displayed.
+#
+# SINCE 0.5.0
+web.siteName =
+
+# If *web.authenticateAdminPages*=true, users with "admin" role can create
+# repositories, create users, and edit repository metadata.
+#
+# If *web.authenticateAdminPages*=false, any user can execute the aforementioned
+# functions.
+#
+# SINCE 0.5.0
+web.allowAdministration = true
+
+# Allows rpc clients to list repositories and possibly manage or administer the
+# Gitblit server, if the authenticated account has administrator permissions.
+# See *web.enableRpcManagement* and *web.enableRpcAdministration*.
+#
+# SINCE 0.7.0
+web.enableRpcServlet = true
+
+# Allows rpc clients to manage repositories and users of the Gitblit instance,
+# if the authenticated account has administrator permissions.
+# Requires *web.enableRpcServlet=true*.
+#
+# SINCE 0.7.0
+web.enableRpcManagement = false
+
+# Allows rpc clients to control the server settings and monitor the health of this
+# this Gitblit instance, if the authenticated account has administrator permissions.
+# Requires *web.enableRpcServlet=true* and *web.enableRpcManagement*.
+#
+# SINCE 0.7.0
+web.enableRpcAdministration = false
+
+# Full path to a configurable robots.txt file. With this file you can control
+# what parts of your Gitblit server respectable robots are allowed to traverse.
+# http://googlewebmastercentral.blogspot.com/2008/06/improving-on-robots-exclusion-protocol.html
+#
+# SINCE 1.0.0
+# BASEFOLDER
+web.robots.txt = ${baseFolder}/robots.txt
+
+# If true, the web ui layout will respond and adapt to the browser's dimensions.
+# if false, the web ui will use a 940px fixed-width layout.
+# http://twitter.github.com/bootstrap/scaffolding.html#responsive
+#
+# SINCE 1.0.0
+web.useResponsiveLayout = true
+
+# Allow Gravatar images to be displayed in Gitblit pages.
+#
+# SINCE 0.8.0
+web.allowGravatar = true
+
+# Allow dynamic zip downloads.
+#
+# SINCE 0.5.0
+web.allowZipDownloads = true
+
+# If *web.allowZipDownloads=true* the following formats will be displayed for
+# download compressed archive links:
+#
+# zip = standard .zip
+# tar = standard tar format (preserves *nix permissions and symlinks)
+# gz = gz-compressed tar
+# xz = xz-compressed tar
+# bzip2 = bzip2-compressed tar
+#
+# SPACE-DELIMITED
+# SINCE 1.2.0
+web.compressedDownloads = zip gz
+
+# Allow optional Lucene integration. Lucene indexing is an opt-in feature.
+# A repository may specify branches to index with Lucene instead of using Git
+# commit traversal. There are scenarios where you may want to completely disable
+# Lucene indexing despite a repository specifying indexed branches. One such
+# scenario is on a resource-constrained federated Gitblit mirror.
+#
+# SINCE 0.9.0
+web.allowLuceneIndexing = true
+
+# Allows an authenticated user to create forks of a repository
+#
+# set this to false if you want to disable all fork controls on the web site
+#
+web.allowForking = true
+
+# Controls the length of shortened commit hash ids
+#
+# SINCE 1.2.0
+web.shortCommitIdLength = 6
+
+# Use Clippy (Flash solution) to provide a copy-to-clipboard button.
+# If false, a button with a more primitive JavaScript-based prompt box will
+# offer a 3-step (click, ctrl+c, enter) copy-to-clipboard alternative.
+#
+# SINCE 0.8.0
+web.allowFlashCopyToClipboard = true
+
+# Default maximum number of commits that a repository may contribute to the
+# activity page, regardless of the selected duration. This setting may be valuable
+# for an extremely busy server. This value may also be configed per-repository
+# in Edit Repository. 0 disables this throttle.
+#
+# SINCE 1.2.0
+web.maxActivityCommits = 0
+
+# Default number of entries to include in RSS Syndication links
+#
+# SINCE 0.5.0
+web.syndicationEntries = 25
+
+# Show the size of each repository on the repositories page.
+# This requires recursive traversal of each repository folder. This may be
+# non-performant on some operating systems and/or filesystems.
+#
+# SINCE 0.5.2
+web.showRepositorySizes = true
+
+# List of custom regex expressions that can be displayed in the Filters menu
+# of the Repositories and Activity pages. Keep them very simple because you
+# are likely to run into encoding issues if they are too complex.
+#
+# Use !!! to separate the filters
+#
+# SINCE 0.8.0
+web.customFilters =
+
+# Show federation registrations (without token) and the current pull status
+# to non-administrator users.
+#
+# SINCE 0.6.0
+web.showFederationRegistrations = false
+
+# This is the message displayed when *web.authenticateViewPages=true*.
+# This can point to a file with Markdown content.
+# Specifying "gitblit" uses the internal login message.
+#
+# SINCE 0.7.0
+# BASEFOLDER
+web.loginMessage = gitblit
+
+# This is the message displayed above the repositories table.
+# This can point to a file with Markdown content.
+# Specifying "gitblit" uses the internal welcome message.
+#
+# SINCE 0.5.0
+# BASEFOLDER
+web.repositoriesMessage = gitblit
+
+# Ordered list of charsets/encodings to use when trying to display a blob.
+# If empty, UTF-8 and ISO-8859-1 are used. The server's default charset
+# is always appended to the encoding list. If all encodings fail to cleanly
+# decode the blob content, UTF-8 will be used with the standard malformed
+# input/unmappable character replacement strings.
+#
+# SPACE-DELIMITED
+# SINCE 1.0.0
+web.blobEncodings = UTF-8 ISO-8859-1
+
+# Manually set the default timezone to be used by Gitblit for display in the
+# web ui. This value is independent of the JVM timezone. Specifying a blank
+# value will default to the JVM timezone.
+# e.g. America/New_York, US/Pacific, UTC, Europe/Berlin
+#
+# SINCE 0.9.0
+# RESTART REQUIRED
+web.timezone =
+
+# Use the client timezone when formatting dates.
+# This uses AJAX to determine the browser's timezone and may require more
+# server overhead because a Wicket session is created. All Gitblit pages
+# attempt to be stateless, if possible.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+web.useClientTimezone = false
+
+# Time format
+# <http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html>
+#
+# SINCE 0.8.0
+web.timeFormat = HH:mm
+
+# Short date format
+# <http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html>
+#
+# SINCE 0.5.0
+web.datestampShortFormat = yyyy-MM-dd
+
+# Long date format
+#
+# SINCE 0.8.0
+web.datestampLongFormat = EEEE, MMMM d, yyyy
+
+# Long timestamp format
+# <http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html>
+#
+# SINCE 0.5.0
+web.datetimestampLongFormat = EEEE, MMMM d, yyyy HH:mm Z
+
+# Mount URL parameters
+# This setting controls if pretty or parameter URLs are used.
+# i.e.
+# if true:
+# http://localhost/commit/myrepo/abcdef
+# if false:
+# http://localhost/commit/?r=myrepo&h=abcdef
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+web.mountParameters = true
+
+# Some servlet containers (e.g. Tomcat >= 6.0.10) disallow '/' (%2F) encoding
+# in URLs as a security precaution for proxies. This setting tells Gitblit
+# to preemptively replace '/' with '*' or '!' for url string parameters.
+#
+# <https://issues.apache.org/jira/browse/WICKET-1303>
+# <http://tomcat.apache.org/security-6.html#Fixed_in_Apache_Tomcat_6.0.10>
+# Add *-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true* to your
+# *CATALINA_OPTS* or to your JVM launch parameters
+#
+# SINCE 0.5.2
+web.forwardSlashCharacter = /
+
+# Show other URLs on the summary page for accessing your git repositories
+# Use spaces to separate urls. {0} is the token for the repository name.
+# e.g.
+# web.otherUrls = ssh://localhost/git/{0} git://localhost/git/{0}
+#
+# SPACE-DELIMITED
+# SINCE 0.5.0
+web.otherUrls =
+
+# Choose how to present the repositories list.
+# grouped = group nested/subfolder repositories together (no sorting)
+# flat = flat list of repositories (sorting allowed)
+#
+# SINCE 0.5.0
+web.repositoryListType = grouped
+
+# If using a grouped repository list and there are repositories at the
+# root level of your repositories folder, you may specify the displayed
+# group name with this setting. This value is only used for web presentation.
+#
+# SINCE 0.5.0
+web.repositoryRootGroupName = main
+
+# Display the repository swatch color next to the repository name link in the
+# repositories list.
+#
+# SINCE 0.8.0
+web.repositoryListSwatches = true
+
+# Choose the diff presentation style: gitblt, gitweb, or plain
+#
+# SINCE 0.5.0
+web.diffStyle = gitblit
+
+# Control if email addresses are shown in web ui
+#
+# SINCE 0.5.0
+web.showEmailAddresses = true
+
+# Shows a combobox in the page links header with commit, committer, and author
+# search selection. Default search is commit.
+#
+# SINCE 0.5.0
+web.showSearchTypeSelection = false
+
+# Generates a line graph of repository activity over time on the Summary page.
+# This uses the Google Charts API.
+#
+# SINCE 0.5.0
+web.generateActivityGraph = true
+
+# The number of days to show on the activity page.
+# Value must exceed 0 else default of 14 is used
+#
+# SINCE 0.8.0
+web.activityDuration = 14
+
+# The number of commits to display on the summary page
+# Value must exceed 0 else default of 20 is used
+#
+# SINCE 0.5.0
+web.summaryCommitCount = 16
+
+# The number of tags/branches to display on the summary page.
+# -1 = all tags/branches
+# 0 = hide tags/branches
+# N = N tags/branches
+#
+# SINCE 0.5.0
+web.summaryRefsCount = 5
+
+# The number of items to show on a page before showing the first, prev, next
+# pagination links. A default if 50 is used for any invalid value.
+#
+# SINCE 0.5.0
+web.itemsPerPage = 50
+
+# Registered file extensions to ignore during Lucene indexing
+#
+# SPACE-DELIMITED
+# SINCE 0.9.0
+web.luceneIgnoreExtensions = 7z arc arj bin bmp dll doc docx exe gif gz jar jpg lib lzh odg odf odt pdf ppt png so swf xcf xls xlsx zip
+
+# Registered extensions for google-code-prettify
+#
+# SPACE-DELIMITED
+# SINCE 0.5.0
+web.prettyPrintExtensions = c cpp cs css frm groovy htm html java js php pl prefs properties py rb scala sh sql xml vb
+
+# Registered extensions for markdown transformation
+#
+# SPACE-DELIMITED
+# CASE-SENSITIVE
+# SINCE 0.5.0
+web.markdownExtensions = md mkd markdown MD MKD
+
+# Image extensions
+#
+# SPACE-DELIMITED
+# SINCE 0.5.0
+web.imageExtensions = bmp jpg gif png
+
+# Registered extensions for binary blobs
+#
+# SPACE-DELIMITED
+# SINCE 0.5.0
+web.binaryExtensions = jar pdf tar.gz zip
+
+# Aggressive heap management will run the garbage collector on every generated
+# page. This slows down page generation a little but improves heap consumption.
+#
+# SINCE 0.5.0
+web.aggressiveHeapManagement = false
+
+# Run the webapp in debug mode
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+web.debugMode = false
+
+# Enable/disable global regex substitutions (i.e. shared across repositories)
+#
+# SINCE 0.5.0
+regex.global = true
+
+# Example global regex substitutions
+# Use !!! to separate the search pattern and the replace pattern
+# searchpattern!!!replacepattern
+# SINCE 0.5.0
+regex.global.bug = \\b(Bug:)(\\s*[#]?|-){0,1}(\\d+)\\b!!!<a href="http://somehost/bug/$3">Bug-Id: $3</a>
+# SINCE 0.5.0
+regex.global.changeid = \\b(Change-Id:\\s*)([A-Za-z0-9]*)\\b!!!<a href="http://somehost/changeid/$2">Change-Id: $2</a>
+
+# Example per-repository regex substitutions overrides global
+# SINCE 0.5.0
+regex.myrepository.bug = \\b(Bug:)(\\s*[#]?|-){0,1}(\\d+)\\b!!!<a href="http://elsewhere/bug/$3">Bug-Id: $3</a>
+
+#
+# Mail Settings
+# SINCE 0.6.0
+#
+# Mail settings are used to notify administrators of received federation proposals
+#
+
+# ip or hostname of smtp server
+#
+# SINCE 0.6.0
+mail.server =
+
+# port to use for smtp requests
+#
+# SINCE 0.6.0
+mail.port = 25
+
+# debug the mail executor
+#
+# SINCE 0.6.0
+mail.debug = false
+
+# if your smtp server requires authentication, supply the credentials here
+#
+# SINCE 0.6.0
+mail.username =
+# SINCE 0.6.0
+mail.password =
+
+# from address for generated emails
+#
+# SINCE 0.6.0
+mail.fromAddress =
+
+# List of email addresses for the Gitblit administrators
+#
+# SPACE-DELIMITED
+# SINCE 0.6.0
+mail.adminAddresses =
+
+# List of email addresses for sending push email notifications.
+#
+# This key currently requires use of the sendemail.groovy hook script.
+# If you set sendemail.groovy in *groovy.postReceiveScripts* then email
+# notifications for all repositories (regardless of access restrictions!)
+# will be sent to these addresses.
+#
+# SPACE-DELIMITED
+# SINCE 0.8.0
+mail.mailingLists =
+
+#
+# Federation Settings
+# SINCE 0.6.0
+#
+# A Gitblit federation is a way to backup one Gitblit instance to another.
+#
+# *git.enableGitServlet* must be true to use this feature.
+
+# Your federation name is used for federation status acknowledgments. If it is
+# unset, and you elect to send a status acknowledgment, your Gitblit instance
+# will be identified by its hostname, if available, else your internal ip address.
+# The source Gitblit instance will also append your external IP address to your
+# identification to differentiate multiple pulling systems behind a single proxy.
+#
+# SINCE 0.6.0
+federation.name =
+
+# Specify the passphrase of this Gitblit instance.
+#
+# An unspecified (empty) passphrase disables processing federation requests.
+#
+# This value can be anything you want: an integer, a sentence, an haiku, etc.
+# Keep the value simple, though, to avoid Java properties file encoding issues.
+#
+# Changing your passphrase will break any registrations you have established with other
+# Gitblit instances.
+#
+# CASE-SENSITIVE
+# SINCE 0.6.0
+# RESTART REQUIRED *(only to enable or disable federation)*
+federation.passphrase =
+
+# Control whether or not this Gitblit instance can receive federation proposals
+# from another Gitblit instance. Registering a federated Gitblit is a manual
+# process. Proposals help to simplify that process by allowing a remote Gitblit
+# instance to send your Gitblit instance the federation pull data.
+#
+# SINCE 0.6.0
+federation.allowProposals = false
+
+# The destination folder for cached federation proposals.
+# Use forward slashes even on Windows!!
+#
+# SINCE 0.6.0
+# BASEFOLDER
+federation.proposalsFolder = ${baseFolder}/proposals
+
+# The default pull frequency if frequency is unspecified on a registration
+#
+# SINCE 0.6.0
+federation.defaultFrequency = 60 mins
+
+# Federation Sets are named groups of repositories. The Federation Sets are
+# available for selection in the repository settings page. You can assign a
+# repository to one or more sets and then distribute the token for the set.
+# This allows you to grant federation pull access to a subset of your available
+# repositories. Tokens for federation sets only grant repository pull access.
+#
+# SPACE-DELIMITED
+# CASE-SENSITIVE
+# SINCE 0.6.0
+federation.sets =
+
+# Federation pull registrations
+# Registrations are read once, at startup.
+#
+# RESTART REQUIRED
+#
+# frequency:
+# The shortest frequency allowed is every 5 minutes
+# Decimal frequency values are cast to integers
+# Frequency values may be specified in mins, hours, or days
+# Values that can not be parsed or are unspecified default to *federation.defaultFrequency*
+#
+# folder:
+# if unspecified, the folder is *git.repositoriesFolder*
+# if specified, the folder is relative to *git.repositoriesFolder*
+#
+# bare:
+# if true, each repository will be created as a *bare* repository and will not
+# have a working directory.
+#
+# if false, each repository will be created as a normal repository suitable
+# for local work.
+#
+# mirror:
+# if true, each repository HEAD is reset to *origin/master* after each pull.
+# The repository will be flagged *isFrozen* after the initial clone.
+#
+# if false, each repository HEAD will point to the FETCH_HEAD of the initial
+# clone from the origin until pushed to or otherwise manipulated.
+#
+# mergeAccounts:
+# if true, remote accounts and their permissions are merged into your
+# users.properties file
+#
+# notifyOnError:
+# if true and the mail configuration is properly set, administrators will be
+# notified by email of pull failures
+#
+# include and exclude:
+# Space-delimited list of repositories to include or exclude from pull
+# may be * wildcard to include or exclude all
+# may use fuzzy match (e.g. org.eclipse.*)
+
+#
+# (Nearly) Perfect Mirror example
+#
+
+#federation.example1.url = https://go.gitblit.com
+#federation.example1.token = 6f3b8a24bf970f17289b234284c94f43eb42f0e4
+#federation.example1.frequency = 120 mins
+#federation.example1.folder =
+#federation.example1.bare = true
+#federation.example1.mirror = true
+#federation.example1.mergeAccounts = true
+
+#
+# Advanced Realm Settings
+#
+
+# URL of the LDAP server.
+# To use encrypted transport, use either ldaps:// URL for SSL or ldap+tls:// to
+# send StartTLS command.
+#
+# SINCE 1.0.0
+realm.ldap.server = ldap://localhost
+
+# Login username for LDAP searches.
+# If this value is unspecified, anonymous LDAP login will be used.
+#
+# e.g. mydomain\\username
+#
+# SINCE 1.0.0
+realm.ldap.username = cn=Directory Manager
+
+# Login password for LDAP searches.
+#
+# SINCE 1.0.0
+realm.ldap.password = password
+
+# The LdapUserService must be backed by another user service for standard user
+# and team management.
+# default: users.conf
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+# BASEFOLDER
+realm.ldap.backingUserService = ${baseFolder}/users.conf
+
+# Delegate team membership control to LDAP.
+#
+# If true, team user memberships will be specified by LDAP groups. This will
+# disable team selection in Edit User and user selection in Edit Team.
+#
+# If false, LDAP will only be used for authentication and Gitblit will maintain
+# team memberships with the *realm.ldap.backingUserService*.
+#
+# SINCE 1.0.0
+realm.ldap.maintainTeams = false
+
+# Root node for all LDAP users
+#
+# This is the root node from which subtree user searches will begin.
+# If blank, Gitblit will search ALL nodes.
+#
+# SINCE 1.0.0
+realm.ldap.accountBase = OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain
+
+# Filter criteria for LDAP users
+#
+# Query pattern to use when searching for a user account. This may be any valid
+# LDAP query expression, including the standard (&) and (|) operators.
+#
+# Variables may be injected via the ${variableName} syntax.
+# Recognized variables are:
+# ${username} - The text entered as the user name
+#
+# SINCE 1.0.0
+realm.ldap.accountPattern = (&(objectClass=person)(sAMAccountName=${username}))
+
+# Root node for all LDAP groups to be used as Gitblit Teams
+#
+# This is the root node from which subtree team searches will begin.
+# If blank, Gitblit will search ALL nodes.
+#
+# SINCE 1.0.0
+realm.ldap.groupBase = OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain
+
+# Filter criteria for LDAP groups
+#
+# Query pattern to use when searching for a team. This may be any valid
+# LDAP query expression, including the standard (&) and (|) operators.
+#
+# Variables may be injected via the ${variableName} syntax.
+# Recognized variables are:
+# ${username} - The text entered as the user name
+# ${dn} - The Distinguished Name of the user logged in
+#
+# All attributes from the LDAP User record are available. For example, if a user
+# has an attribute "fullName" set to "John", "(fn=${fullName})" will be
+# translated to "(fn=John)".
+#
+# SINCE 1.0.0
+realm.ldap.groupMemberPattern = (&(objectClass=group)(member=${dn}))
+
+# LDAP users or groups that should be given administrator privileges.
+#
+# Teams are specified with a leading '@' character. Groups with spaces in the
+# name can be entered as "@team name".
+#
+# e.g. realm.ldap.admins = john @git_admins "@git admins"
+#
+# SPACE-DELIMITED
+# SINCE 1.0.0
+realm.ldap.admins = @Git_Admins
+
+# Attribute(s) on the USER record that indicate their display (or full) name.
+# Leave blank for no mapping available in LDAP.
+#
+# This may be a single attribute, or a string of multiple attributes. Examples:
+# displayName - Uses the attribute 'displayName' on the user record
+# ${personalTitle}. ${givenName} ${surname} - Will concatenate the 3
+# attributes together, with a '.' after personalTitle
+#
+# SINCE 1.0.0
+realm.ldap.displayName = displayName
+
+# Attribute(s) on the USER record that indicate their email address.
+# Leave blank for no mapping available in LDAP.
+#
+# This may be a single attribute, or a string of multiple attributes. Examples:
+# email - Uses the attribute 'email' on the user record
+# ${givenName}.${surname}@gitblit.com -Will concatenate the 2 attributes
+# together with a '.' and '@' creating something like first.last@gitblit.com
+#
+# SINCE 1.0.0
+realm.ldap.email = email
+
+# Defines the cache period to be used when caching LDAP queries. This is currently
+# only used for LDAP user synchronization.
+#
+# Must be of the form '<long> <TimeUnit>' where <TimeUnit> is one of 'MILLISECONDS', 'SECONDS', 'MINUTES', 'HOURS', 'DAYS'
+# default: 2 MINUTES
+#
+# RESTART REQUIRED
+realm.ldap.ldapCachePeriod = 2 MINUTES
+
+# Defines whether to synchronize all LDAP users into the backing user service
+#
+# Valid values: true, false
+# If left blank, false is assumed
+realm.ldap.synchronizeUsers.enable = false
+
+# Defines whether to delete non-existent LDAP users from the backing user service
+# during synchronization. depends on realm.ldap.synchronizeUsers.enable = true
+#
+# Valid values: true, false
+# If left blank, true is assumed
+realm.ldap.synchronizeUsers.removeDeleted = true
+
+# Attribute on the USER record that indicate their username to be used in gitblit
+# when synchronizing users from LDAP
+# if blank, Gitblit will use uid
+# For MS Active Directory this may be sAMAccountName
+realm.ldap.uid = uid
+
+# The RedmineUserService must be backed by another user service for standard user
+# and team management.
+# default: users.conf
+#
+# RESTART REQUIRED
+# BASEFOLDER
+realm.redmine.backingUserService = ${baseFolder}/users.conf
+
+# URL of the Redmine.
+realm.redmine.url = http://example.com/redmine
+
+#
+# Server Settings
+#
+
+# The temporary folder to decompress the embedded gitblit webapp.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+# BASEFOLDER
+server.tempFolder = ${baseFolder}/temp
+
+# Use Jetty NIO connectors. If false, Jetty Socket connectors will be used.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.useNio = true
+
+# Context path for the GO application. You might want to change the context
+# path if running Gitblit behind a proxy layer such as mod_proxy.
+#
+# SINCE 0.7.0
+# RESTART REQUIRED
+server.contextPath = /
+
+# Standard http port to serve. <= 0 disables this connector.
+# On Unix/Linux systems, ports < 1024 require root permissions.
+# Recommended value: 80 or 8080
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.httpPort = 0
+
+# Secure/SSL https port to serve. <= 0 disables this connector.
+# On Unix/Linux systems, ports < 1024 require root permissions.
+# Recommended value: 443 or 8443
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.httpsPort = 8443
+
+# Port for serving an Apache JServ Protocol (AJP) 1.3 connector for integrating
+# Gitblit GO into an Apache HTTP server setup. <= 0 disables this connector.
+# Recommended value: 8009
+#
+# SINCE 0.9.0
+# RESTART REQUIRED
+server.ajpPort = 0
+
+# Specify the interface for Jetty to bind the standard connector.
+# You may specify an ip or an empty value to bind to all interfaces.
+# Specifying localhost will result in Gitblit ONLY listening to requests to
+# localhost.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.httpBindInterface = localhost
+
+# Specify the interface for Jetty to bind the secure connector.
+# You may specify an ip or an empty value to bind to all interfaces.
+# Specifying localhost will result in Gitblit ONLY listening to requests to
+# localhost.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.httpsBindInterface = localhost
+
+# Specify the interface for Jetty to bind the AJP connector.
+# You may specify an ip or an empty value to bind to all interfaces.
+# Specifying localhost will result in Gitblit ONLY listening to requests to
+# localhost.
+#
+# SINCE 0.9.0
+# RESTART REQUIRED
+server.ajpBindInterface = localhost
+
+# Alias of certificate to use for https/SSL serving. If blank the first
+# certificate found in the keystore will be used.
+#
+# SINCE 1.2.0
+# RESTART REQUIRED
+server.certificateAlias = localhost
+
+# Password for SSL keystore.
+# Keystore password and certificate password must match.
+# This is provided for convenience, its probably more secure to set this value
+# using the --storePassword command line parameter.
+#
+# If you are using the official JRE or JDK from Oracle you may not have the
+# JCE Unlimited Strength Jurisdiction Policy files bundled with your JVM. Because
+# of this, your store/key password can not exceed 7 characters. If you require
+# longer passwords you may need to install the JCE Unlimited Strength Jurisdiction
+# Policy files from Oracle.
+#
+# http://www.oracle.com/technetwork/java/javase/downloads/index.html
+#
+# Gitblit and the Gitblit Certificate Authority will both indicate if Unlimited
+# Strength encryption is available.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.storePassword = gitblit
+
+# If serving over https (recommended) you might consider requiring clients to
+# authenticate with ssl certificates. If enabled, only https clients with the
+# a valid client certificate will be able to access Gitblit.
+#
+# If disabled, client certificate authentication is optional and will be tried
+# first before falling-back to form authentication or basic authentication.
+#
+# Requiring client certificates to access any of Gitblit may be too extreme,
+# consider this carefully.
+#
+# SINCE 1.2.0
+# RESTART REQUIRED
+server.requireClientCertificates = false
+
+# Port for shutdown monitor to listen on.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.shutdownPort = 8081
diff --git a/src/main/distrib/data/groovy/.gitignore b/src/main/distrib/data/groovy/.gitignore new file mode 100644 index 00000000..e58dc47f --- /dev/null +++ b/src/main/distrib/data/groovy/.gitignore @@ -0,0 +1 @@ +/grape diff --git a/src/main/distrib/data/groovy/blockpush.groovy b/src/main/distrib/data/groovy/blockpush.groovy new file mode 100644 index 00000000..caef3306 --- /dev/null +++ b/src/main/distrib/data/groovy/blockpush.groovy @@ -0,0 +1,94 @@ +/*
+ * Copyright 2011 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.
+ */
+import java.text.MessageFormat;
+
+import com.gitblit.GitBlit
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.UserModel
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.slf4j.Logger
+import com.gitblit.utils.ClientLogger
+
+/**
+ * Sample Gitblit Pre-Receive Hook: blockpush
+ *
+ * This script could and perhaps should be further developed to provide
+ * a full repository-branch permissions system similar to gitolite or gitosis.
+ *
+ * The Pre-Receive hook is executed after an incoming push has been parsed,
+ * validated, and objects have been written but BEFORE the refs are updated.
+ * This is the appropriate point to block a push for some reason.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.preReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * If you want this hook script to fail and abort all subsequent scripts in the
+ * chain, "return false" at the appropriate failure points.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * receivePack JGit Receive Pack org.eclipse.jgit.transport.ReceivePack
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ */
+
+// Indicate we have started the script
+logger.info("blockpush hook triggered by ${user.username} for ${repository.name}: checking ${commands.size} commands")
+
+/*
+ * Example rejection of pushes to the master branch of example.git
+ */
+def blocked = false
+switch (repository.name) {
+ case 'ex@mple.git':
+ for (ReceiveCommand command : commands) {
+ def updatedRef = command.refName
+ if (updatedRef.equals('refs/heads/master')) {
+ // to reject a command set it's result to anything other than Result.NOT_ATTEMPTED
+ command.setResult(Result.REJECTED_OTHER_REASON, "You are not permitted to write to ${repository.name}:${updatedRef}")
+ blocked = true
+ }
+ }
+ break
+
+ default:
+ break
+}
+
+if (blocked) {
+ // return false to break the push hook chain
+ return false
+}
\ No newline at end of file diff --git a/src/main/distrib/data/groovy/jenkins.groovy b/src/main/distrib/data/groovy/jenkins.groovy new file mode 100644 index 00000000..d76a3d66 --- /dev/null +++ b/src/main/distrib/data/groovy/jenkins.groovy @@ -0,0 +1,76 @@ +/*
+ * Copyright 2011 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.
+ */
+import com.gitblit.GitBlit
+import com.gitblit.Keys
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.UserModel
+import com.gitblit.utils.JGitUtils
+import org.eclipse.jgit.lib.Repository
+import org.eclipse.jgit.revwalk.RevCommit
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.slf4j.Logger
+
+/**
+ * Sample Gitblit Post-Receive Hook: jenkins
+ *
+ * The Post-Receive hook is executed AFTER the pushed commits have been applied
+ * to the Git repository. This is the appropriate point to trigger an
+ * integration build or to send a notification.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.postReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * receivePack JGit Receive Pack org.eclipse.jgit.transport.ReceivePack
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ */
+// Indicate we have started the script
+logger.info("jenkins hook triggered by ${user.username} for ${repository.name}")
+
+// This script requires Jenkins Git plugin 1.1.14 or later
+// http://kohsuke.org/2011/12/01/polling-must-die-triggering-jenkins-builds-from-a-git-hook/
+
+// define your jenkins url here or set groovy.jenkinsServer in
+// gitblit.properties or web.xml
+def jenkinsUrl = gitblit.getString('groovy.jenkinsServer', 'http://yourserver/jenkins')
+
+// define the trigger url
+def triggerUrl = jenkinsUrl + "/git/notifyCommit?url=$url/git/$repository.name"
+
+// trigger the build
+new URL(triggerUrl).getContent()
diff --git a/src/main/distrib/data/groovy/localclone.groovy b/src/main/distrib/data/groovy/localclone.groovy new file mode 100644 index 00000000..49b7f8b3 --- /dev/null +++ b/src/main/distrib/data/groovy/localclone.groovy @@ -0,0 +1,106 @@ +/*
+ * Copyright 2012 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import com.gitblit.GitBlit
+import com.gitblit.Keys
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.TeamModel
+import com.gitblit.models.UserModel
+import com.gitblit.utils.JGitUtils
+import com.gitblit.utils.StringUtils
+import java.text.SimpleDateFormat
+import org.eclipse.jgit.api.CloneCommand
+import org.eclipse.jgit.api.Git
+import org.eclipse.jgit.lib.Repository
+import org.eclipse.jgit.lib.Config
+import org.eclipse.jgit.revwalk.RevCommit
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.eclipse.jgit.util.FileUtils
+import org.slf4j.Logger
+
+/**
+ * Sample Gitblit Post-Receive Hook: localclone
+ *
+ * The Post-Receive hook is executed AFTER the pushed commits have been applied
+ * to the Git repository. This is the appropriate point to trigger an
+ * integration build or to send a notification.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.postReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * If you want this hook script to fail and abort all subsequent scripts in the
+ * chain, "return false" at the appropriate failure points.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * receivePack JGit Receive Pack org.eclipse.jgit.transport.ReceivePack
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ */
+
+// Indicate we have started the script
+logger.info("localclone hook triggered by ${user.username} for ${repository.name}")
+
+def rootFolder = 'c:/test'
+def bare = false
+def cloneAllBranches = true
+def cloneBranch = 'refs/heads/master'
+def includeSubmodules = true
+
+def repoName = repository.name
+def destinationFolder = new File(rootFolder, StringUtils.stripDotGit(repoName))
+def srcUrl = 'file://' + new File(GitBlit.getRepositoriesFolder(), repoName).absolutePath
+
+// delete any previous clone
+if (destinationFolder.exists()) {
+ FileUtils.delete(destinationFolder, FileUtils.RECURSIVE)
+}
+
+// clone the repository
+logger.info("cloning ${srcUrl} to ${destinationFolder}")
+CloneCommand cmd = Git.cloneRepository();
+cmd.setBare(bare)
+if (cloneAllBranches)
+ cmd.setCloneAllBranches(true)
+else
+ cmd.setBranch(cloneBranch)
+cmd.setCloneSubmodules(includeSubmodules)
+cmd.setURI(srcUrl)
+cmd.setDirectory(destinationFolder)
+Git git = cmd.call();
+git.repository.close()
+
+// report clone operation success back to pushing Git client
+clientLogger.info("${repoName} cloned to ${destinationFolder}")
\ No newline at end of file diff --git a/src/main/distrib/data/groovy/protect-refs.groovy b/src/main/distrib/data/groovy/protect-refs.groovy new file mode 100644 index 00000000..b1b611f4 --- /dev/null +++ b/src/main/distrib/data/groovy/protect-refs.groovy @@ -0,0 +1,113 @@ +/*
+ * Copyright 2012 Philip L. McMahon.
+ *
+ * Derived from blockpush.groovy, copyright 2011 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.
+ */
+import com.gitblit.GitBlit
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.UserModel
+
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.slf4j.Logger
+
+/**
+ * Sample Gitblit Pre-Receive Hook: protect-refs
+ *
+ * This script provides basic authorization of receive command types for a list
+ * of known ref patterns. Command types and unmatched ref patterns will be
+ * ignored, meaning this script has an "allow by default" policy.
+ *
+ * This script works best when a repository requires authentication on push, but
+ * can be used to enforce fast-forward commits or prohibit ref deletion by
+ * setting the *authorizedTeams* variable to an empty list and adding a ".+"
+ * entry to the *protectedRefs* list.
+ *
+ * The Pre-Receive hook is executed after an incoming push has been parsed,
+ * validated, and objects have been written but BEFORE the refs are updated.
+ * This is the appropriate point to block a push for some reason.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.preReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * This script may reject one or more commands, but will never return false.
+ * Subsequent scripts, if any, will always be invoked.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * receivePack JGit Receive Pack org.eclipse.jgit.transport.ReceivePack
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ */
+
+// map of protected command types to returned results type
+// commands not included will skip authz check
+def protectedCmds = [
+ UPDATE_NONFASTFORWARD: Result.REJECTED_NONFASTFORWARD,
+ DELETE: Result.REJECTED_NODELETE
+]
+
+// list of regex patterns for protected refs
+def protectedRefs = [
+ "refs/heads/master",
+ "refs/tags/.+"
+]
+
+// teams which are authorized to perform protected commands on protected refs
+def authorizedTeams = [ "admins" ]
+
+for (ReceiveCommand command : commands) {
+ def updateType = command.type
+ def updatedRef = command.refName
+
+ // find first regex which matches updated ref, if any
+ def refPattern = protectedRefs.find { updatedRef.matches ~it }
+
+ // find rejection result for update type, if any
+ def result = protectedCmds[updateType.name()]
+
+ // command requires authz if ref is protected and has a mapped rejection result
+ if (refPattern && result) {
+
+ // verify user is a member of any authorized team
+ def team = authorizedTeams.find { user.isTeamMember it }
+ if (team) {
+ // don't adjust command result
+ logger.info "${user.username} authorized for ${updateType} of protected ref ${repository.name}:${updatedRef} (${command.oldId.name} -> ${command.newId.name})"
+ } else {
+ // mark command result as rejected
+ command.setResult(result, "${user.username} cannot ${updateType} protected ref ${repository.name}:${updatedRef} matching pattern ${refPattern}")
+ }
+ }
+}
diff --git a/src/main/distrib/data/groovy/sendmail-html.groovy b/src/main/distrib/data/groovy/sendmail-html.groovy new file mode 100644 index 00000000..16920735 --- /dev/null +++ b/src/main/distrib/data/groovy/sendmail-html.groovy @@ -0,0 +1,516 @@ +/*
+ * Copyright 2012 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import com.gitblit.GitBlit
+import com.gitblit.Keys
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.TeamModel
+import com.gitblit.models.UserModel
+import com.gitblit.utils.JGitUtils
+import java.text.SimpleDateFormat
+
+import org.eclipse.jgit.api.Status;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.diff.DiffEntry;
+import org.eclipse.jgit.diff.DiffFormatter;
+import org.eclipse.jgit.diff.RawTextComparator;
+import org.eclipse.jgit.diff.DiffEntry.ChangeType;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.IndexDiff;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository
+import org.eclipse.jgit.lib.Config
+import org.eclipse.jgit.patch.FileHeader;
+import org.eclipse.jgit.revwalk.RevCommit
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.eclipse.jgit.treewalk.FileTreeIterator;
+import org.eclipse.jgit.treewalk.EmptyTreeIterator;
+import org.eclipse.jgit.treewalk.CanonicalTreeParser;
+import org.eclipse.jgit.util.io.DisabledOutputStream;
+import org.slf4j.Logger
+import groovy.xml.MarkupBuilder
+
+import java.io.IOException;
+import java.security.MessageDigest
+
+
+/**
+ * Sample Gitblit Post-Receive Hook: sendmail-html
+ *
+ * The Post-Receive hook is executed AFTER the pushed commits have been applied
+ * to the Git repository. This is the appropriate point to trigger an
+ * integration build or to send a notification.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.postReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * If you want this hook script to fail and abort all subsequent scripts in the
+ * chain, "return false" at the appropriate failure points.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit java.lang.String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ */
+
+com.gitblit.models.UserModel userModel = user
+
+// Indicate we have started the script
+logger.info("sendmail-html hook triggered by ${user.username} for ${repository.name}")
+
+/*
+ * Primitive email notification.
+ * This requires the mail settings to be properly configured in Gitblit.
+ */
+
+Repository r = gitblit.getRepository(repository.name)
+
+// reuse existing repository config settings, if available
+Config config = r.getConfig()
+def mailinglist = config.getString('hooks', null, 'mailinglist')
+def emailprefix = config.getString('hooks', null, 'emailprefix')
+
+// set default values
+def toAddresses = []
+if (emailprefix == null) {
+ emailprefix = '[Gitblit]'
+}
+
+if (mailinglist != null) {
+ def addrs = mailinglist.split(/(,|\s)/)
+ toAddresses.addAll(addrs)
+}
+
+// add all mailing lists defined in gitblit.properties or web.xml
+toAddresses.addAll(GitBlit.getStrings(Keys.mail.mailingLists))
+
+// add all team mailing lists
+def teams = gitblit.getRepositoryTeams(repository)
+for (team in teams) {
+ TeamModel model = gitblit.getTeamModel(team)
+ if (model.mailingLists) {
+ toAddresses.addAll(model.mailingLists)
+ }
+}
+
+// add all mailing lists for the repository
+toAddresses.addAll(repository.mailingLists)
+
+// define the summary and commit urls
+def repo = repository.name
+def summaryUrl = url + "/summary?r=$repo"
+def baseCommitUrl = url + "/commit?r=$repo&h="
+def baseBlobDiffUrl = url + "/blobdiff/?r=$repo&h="
+def baseCommitDiffUrl = url + "/commitdiff/?r=$repo&h="
+def forwardSlashChar = gitblit.getString(Keys.web.forwardSlashCharacter, '/')
+
+if (gitblit.getBoolean(Keys.web.mountParameters, true)) {
+ repo = repo.replace('/', forwardSlashChar).replace('/', '%2F')
+ summaryUrl = url + "/summary/$repo"
+ baseCommitUrl = url + "/commit/$repo/"
+ baseBlobDiffUrl = url + "/blobdiff/$repo/"
+ baseCommitDiffUrl = url + "/commitdiff/$repo/"
+}
+
+class HtmlMailWriter {
+ Repository repository
+ def url
+ def baseCommitUrl
+ def baseCommitDiffUrl
+ def baseBlobDiffUrl
+ def mountParameters
+ def forwardSlashChar
+ def includeGravatar
+ def shortCommitIdLength
+ def commitCount = 0
+ def commands
+ def writer = new StringWriter();
+ def builder = new MarkupBuilder(writer)
+
+ def writeStyle() {
+ builder.style(type:"text/css", '''
+ .table td {
+ vertical-align: middle;
+ }
+ tr.noborder td {
+ border: none;
+ padding-top: 0px;
+ }
+ .gravatar-column {
+ width: 5%;
+ }
+ .author-column {
+ width: 20%;
+ }
+ .commit-column {
+ width: 5%;
+ }
+ .status-column {
+ width: 10%;
+ }
+ .table-disable-hover.table tbody tr:hover td,
+ .table-disable-hover.table tbody tr:hover th {
+ background-color: inherit;
+ }
+ .table-disable-hover.table-striped tbody tr:nth-child(odd):hover td,
+ .table-disable-hover.table-striped tbody tr:nth-child(odd):hover th {
+ background-color: #f9f9f9;
+ }
+ ''')
+ }
+
+ def writeBranchTitle(type, name, action, number) {
+ builder.div('class' : 'pageTitle') {
+ builder.span('class':'project') {
+ mkp.yield "$type "
+ span('class': 'repository', name )
+ if (number > 0) {
+ mkp.yield " $action ($number commits)"
+ } else {
+ mkp.yield " $action"
+ }
+ }
+ }
+ }
+
+ def writeBranchDeletedTitle(type, name) {
+ builder.div('class' : 'pageTitle', 'style':'color:red') {
+ builder.span('class':'project') {
+ mkp.yield "$type "
+ span('class': 'repository', name )
+ mkp.yield " deleted"
+ }
+ }
+ }
+
+ def commitUrl(RevCommit commit) {
+ "${baseCommitUrl}$commit.id.name"
+ }
+
+ def commitDiffUrl(RevCommit commit) {
+ "${baseCommitDiffUrl}$commit.id.name"
+ }
+
+ def encoded(String path) {
+ path.replace('/', forwardSlashChar).replace('/', '%2F')
+ }
+
+ def blobDiffUrl(objectId, path) {
+ if (mountParameters) {
+ // REST style
+ "${baseBlobDiffUrl}${objectId.name()}/${encoded(path)}"
+ } else {
+ "${baseBlobDiffUrl}${objectId.name()}&f=${path}"
+ }
+
+ }
+
+ def writeCommitTable(commits, includeChangedPaths=true) {
+ // Write commits table
+ builder.table('class':"table table-disable-hover") {
+ thead {
+ tr {
+ th(colspan: includeGravatar ? 2 : 1, "Author")
+ th( "Commit" )
+ th( "Message" )
+ }
+ }
+ tbody() {
+
+ // Write all the commits
+ for (commit in commits) {
+ writeCommit(commit)
+
+ if (includeChangedPaths) {
+ // Write detail on that particular commit
+ tr('class' : 'noborder') {
+ td (colspan: includeGravatar ? 3 : 2)
+ td (colspan:2) { writeStatusTable(commit) }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ def writeCommit(commit) {
+ def abbreviated = repository.newObjectReader().abbreviate(commit.id, shortCommitIdLength).name()
+ def author = commit.authorIdent.name
+ def email = commit.authorIdent.emailAddress
+ def message = commit.shortMessage
+ builder.tr {
+ if (includeGravatar) {
+ td('class':"gravatar-column") {
+ img(src:gravatarUrl(email), 'class':"gravatar")
+ }
+ }
+ td('class':"author-column", author)
+ td('class':"commit-column") {
+ a(href:commitUrl(commit)) {
+ span('class':"label label-info", abbreviated )
+ }
+ }
+ td {
+ mkp.yield message
+ a('class':'link', href:commitDiffUrl(commit), " [commitdiff]" )
+ }
+ }
+ }
+
+ def writeStatusLabel(style, tooltip) {
+ builder.span('class' : style, 'title' : tooltip )
+ }
+
+ def writeAddStatusLine(ObjectId id, FileHeader header) {
+ builder.td('class':'changeType') {
+ writeStatusLabel("addition", "addition")
+ }
+ builder.td {
+ a(href:blobDiffUrl(id, header.newPath), header.newPath)
+ }
+ }
+
+ def writeCopyStatusLine(ObjectId id, FileHeader header) {
+ builder.td('class':'changeType') {
+ writeStatusLabel("rename", "rename")
+ }
+ builder.td() {
+ a(href:blobDiffUrl(id, header.newPath), header.oldPath + " copied to " + header.newPath)
+ }
+ }
+
+ def writeDeleteStatusLine(ObjectId id, FileHeader header) {
+ builder.td('class':'changeType') {
+ writeStatusLabel("deletion", "deletion")
+ }
+ builder.td() {
+ a(href:blobDiffUrl(id, header.oldPath), header.oldPath)
+ }
+ }
+
+ def writeModifyStatusLine(ObjectId id, FileHeader header) {
+ builder.td('class':'changeType') {
+ writeStatusLabel("modification", "modification")
+ }
+ builder.td() {
+ a(href:blobDiffUrl(id, header.oldPath), header.oldPath)
+ }
+ }
+
+ def writeRenameStatusLine(ObjectId id, FileHeader header) {
+ builder.td('class':'changeType') {
+ writeStatusLabel("rename", "rename")
+ }
+ builder.td() {
+ mkp.yield header.oldPath
+ mkp.yieldUnescaped "<b> -&rt; </b>"
+ a(href:blobDiffUrl(id, header.newPath), header.newPath)
+ }
+ }
+
+ def writeStatusLine(ObjectId id, FileHeader header) {
+ builder.tr {
+ switch (header.changeType) {
+ case ChangeType.ADD:
+ writeAddStatusLine(id, header)
+ break;
+ case ChangeType.COPY:
+ writeCopyStatusLine(id, header)
+ break;
+ case ChangeType.DELETE:
+ writeDeleteStatusLine(id, header)
+ break;
+ case ChangeType.MODIFY:
+ writeModifyStatusLine(id, header)
+ break;
+ case ChangeType.RENAME:
+ writeRenameStatusLine(id, header)
+ break;
+ }
+ }
+ }
+
+ def writeStatusTable(RevCommit commit) {
+ DiffFormatter formatter = new DiffFormatter(DisabledOutputStream.INSTANCE)
+ formatter.setRepository(repository)
+ formatter.setDetectRenames(true)
+ formatter.setDiffComparator(RawTextComparator.DEFAULT);
+
+ def diffs
+ RevWalk rw = new RevWalk(repository)
+ if (commit.parentCount > 0) {
+ RevCommit parent = rw.parseCommit(commit.parents[0].id)
+ diffs = formatter.scan(parent.tree, commit.tree)
+ } else {
+ diffs = formatter.scan(new EmptyTreeIterator(),
+ new CanonicalTreeParser(null, rw.objectReader, commit.tree))
+ }
+ rw.dispose()
+ // Write status table
+ builder.table('class':"plain") {
+ tbody() {
+ for (DiffEntry entry in diffs) {
+ FileHeader header = formatter.toFileHeader(entry)
+ writeStatusLine(commit.id, header)
+ }
+ }
+ }
+ }
+
+
+ def md5(text) {
+
+ def digest = MessageDigest.getInstance("MD5")
+
+ //Quick MD5 of text
+ def hash = new BigInteger(1, digest.digest(text.getBytes()))
+ .toString(16)
+ .padLeft(32, "0")
+ hash.toString()
+ }
+
+ def gravatarUrl(email) {
+ def cleaned = email.trim().toLowerCase()
+ "http://www.gravatar.com/avatar/${md5(cleaned)}?s=30"
+ }
+
+ def writeNavbar() {
+ builder.div('class':"navbar navbar-fixed-top") {
+ div('class':"navbar-inner") {
+ div('class':"container") {
+ a('class':"brand", href:"${url}", title:"GitBlit") {
+ img(src:"${url}/gitblt_25_white.png",
+ width:"79",
+ height:"25",
+ 'class':"logo")
+ }
+ }
+ }
+ }
+ }
+
+ def write() {
+ builder.html {
+ head {
+ link(rel:"stylesheet", href:"${url}/bootstrap/css/bootstrap.css")
+ link(rel:"stylesheet", href:"${url}/gitblit.css")
+ link(rel:"stylesheet", href:"${url}/bootstrap/css/bootstrap-responsive.css")
+ writeStyle()
+ }
+ body {
+
+ writeNavbar()
+
+ div('class':"container") {
+
+ for (command in commands) {
+ def ref = command.refName
+ def refType = 'Branch'
+ if (ref.startsWith('refs/heads/')) {
+ ref = command.refName.substring('refs/heads/'.length())
+ } else if (ref.startsWith('refs/tags/')) {
+ ref = command.refName.substring('refs/tags/'.length())
+ refType = 'Tag'
+ }
+
+ switch (command.type) {
+ case ReceiveCommand.Type.CREATE:
+ def commits = JGitUtils.getRevLog(repository, command.oldId.name, command.newId.name).reverse()
+ commitCount += commits.size()
+ if (refType == 'Branch') {
+ // new branch
+ writeBranchTitle(refType, ref, "created", commits.size())
+ writeCommitTable(commits, true)
+ } else {
+ // new tag
+ writeBranchTitle(refType, ref, "created", 0)
+ writeCommitTable(commits, false)
+ }
+ break
+ case ReceiveCommand.Type.UPDATE:
+ def commits = JGitUtils.getRevLog(repository, command.oldId.name, command.newId.name).reverse()
+ commitCount += commits.size()
+ // fast-forward branch commits table
+ // Write header
+ writeBranchTitle(refType, ref, "updated", commits.size())
+ writeCommitTable(commits)
+ break
+ case ReceiveCommand.Type.UPDATE_NONFASTFORWARD:
+ def commits = JGitUtils.getRevLog(repository, command.oldId.name, command.newId.name).reverse()
+ commitCount += commits.size()
+ // non-fast-forward branch commits table
+ // Write header
+ writeBranchTitle(refType, ref, "updated [NON fast-forward]", commits.size())
+ writeCommitTable(commits)
+ break
+ case ReceiveCommand.Type.DELETE:
+ // deleted branch/tag
+ writeBranchDeletedTitle(refType, ref)
+ break
+ default:
+ break
+ }
+ }
+ }
+ }
+ }
+ writer.toString()
+ }
+
+}
+
+def mailWriter = new HtmlMailWriter()
+mailWriter.repository = r
+mailWriter.baseCommitUrl = baseCommitUrl
+mailWriter.baseBlobDiffUrl = baseBlobDiffUrl
+mailWriter.baseCommitDiffUrl = baseCommitDiffUrl
+mailWriter.forwardSlashChar = forwardSlashChar
+mailWriter.commands = commands
+mailWriter.url = url
+mailWriter.mountParameters = GitBlit.getBoolean(Keys.web.mountParameters, true)
+mailWriter.includeGravatar = GitBlit.getBoolean(Keys.web.allowGravatar, true)
+mailWriter.shortCommitIdLength = GitBlit.getInteger(Keys.web.shortCommitIdLength, 8)
+
+def content = mailWriter.write()
+
+// close the repository reference
+r.close()
+
+// tell Gitblit to send the message (Gitblit filters duplicate addresses)
+def repositoryName = repository.name.substring(0, repository.name.length() - 4)
+gitblit.sendHtmlMail("${emailprefix} ${userModel.displayName} pushed ${mailWriter.commitCount} commits => $repositoryName",
+ content,
+ toAddresses)
diff --git a/src/main/distrib/data/groovy/sendmail.groovy b/src/main/distrib/data/groovy/sendmail.groovy new file mode 100644 index 00000000..c832bc64 --- /dev/null +++ b/src/main/distrib/data/groovy/sendmail.groovy @@ -0,0 +1,176 @@ +/*
+ * Copyright 2011 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.
+ */
+import com.gitblit.GitBlit
+import com.gitblit.Keys
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.TeamModel
+import com.gitblit.models.UserModel
+import com.gitblit.utils.JGitUtils
+import java.text.SimpleDateFormat
+import org.eclipse.jgit.lib.Repository
+import org.eclipse.jgit.lib.Config
+import org.eclipse.jgit.revwalk.RevCommit
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.slf4j.Logger
+
+/**
+ * Sample Gitblit Post-Receive Hook: sendmail
+ *
+ * The Post-Receive hook is executed AFTER the pushed commits have been applied
+ * to the Git repository. This is the appropriate point to trigger an
+ * integration build or to send a notification.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.postReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * If you want this hook script to fail and abort all subsequent scripts in the
+ * chain, "return false" at the appropriate failure points.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * receivePack JGit Receive Pack org.eclipse.jgit.transport.ReceivePack
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ */
+
+// Indicate we have started the script
+logger.info("sendmail hook triggered by ${user.username} for ${repository.name}")
+
+/*
+ * Primitive email notification.
+ * This requires the mail settings to be properly configured in Gitblit.
+ */
+
+Repository r = gitblit.getRepository(repository.name)
+
+// reuse existing repository config settings, if available
+Config config = r.getConfig()
+def mailinglist = config.getString('hooks', null, 'mailinglist')
+def emailprefix = config.getString('hooks', null, 'emailprefix')
+
+// set default values
+def toAddresses = []
+if (emailprefix == null)
+emailprefix = '[Gitblit]'
+
+if (mailinglist != null) {
+ def addrs = mailinglist.split(/(,|\s)/)
+ toAddresses.addAll(addrs)
+}
+
+// add all mailing lists defined in gitblit.properties or web.xml
+toAddresses.addAll(gitblit.getStrings(Keys.mail.mailingLists))
+
+// add all team mailing lists
+def teams = gitblit.getRepositoryTeams(repository)
+for (team in teams) {
+ TeamModel model = gitblit.getTeamModel(team)
+ if (model.mailingLists) {
+ toAddresses.addAll(model.mailingLists)
+ }
+}
+
+// add all mailing lists for the repository
+toAddresses.addAll(repository.mailingLists)
+
+// define the summary and commit urls
+def repo = repository.name
+def summaryUrl
+def commitUrl
+if (gitblit.getBoolean(Keys.web.mountParameters, true)) {
+ repo = repo.replace('/', gitblit.getString(Keys.web.forwardSlashCharacter, '/')).replace('/', '%2F')
+ summaryUrl = url + "/summary/$repo"
+ commitUrl = url + "/commit/$repo/"
+} else {
+ summaryUrl = url + "/summary?r=$repo"
+ commitUrl = url + "/commit?r=$repo&h="
+}
+
+// construct a simple text summary of the changes contained in the push
+def branchBreak = '>---------------------------------------------------------------\n'
+def commitBreak = '\n\n ----\n'
+def commitCount = 0
+def changes = ''
+SimpleDateFormat df = new SimpleDateFormat(gitblit.getString(Keys.web.datetimestampLongFormat, 'EEEE, MMMM d, yyyy h:mm a z'))
+def table = { "\n ${JGitUtils.getDisplayName(it.authorIdent)}\n ${df.format(JGitUtils.getCommitDate(it))}\n\n $it.shortMessage\n\n $commitUrl$it.id.name" }
+for (command in commands) {
+ def ref = command.refName
+ def refType = 'branch'
+ if (ref.startsWith('refs/heads/')) {
+ ref = command.refName.substring('refs/heads/'.length())
+ } else if (ref.startsWith('refs/tags/')) {
+ ref = command.refName.substring('refs/tags/'.length())
+ refType = 'tag'
+ }
+
+ switch (command.type) {
+ case ReceiveCommand.Type.CREATE:
+ def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
+ commitCount += commits.size()
+ // new branch
+ changes += "\n$branchBreak new $refType $ref created ($commits.size commits)\n$branchBreak"
+ changes += commits.collect(table).join(commitBreak)
+ changes += '\n'
+ break
+ case ReceiveCommand.Type.UPDATE:
+ def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
+ commitCount += commits.size()
+ // fast-forward branch commits table
+ changes += "\n$branchBreak $ref $refType updated ($commits.size commits)\n$branchBreak"
+ changes += commits.collect(table).join(commitBreak)
+ changes += '\n'
+ break
+ case ReceiveCommand.Type.UPDATE_NONFASTFORWARD:
+ def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
+ commitCount += commits.size()
+ // non-fast-forward branch commits table
+ changes += "\n$branchBreak $ref $refType updated [NON fast-forward] ($commits.size commits)\n$branchBreak"
+ changes += commits.collect(table).join(commitBreak)
+ changes += '\n'
+ break
+ case ReceiveCommand.Type.DELETE:
+ // deleted branch/tag
+ changes += "\n$branchBreak $ref $refType deleted\n$branchBreak"
+ break
+ default:
+ break
+ }
+}
+// close the repository reference
+r.close()
+
+// tell Gitblit to send the message (Gitblit filters duplicate addresses)
+gitblit.sendMail("$emailprefix $user.username pushed $commitCount commits => $repository.name", "$summaryUrl\n$changes", toAddresses)
\ No newline at end of file diff --git a/src/main/distrib/data/groovy/thebuggenie.groovy b/src/main/distrib/data/groovy/thebuggenie.groovy new file mode 100644 index 00000000..b4385a26 --- /dev/null +++ b/src/main/distrib/data/groovy/thebuggenie.groovy @@ -0,0 +1,88 @@ +/*
+ * Copyright 2011 Wolfgang Gassler gassler.org
+ *
+ * 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.
+ */
+
+import com.gitblit.GitBlit
+import com.gitblit.Keys
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.TeamModel
+import com.gitblit.models.UserModel
+import com.gitblit.utils.JGitUtils
+import java.text.SimpleDateFormat
+import org.eclipse.jgit.lib.Repository
+import org.eclipse.jgit.lib.Config
+import org.eclipse.jgit.revwalk.RevCommit
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.slf4j.Logger
+import org.eclipse.jgit.lib.IndexDiff
+import org.eclipse.jgit.lib.Constants
+import com.gitblit.utils.DiffUtils
+
+/**
+ * Gitblit Post-Receive Hook: thebuggenie
+ * www.thebuggenie.com
+ *
+ * Submit the commit information to thebuggenie bug tracker by calling thebuggenie client tool
+ *
+ * Config of the Script:
+ *
+ * Setup a custom gitblit field in the proprties file of gitblit by adding the following line
+ * groovy.customFields = "thebuggenieProjectId=TheBugGennie project id (used for thebuggenie hoocks)"
+ * This field allows to specify the project id of thebuggenie project in the edit section of gitblit
+ *
+ * Furthermore you need to set the path to thebuggenie client tool by adding the following property to
+ * the gitblit properties file
+ * thebuggenie.tbg_cli = /var/www/thebuggenie_root/tbg_cli
+ */
+
+// Indicate we have started the script
+logger.info("thebuggenie hook triggered by ${user.username} for ${repository.name}")
+
+//fetch the repository data
+Repository r = gitblit.getRepository(repository.name)
+
+//get project id which is defined in the git repo metadata
+def tbgProjectId = repository.customFields.thebuggenieProjectId
+//get path to the thebuggenie client tool which is defined in the gitblit proprties files
+def tbgCliPath = gitblit.getString('thebuggenie.tbg_cli', '/var/www/thebuggenie/tbg_cli')
+def tbgCliDirPath = new File(tbgCliPath).getParent()
+
+for(command in commands) {
+ //fetch all pushed commits
+ def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
+ for (commit in commits) {
+ //get hashes and author data of commit
+ def oldhash = commit.getParent(0).getId().getName()
+ def newhash = commit.getId().getName()
+ def authorIdent = commit.getAuthorIdent()
+ def author = "${authorIdent.name} <${authorIdent.emailAddress}>"
+ //fetch all changed files of the commit
+ def files = JGitUtils.getFilesInCommit(r,commit)
+ def changedFiles = ""
+ for (f in files) {
+ //transform file data to the format which is needed by thebuggenie
+ changedFiles += f.changeType.toString().substring(0,1)+"\t${f.path}\n"
+ }
+ //ok let's submit all information to thebuggenie by calling the client tool
+// def shc = "$tbgCliPath vcs_integration:report_commit $tbgProjectId \"$author\" $newhash \"${commit.fullMessage}\" \"$changedFiles\" $oldhash ${commit.commitTime}"
+ def shc = [tbgCliPath, "vcs_integration:report_commit", tbgProjectId, author, newhash, commit.getFullMessage(), changedFiles, oldhash, commit.getCommitTime()];
+ logger.info("executing in path " + tbgCliDirPath + ": "+shc)
+ shc.execute(null, new File(tbgCliDirPath))
+ }
+}
+
+// close the repository reference
+r.close()
diff --git a/src/main/distrib/data/projects.conf b/src/main/distrib/data/projects.conf new file mode 100644 index 00000000..d43f4829 --- /dev/null +++ b/src/main/distrib/data/projects.conf @@ -0,0 +1,3 @@ +[project "main"]
+ title = Main Repositories
+ description = main group of repositories
\ No newline at end of file diff --git a/src/main/distrib/data/users.conf b/src/main/distrib/data/users.conf new file mode 100644 index 00000000..e9dbd83d --- /dev/null +++ b/src/main/distrib/data/users.conf @@ -0,0 +1,4 @@ +[user "admin"] + password = admin + role = "#admin" + role = "#notfederated" diff --git a/src/main/distrib/federation.properties b/src/main/distrib/federation.properties new file mode 100644 index 00000000..c762b45c --- /dev/null +++ b/src/main/distrib/federation.properties @@ -0,0 +1,83 @@ +#
+# Git Repository Settings
+#
+
+# Base folder for repositories
+# Use forward slashes even on Windows!!
+# e.g. c:/gitrepos
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+git.repositoriesFolder = git
+
+# Search the repositories folder subfolders for other repositories.
+# Repositories MAY NOT be nested (i.e. one repository within another)
+# but they may be grouped together in subfolders.
+# e.g. c:/gitrepos/libraries/mylibrary.git
+# c:/gitrepos/libraries/myotherlibrary.git
+#
+# SINCE 0.5.0
+git.searchRepositoriesSubfolders = true
+
+# Your federation name is used for federation status acknowledgments. If it is
+# unset, and you elect to send a status acknowledgment, your Gitblit instance
+# will be identified by its hostname, if available, else your internal ip address.
+# The source Gitblit instance will also append your external IP address to your
+# identification to differentiate multiple pulling systems behind a single proxy.
+#
+# SINCE 0.6.0
+federation.name =
+
+# Federation pull registrations
+# Registrations are read once, at startup.
+#
+# RESTART REQUIRED
+#
+# frequency:
+# The shortest frequency allowed is every 5 minutes
+# Decimal frequency values are cast to integers
+# Frequency values may be specified in mins, hours, or days
+# Values that can not be parsed or are unspecified default to *federation.defaultFrequency*
+#
+# folder:
+# if unspecified, the folder is *git.repositoriesFolder*
+# if specified, the folder is relative to *git.repositoriesFolder*
+#
+# bare:
+# if true, each repository will be created as a *bare* repository and will not
+# have a working directory.
+#
+# if false, each repository will be created as a normal repository suitable
+# for local work.
+#
+# mirror:
+# if true, each repository HEAD is reset to *origin/master* after each pull.
+# The repository will be flagged *isFrozen* after the initial clone.
+#
+# if false, each repository HEAD will point to the FETCH_HEAD of the initial
+# clone from the origin until pushed to or otherwise manipulated.
+#
+# mergeAccounts:
+# if true, remote accounts and their permissions are merged into your
+# users.properties file
+#
+# notifyOnError:
+# if true and the mail configuration is properly set, administrators will be
+# notified by email of pull failures
+#
+# include and exclude:
+# Space-delimited list of repositories to include or exclude from pull
+# may be * wildcard to include or exclude all
+# may use fuzzy match (e.g. org.eclipse.*)
+
+#
+# (Nearly) Perfect Mirror example
+#
+
+#federation.example1.url = https://go.gitblit.com
+#federation.example1.token = 6f3b8a24bf970f17289b234284c94f43eb42f0e4
+#federation.example1.frequency = 120 mins
+#federation.example1.folder =
+#federation.example1.bare = true
+#federation.example1.mirror = true
+#federation.example1.mergeAccounts = true
diff --git a/src/main/distrib/groovy/fogbugz.groovy b/src/main/distrib/groovy/fogbugz.groovy new file mode 100644 index 00000000..4c19d3da --- /dev/null +++ b/src/main/distrib/groovy/fogbugz.groovy @@ -0,0 +1,167 @@ +import org.eclipse.jgit.revwalk.RevCommit;
+
+/*
+ * 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.
+ */
+import com.gitblit.GitBlit
+import com.gitblit.Keys
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.TeamModel
+import com.gitblit.models.UserModel
+import com.gitblit.utils.JGitUtils
+import com.sun.org.apache.xalan.internal.xsltc.compiler.Import;
+
+import java.text.SimpleDateFormat
+import org.eclipse.jgit.lib.Repository
+import org.eclipse.jgit.lib.Config
+import org.eclipse.jgit.revwalk.RevCommit
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.slf4j.Logger
+
+import org.eclipse.jgit.api.Status;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.diff.DiffEntry;
+import org.eclipse.jgit.diff.DiffFormatter;
+import org.eclipse.jgit.diff.RawTextComparator;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.IndexDiff;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.patch.FileHeader;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.FileTreeIterator;
+import org.eclipse.jgit.treewalk.EmptyTreeIterator;
+import org.eclipse.jgit.treewalk.CanonicalTreeParser;
+import org.eclipse.jgit.util.io.DisabledOutputStream;
+
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * Sample Gitblit Post-Receive Hook: fogbugz
+ *
+ * The purpose of this script is to invoke the Fogbugz API and update a case when
+ * push is received based.
+ *
+ * Example URL - http://bugs.yourdomain.com/fogbugz/cvsSubmit.asp?ixBug=bugID&sFile=file&sPrev=x&sNew=y&ixRepository=206
+ *
+ * The Post-Receive hook is executed AFTER the pushed commits have been applied
+ * to the Git repository. This is the appropriate point to trigger an
+ * integration build or to send a notification.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.postReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * If you want this hook script to fail and abort all subsequent scripts in the
+ * chain, "return false" at the appropriate failure points.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * receivePack JGit Receive Pack org.eclipse.jgit.transport.ReceivePack
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ * Cusom Fileds Used by This script
+ * fogbugzUrl - base URL to Fogbugz (ie. https://bugs.yourdomain.com/fogbugz/)
+ * fogbugzRepositoryId - (ixRepository value from Fogbugz Source Control configuration screen)
+ * fogbugzCommitMessageRegex - regex pattern used to match on bug id
+ */
+
+// Indicate we have started the script
+logger.info("fogbugz hook triggered by ${user.username} for ${repository.name}")
+
+/*
+ * Primitive email notification.
+ * This requires the mail settings to be properly configured in Gitblit.
+ */
+
+Repository r = gitblit.getRepository(repository.name)
+
+// pull custom fields from repository specific values
+// groovy.customFields = "fogbugzUrl=Fogbugz Base URL" "fogbugzRepositoryId=Fogbugz Repository ID" "fogbugzCommitMessageRegex="Fogbugz Commit Message Regular Expression"
+def fogbugzUrl = repository.customFields.fogbugzUrl
+def fogbugzRepositoryId = repository.customFields.fogbugzRepositoryId
+def bugIdRegex = repository.customFields.fogbugzCommitMessageRegex
+
+for (command in commands) {
+
+ for( commit in JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse() ) {
+ // Example URL - http://bugs.salsalabs.com/fogbugz/cvsSubmit.asp?ixBug=bugID&sFile=file&sPrev=x&sNew=y&ixRepository=206
+ def bugIds = [];
+ // Grab the second matcher and then filter out each numeric ID and add it to array
+ (commit.getFullMessage() =~ bugIdRegex).each{ (it[1] =~ "\\d+").each {bugIds.add(it)} }
+
+ for( file in getFiles(r, commit) ) {
+ for( bugId in bugIds ) {
+ def url = "${fogbugzUrl}/cvsSubmit.asp?ixBug=${bugId}&sFile=${file}&sPrev=${command.oldId.name}&sNew=${command.newId.name}&ixRepository=${fogbugzRepositoryId}"
+ logger.info( url );
+ // Hit the page and make sure we get an "OK" response
+ def responseString = new URL(url).getText()
+ if( !"OK".equals(responseString) ) {
+ throw new Exception( "Problem posting ${url} - ${responseString}" );
+ }
+ }
+ }
+ }
+}
+// close the repository reference
+r.close()
+
+/**
+ * For a given commit, find all files part of it.
+ */
+def Set<String> getFiles(Repository r, RevCommit commit) {
+ DiffFormatter formatter = new DiffFormatter(DisabledOutputStream.INSTANCE)
+ formatter.setRepository(r)
+ formatter.setDetectRenames(true)
+ formatter.setDiffComparator(RawTextComparator.DEFAULT);
+
+ def diffs
+ RevWalk rw = new RevWalk(r)
+ if (commit.parentCount > 0) {
+ RevCommit parent = rw.parseCommit(commit.parents[0].id)
+ diffs = formatter.scan(parent.tree, commit.tree)
+ } else {
+ diffs = formatter.scan(new EmptyTreeIterator(),
+ new CanonicalTreeParser(null, rw.objectReader, commit.tree))
+ }
+ rw.dispose()
+
+ // Grab each filepath
+ Set<String> fileNameSet = new HashSet<String>( diffs.size() );
+ for (DiffEntry entry in diffs) {
+ FileHeader header = formatter.toFileHeader(entry)
+ fileNameSet.add( header.newPath )
+ }
+ return fileNameSet;
+}
\ No newline at end of file diff --git a/src/main/distrib/linux/add-indexed-branch.sh b/src/main/distrib/linux/add-indexed-branch.sh new file mode 100644 index 00000000..d31f43ed --- /dev/null +++ b/src/main/distrib/linux/add-indexed-branch.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# -------------------------------------------------------------------------- +# This is for Lucene search integration. +# +# Allows you to add an indexed branch specification to the repository config +# for all matching repositories in the specified folder. +# +# All repositories are included unless excluded using a --skip parameter. +# --skip supports simple wildcard fuzzy matching however only 1 asterisk is +# allowed per parameter. +# +# Always use forward-slashes for the path separator in your parameters!! +# +# Set FOLDER to the server's git.repositoriesFolder +# Set BRANCH ("default" or fully qualified ref - i.e. refs/heads/master) +# Set EXCLUSIONS for any repositories that you do not want to change +# -------------------------------------------------------------------------- +SET FOLDER=git +SET EXCLUSIONS=--skip test.git --skip group/test* +SET BRANCH=default +java -cp gitblit.jar;"%CD%\ext\*" com.gitblit.AddIndexedBranch --repositoriesFolder %FOLDER% --branch %BRANCH% %EXCLUSIONS%
\ No newline at end of file diff --git a/src/main/distrib/linux/authority.sh b/src/main/distrib/linux/authority.sh new file mode 100644 index 00000000..ce5c2377 --- /dev/null +++ b/src/main/distrib/linux/authority.sh @@ -0,0 +1,2 @@ +#!/bin/bash +java -cp gitblit.jar com.gitblit.authority.Launcher --baseFolder data diff --git a/src/main/distrib/linux/gitblit-stop.sh b/src/main/distrib/linux/gitblit-stop.sh new file mode 100644 index 00000000..2fef2034 --- /dev/null +++ b/src/main/distrib/linux/gitblit-stop.sh @@ -0,0 +1,2 @@ +#!/bin/bash +java -jar gitblit.jar --baseFolder data --stop diff --git a/src/main/distrib/linux/gitblit.sh b/src/main/distrib/linux/gitblit.sh new file mode 100644 index 00000000..7d631e72 --- /dev/null +++ b/src/main/distrib/linux/gitblit.sh @@ -0,0 +1,2 @@ +#!/bin/bash +java -jar gitblit.jar --baseFolder data diff --git a/src/main/distrib/linux/install-service-centos.sh b/src/main/distrib/linux/install-service-centos.sh new file mode 100644 index 00000000..19d28c73 --- /dev/null +++ b/src/main/distrib/linux/install-service-centos.sh @@ -0,0 +1,3 @@ +#!/bin/bash +sudo cp service-centos.sh /etc/init.d/gitblit +sudo chkconfig --add gitblit diff --git a/src/main/distrib/linux/install-service-ubuntu.sh b/src/main/distrib/linux/install-service-ubuntu.sh new file mode 100644 index 00000000..72c4e6c2 --- /dev/null +++ b/src/main/distrib/linux/install-service-ubuntu.sh @@ -0,0 +1,3 @@ +#!/bin/bash +sudo cp service-ubuntu.sh /etc/init.d/gitblit +sudo update-rc.d gitblit defaults diff --git a/src/main/distrib/linux/java-proxy-config.sh b/src/main/distrib/linux/java-proxy-config.sh new file mode 100644 index 00000000..5f7a2a27 --- /dev/null +++ b/src/main/distrib/linux/java-proxy-config.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# To set the proxy configuration, specify the following host name and port +#PROXY_HOST= +#PROXY_PORT= + +# To exclude any hosts from proxy configuration such that they directly accessed by Gitblit without passing through the proxy server, append the host name to the following variable using "|" as the separator +NON_PROXY_HOSTS="localhost|127.0.0.*|*.local|192.168.*.*|10.193.*.*" + +### The following should not need to be modified + +JAVA_PROXY_CONFIG="" + +if [ -n "${PROXY_HOST}" -a -n "${PROXY_PORT}" ]; then + + JAVA_PROXY_CONFIG=" -DproxySet=true -Dhttp.proxyHost=${PROXY_HOST} -Dhttp.proxyPort=${PROXY_PORT} -Dhttps.proxyHost=${PROXY_HOST} -Dhttps.proxyPort=${PROXY_PORT} -Dftp.proxyHost=${PROXY_HOST} -Dftp.proxyPort=${PROXY_PORT} " +fi + +if [ -n "${PROXY_HOST}" -a -n "${PROXY_PORT}" -a -n "${NON_PROXY_HOSTS}" ]; then + + JAVA_PROXY_CONFIG="${JAVA_PROXY_CONFIG} -Dhttp.nonProxyHosts=\"${NON_PROXY_HOSTS}\" -Dftp.nonProxyHosts=\"${NON_PROXY_HOSTS}\" " +fi + +export JAVA_PROXY_CONFIG + diff --git a/src/main/distrib/linux/service-centos.sh b/src/main/distrib/linux/service-centos.sh new file mode 100644 index 00000000..04c9a9b4 --- /dev/null +++ b/src/main/distrib/linux/service-centos.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# chkconfig: 3 21 91 +# description: Starts and Stops gitblit +# Source function library. +. /etc/init.d/functions + +# change theses values (default values) +GITBLIT_PATH=/opt/gitblit +GITBLIT_BASE_FOLDER=/opt/gitblit/data +GITBLIT_HTTP_PORT=0 +GITBLIT_HTTPS_PORT=8443 +source ${GITBLIT_PATH}/java-proxy-config.sh +JAVA="java -server -Xmx1024M ${JAVA_PROXY_CONFIG} -Djava.awt.headless=true -jar" + +RETVAL=0 + +case "$1" in + start) + if [ -f $GITBLIT_PATH/gitblit.jar ]; + then + echo $"Starting gitblit server" + cd $GITBLIT_PATH + $JAVA $GITBLIT_PATH/gitblit.jar --httpsPort $GITBLIT_HTTPS_PORT --httpPort $GITBLIT_HTTP_PORT --baseFolder $GITBLIT_BASE_FOLDER > /dev/null & + echo "." + exit $RETVAL + fi + ;; + + stop) + if [ -f $GITBLIT_PATH/gitblit.jar ]; + then + echo $"Stopping gitblit server" + cd $GITBLIT_PATH + $JAVA $GITBLIT_PATH/gitblit.jar --baseFolder $GITBLIT_BASE_FOLDER --stop > /dev/null & + echo "." + exit $RETVAL + fi + ;; + + force-reload|restart) + $0 stop + $0 start + ;; + + *) + echo $"Usage: /etc/init.d/gitblit {start|stop|restart|force-reload}" + exit 1 + ;; +esac + +exit $RETVAL diff --git a/src/main/distrib/linux/service-ubuntu.sh b/src/main/distrib/linux/service-ubuntu.sh new file mode 100644 index 00000000..4ff275d0 --- /dev/null +++ b/src/main/distrib/linux/service-ubuntu.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# chkconfig: 3 21 91 +# Source function library. +. /lib/init/vars.sh +. /lib/lsb/init-functions + +PATH=/sbin:/bin:/usr/bin:/usr/sbin + +# change theses values (default values) +GITBLIT_PATH=/opt/gitblit +GITBLIT_BASE_FOLDER=/opt/gitblit/data +GITBLIT_USER="gitblit" +source ${GITBLIT_PATH}/java-proxy-config.sh +ARGS="-server -Xmx1024M ${JAVA_PROXY_CONFIG} -Djava.awt.headless=true -jar gitblit.jar --baseFolder $GITBLIT_BASE_FOLDER" + +RETVAL=0 + +case "$1" in + start) + if [ -f $GITBLIT_PATH/gitblit.jar ]; + then + echo $"Starting gitblit server" + start-stop-daemon --start --quiet --background --oknodo --make-pidfile --pidfile /var/run/gitblit.pid --exec /usr/bin/java --chuid $GITBLIT_USER --chdir $GITBLIT_PATH -- $ARGS + exit $RETVAL + fi + ;; + + stop) + if [ -f $GITBLIT_PATH/gitblit.jar ]; + then + echo $"Stopping gitblit server" + start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/gitblit.pid + exit $RETVAL + fi + ;; + + force-reload|restart) + $0 stop + $0 start + ;; + + *) + echo $"Usage: /etc/init.d/gitblit {start|stop|restart|force-reload}" + exit 1 + ;; +esac + +exit $RETVAL diff --git a/src/main/distrib/win/add-indexed-branch.cmd b/src/main/distrib/win/add-indexed-branch.cmd new file mode 100644 index 00000000..a7c4451a --- /dev/null +++ b/src/main/distrib/win/add-indexed-branch.cmd @@ -0,0 +1,20 @@ +@REM --------------------------------------------------------------------------
+@REM This is for Lucene search integration.
+@REM
+@REM Allows you to add an indexed branch specification to the repository config
+@REM for all matching repositories in the specified folder.
+@REM
+@REM All repositories are included unless excluded using a --skip parameter.
+@REM --skip supports simple wildcard fuzzy matching however only 1 asterisk is
+@REM allowed per parameter.
+@REM
+@REM Always use forward-slashes for the path separator in your parameters!!
+@REM
+@REM Set FOLDER to the server's git.repositoriesFolder
+@REM Set BRANCH ("default" or fully qualified ref - i.e. refs/heads/master)
+@REM Set EXCLUSIONS for any repositories that you do not want to change
+@REM --------------------------------------------------------------------------
+@SET FOLDER=c:/gitblit/git
+@SET EXCLUSIONS=--skip test.git --skip group/test*
+@SET BRANCH=default
+@java -cp gitblit.jar;"%CD%\ext\*" com.gitblit.AddIndexedBranch --repositoriesFolder %FOLDER% --branch %BRANCH% %EXCLUSIONS% %*
diff --git a/src/main/distrib/win/authority.cmd b/src/main/distrib/win/authority.cmd new file mode 100644 index 00000000..f9a18640 --- /dev/null +++ b/src/main/distrib/win/authority.cmd @@ -0,0 +1 @@ +@java -cp gitblit.jar com.gitblit.authority.Launcher --baseFolder data %*
diff --git a/src/main/distrib/win/gitblit-stop.cmd b/src/main/distrib/win/gitblit-stop.cmd new file mode 100644 index 00000000..34f0f4be --- /dev/null +++ b/src/main/distrib/win/gitblit-stop.cmd @@ -0,0 +1 @@ +@java -jar gitblit.jar --stop --baseFolder data %*
diff --git a/src/main/distrib/win/gitblit.cmd b/src/main/distrib/win/gitblit.cmd new file mode 100644 index 00000000..1a6d7e09 --- /dev/null +++ b/src/main/distrib/win/gitblit.cmd @@ -0,0 +1 @@ +@java -jar gitblit.jar --baseFolder data %*
diff --git a/src/main/distrib/win/installService.cmd b/src/main/distrib/win/installService.cmd new file mode 100644 index 00000000..a684ab21 --- /dev/null +++ b/src/main/distrib/win/installService.cmd @@ -0,0 +1,38 @@ +@REM Install Gitblit as a Windows service.
+
+@REM gitblitw.exe (prunmgr.exe) is a GUI application for monitoring
+@REM and configuring the Gitblit procrun service.
+@REM
+@REM By default this tool launches the service properties dialog
+@REM but it also has some other very useful functionality.
+@REM
+@REM http://commons.apache.org/daemon/procrun.html
+
+@REM arch = x86, amd64, or ia32
+SET ARCH=amd64
+
+@REM Be careful not to introduce trailing whitespace after the ^ characters.
+@REM Use ; or # to separate values in the --StartParams parameter.
+"%CD%\%ARCH%\gitblit.exe" //IS//gitblit ^
+ --DisplayName="gitblit" ^
+ --Description="a pure Java Git solution" ^
+ --Startup=auto ^
+ --LogPath="%CD%\logs" ^
+ --LogLevel=INFO ^
+ --LogPrefix=gitblit ^
+ --StdOutput=auto ^
+ --StdError=auto ^
+ --StartPath="%CD%" ^
+ --StartClass=org.moxie.MxLauncher ^
+ --StartMethod=main ^
+ --StartParams="--storePassword;gitblit;--baseFolder;%CD%\data" ^
+ --StartMode=jvm ^
+ --StopPath="%CD%" ^
+ --StopClass=org.moxie.MxLauncher ^
+ --StopMethod=main ^
+ --StopParams="--stop;--baseFolder;%CD%\data" ^
+ --StopMode=jvm ^
+ --Classpath="%CD%\gitblit.jar" ^
+ --Jvm=auto ^
+ --JvmMx=1024
+
\ No newline at end of file diff --git a/src/main/distrib/win/uninstallService.cmd b/src/main/distrib/win/uninstallService.cmd new file mode 100644 index 00000000..e6c3b98c --- /dev/null +++ b/src/main/distrib/win/uninstallService.cmd @@ -0,0 +1,5 @@ +@REM arch = x86, amd64, or ia32
+SET ARCH=amd64
+
+@REM Delete the gitblit service
+"%CD%\%ARCH%\gitblit.exe" //DS//gitblit
\ No newline at end of file |