diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main/java/com/gitblit/manager/FederationManager.java | 4 | ||||
-rw-r--r-- | src/main/java/com/gitblit/manager/FilestoreManager.java | 182 | ||||
-rw-r--r-- | src/main/java/com/gitblit/manager/RepositoryManager.java | 7 | ||||
-rw-r--r-- | src/main/java/com/gitblit/servlet/GitblitContext.java | 8 | ||||
-rw-r--r-- | src/main/java/com/gitblit/servlet/RawServlet.java | 23 | ||||
-rw-r--r-- | src/main/java/com/gitblit/utils/FileUtils.java | 11 | ||||
-rw-r--r-- | src/main/java/com/gitblit/wicket/pages/FilestorePage.java | 44 | ||||
-rw-r--r-- | src/main/java/com/gitblit/wicket/pages/ForksPage.java | 3 | ||||
-rw-r--r-- | src/main/java/com/gitblit/wicket/pages/RootPage.java | 16 | ||||
-rw-r--r-- | src/site/roadmap.mkd | 8 | ||||
-rw-r--r-- | src/site/siteindex.mkd | 5 |
11 files changed, 157 insertions, 154 deletions
diff --git a/src/main/java/com/gitblit/manager/FederationManager.java b/src/main/java/com/gitblit/manager/FederationManager.java index f009c1c8..8f68733b 100644 --- a/src/main/java/com/gitblit/manager/FederationManager.java +++ b/src/main/java/com/gitblit/manager/FederationManager.java @@ -367,6 +367,10 @@ public class FederationManager implements IFederationManager { && file.getName().toLowerCase().endsWith(Constants.PROPOSAL_EXT); } }); + if (files == null) { + return list; + } + for (File file : files) { String json = com.gitblit.utils.FileUtils.readContent(file, null); FederationProposal proposal = JsonUtils.fromJsonString(json, diff --git a/src/main/java/com/gitblit/manager/FilestoreManager.java b/src/main/java/com/gitblit/manager/FilestoreManager.java index 33672e4a..fe65e216 100644 --- a/src/main/java/com/gitblit/manager/FilestoreManager.java +++ b/src/main/java/com/gitblit/manager/FilestoreManager.java @@ -15,6 +15,7 @@ */ package com.gitblit.manager; +import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -38,15 +39,13 @@ import java.util.regex.Pattern; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; -import org.bouncycastle.util.io.StreamOverflowException; -import org.eclipse.jetty.io.EofException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.gitblit.IStoredSettings; import com.gitblit.Keys; -import com.gitblit.models.FilestoreModel.Status; import com.gitblit.models.FilestoreModel; +import com.gitblit.models.FilestoreModel.Status; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; import com.gitblit.utils.ArrayUtils; @@ -62,7 +61,7 @@ import com.google.inject.Singleton; * FilestoreManager handles files uploaded via: * + git-lfs * + ticket attachment (TBD) - * + * * Files are stored using their SHA256 hash (as per git-lfs) * If the same file is uploaded through different repositories no additional space is used * Access is controlled through the current repository permissions. @@ -76,47 +75,49 @@ import com.google.inject.Singleton; public class FilestoreManager implements IFilestoreManager { private final Logger logger = LoggerFactory.getLogger(getClass()); - + private final IRuntimeManager runtimeManager; - + private final IStoredSettings settings; - + public static final int UNDEFINED_SIZE = -1; - + private static final String METAFILE = "filestore.json"; - + private static final String METAFILE_TMP = "filestore.json.tmp"; - + protected static final Type METAFILE_TYPE = new TypeToken<Collection<FilestoreModel>>() {}.getType(); - + private Map<String, FilestoreModel > fileCache = new ConcurrentHashMap<String, FilestoreModel>(); - - + + @Inject FilestoreManager( IRuntimeManager runtimeManager) { this.runtimeManager = runtimeManager; this.settings = runtimeManager.getSettings(); } - + @Override public IManager start() { - //Try to load any existing metadata - File metadata = new File(getStorageFolder(), METAFILE); - + // Try to load any existing metadata + File dir = getStorageFolder(); + dir.mkdirs(); + File metadata = new File(dir, METAFILE); + if (metadata.exists()) { Collection<FilestoreModel> items = null; - + Gson gson = gson(); try (FileReader file = new FileReader(metadata)) { items = gson.fromJson(file, METAFILE_TYPE); file.close(); - + } catch (IOException e) { e.printStackTrace(); } - + for(Iterator<FilestoreModel> itr = items.iterator(); itr.hasNext(); ) { FilestoreModel model = itr.next(); fileCache.put(model.oid, model); @@ -128,7 +129,7 @@ public class FilestoreManager implements IFilestoreManager { { logger.info("No filestore metadata file found"); } - + return this; } @@ -143,7 +144,7 @@ public class FilestoreManager implements IFilestoreManager { //NOTE: Assuming SHA256 support only as per git-lfs return Pattern.matches("[a-fA-F0-9]{64}", oid); } - + @Override public FilestoreModel.Status addObject(String oid, long size, UserModel user, RepositoryModel repo) { @@ -155,32 +156,32 @@ public class FilestoreManager implements IFilestoreManager { return Status.Error_Unauthorized; } } - + //Handle object details if (!isValidOid(oid)) { return Status.Error_Invalid_Oid; } - + if (fileCache.containsKey(oid)) { FilestoreModel item = fileCache.get(oid); - + if (!item.isInErrorState() && (size != UNDEFINED_SIZE) && (item.getSize() != size)) { return Status.Error_Size_Mismatch; } - + item.addRepository(repo.name); - + if (item.isInErrorState()) { item.reset(user, size); } } else { - + if (size < 0) {return Status.Error_Invalid_Size; } if ((getMaxUploadSize() != UNDEFINED_SIZE) && (size > getMaxUploadSize())) { return Status.Error_Exceeds_Size_Limit; } - - FilestoreModel model = new FilestoreModel(oid, size, user, repo.name); + + FilestoreModel model = new FilestoreModel(oid, size, user, repo.name); fileCache.put(oid, model); saveFilestoreModel(model); } - + return fileCache.get(oid).getStatus(); } @@ -188,14 +189,14 @@ public class FilestoreManager implements IFilestoreManager { public FilestoreModel.Status uploadBlob(String oid, long size, UserModel user, RepositoryModel repo, InputStream streamIn) { //Access control and object logic - Status state = addObject(oid, size, user, repo); - - if (state != Status.Upload_Pending) { + Status state = addObject(oid, size, user, repo); + + if (state != Status.Upload_Pending) { return state; } - + FilestoreModel model = fileCache.get(oid); - + if (!model.actionUpload(user)) { return Status.Upload_In_Progress; } else { @@ -205,55 +206,55 @@ public class FilestoreManager implements IFilestoreManager { try { file.getParentFile().mkdirs(); file.createNewFile(); - + try (FileOutputStream streamOut = new FileOutputStream(file)) { - + actualSize = IOUtils.copyLarge(streamIn, streamOut); - + streamOut.flush(); streamOut.close(); - + if (model.getSize() != actualSize) { model.setStatus(Status.Error_Size_Mismatch, user); - - logger.warn(MessageFormat.format("Failed to upload blob {0} due to size mismatch, expected {1} got {2}", + + logger.warn(MessageFormat.format("Failed to upload blob {0} due to size mismatch, expected {1} got {2}", oid, model.getSize(), actualSize)); } else { String actualOid = ""; - + try (FileInputStream fileForHash = new FileInputStream(file)) { actualOid = DigestUtils.sha256Hex(fileForHash); fileForHash.close(); } - + if (oid.equalsIgnoreCase(actualOid)) { model.setStatus(Status.Available, user); } else { model.setStatus(Status.Error_Hash_Mismatch, user); - + logger.warn(MessageFormat.format("Failed to upload blob {0} due to hash mismatch, got {1}", oid, actualOid)); } } } } catch (Exception e) { - + model.setStatus(Status.Error_Unknown, user); logger.warn(MessageFormat.format("Failed to upload blob {0}", oid), e); } finally { saveFilestoreModel(model); } - + if (model.isInErrorState()) { file.delete(); model.removeRepository(repo.name); } } - + return model.getStatus(); } - + private FilestoreModel.Status canGetObject(String oid, UserModel user, RepositoryModel repo) { - + //Access Control if (!user.canView(repo)) { if (user == UserModel.ANONYMOUS) { @@ -264,53 +265,53 @@ public class FilestoreManager implements IFilestoreManager { } //Object Logic - if (!isValidOid(oid)) { + if (!isValidOid(oid)) { return Status.Error_Invalid_Oid; } - - if (!fileCache.containsKey(oid)) { + + if (!fileCache.containsKey(oid)) { return Status.Unavailable; } - + FilestoreModel item = fileCache.get(oid); - + if (item.getStatus() == Status.Available) { return Status.Available; } - + return Status.Unavailable; } - + @Override public FilestoreModel getObject(String oid, UserModel user, RepositoryModel repo) { - + if (canGetObject(oid, user, repo) == Status.Available) { return fileCache.get(oid); } - + return null; } @Override public FilestoreModel.Status downloadBlob(String oid, UserModel user, RepositoryModel repo, OutputStream streamOut) { - + //Access control and object logic Status status = canGetObject(oid, user, repo); - - if (status != Status.Available) { + + if (status != Status.Available) { return status; } - + FilestoreModel item = fileCache.get(oid); - + if (streamOut != null) { try (FileInputStream streamIn = new FileInputStream(getStoragePath(oid))) { - + IOUtils.copyLarge(streamIn, streamOut); - + streamOut.flush(); streamIn.close(); - } catch (EofException e) { + } catch (EOFException e) { logger.error(MessageFormat.format("Client aborted connection for {0}", oid), e); return Status.Error_Unexpected_Stream_End; } catch (Exception e) { @@ -318,7 +319,7 @@ public class FilestoreManager implements IFilestoreManager { return Status.Error_Unknown; } } - + return item.getStatus(); } @@ -331,7 +332,7 @@ public class FilestoreManager implements IFilestoreManager { public File getStorageFolder() { return runtimeManager.getFileOrFolder(Keys.filestore.storageFolder, "${baseFolder}/lfs"); } - + @Override public File getStoragePath(String oid) { return new File(getStorageFolder(), oid.substring(0, 2).concat("/").concat(oid.substring(2))); @@ -341,41 +342,41 @@ public class FilestoreManager implements IFilestoreManager { public long getMaxUploadSize() { return settings.getLong(Keys.filestore.maxUploadSize, -1); } - + @Override public long getFilestoreUsedByteCount() { Iterator<FilestoreModel> iterator = fileCache.values().iterator(); long total = 0; - + while (iterator.hasNext()) { - + FilestoreModel item = iterator.next(); if (item.getStatus() == Status.Available) { total += item.getSize(); } } - + return total; } - + @Override public long getFilestoreAvailableByteCount() { - + try { return Files.getFileStore(getStorageFolder().toPath()).getUsableSpace(); } catch (IOException e) { logger.error(MessageFormat.format("Failed to retrive available space in Filestore {0}", e)); } - + return UNDEFINED_SIZE; }; - + private synchronized void saveFilestoreModel(FilestoreModel model) { - + File metaFile = new File(getStorageFolder(), METAFILE); File metaFileTmp = new File(getStorageFolder(), METAFILE_TMP); boolean isNewFile = false; - + try { if (!metaFile.exists()) { metaFile.getParentFile().mkdirs(); @@ -383,33 +384,33 @@ public class FilestoreManager implements IFilestoreManager { isNewFile = true; } FileUtils.copyFile(metaFile, metaFileTmp); - + } catch (IOException e) { logger.error("Writing filestore model to file {0}, {1}", METAFILE, e); } - + try (RandomAccessFile fs = new RandomAccessFile(metaFileTmp, "rw")) { - + if (isNewFile) { fs.writeBytes("["); } else { fs.seek(fs.length() - 1); fs.writeBytes(","); } - + fs.writeBytes(gson().toJson(model)); fs.writeBytes("]"); - + fs.close(); - + } catch (IOException e) { logger.error("Writing filestore model to file {0}, {1}", METAFILE_TMP, e); } - + try { if (metaFileTmp.exists()) { FileUtils.copyFile(metaFileTmp, metaFile); - + metaFileTmp.delete(); } else { logger.error("Writing filestore model to file {0}", METAFILE); @@ -419,14 +420,15 @@ public class FilestoreManager implements IFilestoreManager { logger.error("Writing filestore model to file {0}, {1}", METAFILE, e); } } - + /* * Intended for testing purposes only */ + @Override public void clearFilestoreCache() { fileCache.clear(); } - + private static Gson gson(ExclusionStrategy... strategies) { GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Date.class, new GmtDateTypeAdapter()); @@ -435,5 +437,5 @@ public class FilestoreManager implements IFilestoreManager { } return builder.create(); } - + } diff --git a/src/main/java/com/gitblit/manager/RepositoryManager.java b/src/main/java/com/gitblit/manager/RepositoryManager.java index 027ba23b..e2e4de68 100644 --- a/src/main/java/com/gitblit/manager/RepositoryManager.java +++ b/src/main/java/com/gitblit/manager/RepositoryManager.java @@ -1113,9 +1113,16 @@ public class RepositoryManager implements IRepositoryManager { // find the root, cached String key = getRepositoryKey(repository); RepositoryModel model = repositoryListCache.get(key); + if (model == null) { + return null; + } + while (model.originRepository != null) { String originKey = getRepositoryKey(model.originRepository); model = repositoryListCache.get(originKey); + if (model == null) { + return null; + } } ForkModel root = getForkModelFromCache(model.name); return root; diff --git a/src/main/java/com/gitblit/servlet/GitblitContext.java b/src/main/java/com/gitblit/servlet/GitblitContext.java index fb8f6b9d..750da796 100644 --- a/src/main/java/com/gitblit/servlet/GitblitContext.java +++ b/src/main/java/com/gitblit/servlet/GitblitContext.java @@ -24,6 +24,7 @@ import java.io.OutputStream; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; +import java.util.Set; import javax.naming.Context; import javax.naming.InitialContext; @@ -455,7 +456,12 @@ public class GitblitContext extends GuiceServletContextListener { } protected void extractResources(ServletContext context, String path, File toDir) { - for (String resource : context.getResourcePaths(path)) { + Set<String> resources = context.getResourcePaths(path); + if (resources == null) { + logger.warn("There are no WAR resources to extract from {}", path); + return; + } + for (String resource : resources) { // extract the resource to the directory if it does not exist File f = new File(toDir, resource.substring(path.length())); if (!f.exists()) { diff --git a/src/main/java/com/gitblit/servlet/RawServlet.java b/src/main/java/com/gitblit/servlet/RawServlet.java index 1d2724bc..81793bc7 100644 --- a/src/main/java/com/gitblit/servlet/RawServlet.java +++ b/src/main/java/com/gitblit/servlet/RawServlet.java @@ -166,23 +166,14 @@ public class RawServlet extends HttpServlet { } // determine repository and resource from url - String repository = ""; + String repository = path; Repository r = null; - int offset = 0; - while (r == null) { - int slash = path.indexOf('/', offset); - if (slash == -1) { - repository = path; - } else { - repository = path.substring(0, slash); - } - offset = ( slash + 1 ); + int terminator = repository.length(); + do { + repository = repository.substring(0, terminator); r = repositoryManager.getRepository(repository, false); - if (repository.equals(path)) { - // either only repository in url or no repository found - break; - } - } + terminator = repository.lastIndexOf('/'); + } while (r == null && terminator > -1 ); ServletContext context = request.getSession().getServletContext(); @@ -242,7 +233,7 @@ public class RawServlet extends HttpServlet { try { String ext = StringUtils.getFileExtension(file).toLowerCase(); - String contentType = quickContentTypes.get(ext); + String contentType = file.charAt(0) == '.' ? "text/plain" : quickContentTypes.get(ext); if (contentType == null) { List<String> exts = runtimeManager.getSettings().getStrings(Keys.web.prettyPrintExtensions); diff --git a/src/main/java/com/gitblit/utils/FileUtils.java b/src/main/java/com/gitblit/utils/FileUtils.java index e7f01045..ad2509d0 100644 --- a/src/main/java/com/gitblit/utils/FileUtils.java +++ b/src/main/java/com/gitblit/utils/FileUtils.java @@ -140,9 +140,10 @@ public class FileUtils { public static String readContent(File file, String lineEnding) {
StringBuilder sb = new StringBuilder();
InputStreamReader is = null;
+ BufferedReader reader = null;
try {
is = new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8"));
- BufferedReader reader = new BufferedReader(is);
+ reader = new BufferedReader(is);
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
@@ -154,6 +155,14 @@ public class FileUtils { System.err.println("Failed to read content of " + file.getAbsolutePath());
t.printStackTrace();
} finally {
+ if (reader != null){
+ try {
+ reader.close();
+ } catch (IOException ioe) {
+ System.err.println("Failed to close file " + file.getAbsolutePath());
+ ioe.printStackTrace();
+ }
+ }
if (is != null) {
try {
is.close();
diff --git a/src/main/java/com/gitblit/wicket/pages/FilestorePage.java b/src/main/java/com/gitblit/wicket/pages/FilestorePage.java index 5f103edd..97d5f25b 100644 --- a/src/main/java/com/gitblit/wicket/pages/FilestorePage.java +++ b/src/main/java/com/gitblit/wicket/pages/FilestorePage.java @@ -29,51 +29,41 @@ import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.markup.repeater.data.ListDataProvider; import com.gitblit.Constants; -import com.gitblit.Keys; import com.gitblit.models.FilestoreModel; import com.gitblit.models.UserModel; import com.gitblit.wicket.FilestoreUI; -import com.gitblit.wicket.GitBlitWebSession; +import com.gitblit.wicket.RequiresAdminRole; import com.gitblit.wicket.WicketUtils; /** * Page to display the current status of the filestore. - * Certain errors also displayed to aid in fault finding + * Certain errors also displayed to aid in fault finding * * @author Paul Martin - * - * */ +@RequiresAdminRole public class FilestorePage extends RootPage { public FilestorePage() { super(); setupPage("", ""); - // check to see if we should display a login message - boolean authenticateView = app().settings().getBoolean(Keys.web.authenticateViewPages, true); - if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) { - String messageSource = app().settings().getString(Keys.web.loginMessage, "gitblit"); - return; - } - + final List<FilestoreModel> files = app().filestore().getAllObjects(); final long nBytesUsed = app().filestore().getFilestoreUsedByteCount(); final long nBytesAvailable = app().filestore().getFilestoreAvailableByteCount(); - - // Load the markdown welcome message - String messageSource = app().settings().getString(Keys.web.repositoriesMessage, "gitblit"); - String message = MessageFormat.format(getString("gb.filestoreStats"), files.size(), - FileUtils.byteCountToDisplaySize(nBytesUsed), FileUtils.byteCountToDisplaySize(nBytesAvailable) ); + + String message = MessageFormat.format(getString("gb.filestoreStats"), files.size(), + FileUtils.byteCountToDisplaySize(nBytesUsed), FileUtils.byteCountToDisplaySize(nBytesAvailable) ); Component repositoriesMessage = new Label("repositoriesMessage", message) .setEscapeModelStrings(false).setVisible(message.length() > 0); - + add(repositoriesMessage); - + BookmarkablePageLink<Void> helpLink = new BookmarkablePageLink<Void>("filestoreHelp", FilestoreUsage.class); helpLink.add(new Label("helpMessage", getString("gb.filestoreHelp"))); add(helpLink); - + DataView<FilestoreModel> filesView = new DataView<FilestoreModel>("fileRow", new ListDataProvider<FilestoreModel>(files)) { @@ -89,26 +79,26 @@ public class FilestorePage extends RootPage { @Override public void populateItem(final Item<FilestoreModel> item) { final FilestoreModel entry = item.getModelObject(); - + DateFormat dateFormater = new SimpleDateFormat(Constants.ISO8601); - + UserModel user = app().users().getUserModel(entry.getChangedBy()); user = user == null ? UserModel.ANONYMOUS : user; - + Label icon = FilestoreUI.getStatusIcon("status", entry); item.add(icon); item.add(new Label("on", dateFormater.format(entry.getChangedOn()))); item.add(new Label("by", user.getDisplayName())); - + item.add(new Label("oid", entry.oid)); - item.add(new Label("size", FileUtils.byteCountToDisplaySize(entry.getSize()))); - + item.add(new Label("size", FileUtils.byteCountToDisplaySize(entry.getSize()))); + WicketUtils.setAlternatingBackground(item, counter); counter++; } }; - + add(filesView); } } diff --git a/src/main/java/com/gitblit/wicket/pages/ForksPage.java b/src/main/java/com/gitblit/wicket/pages/ForksPage.java index 93fc9faf..045f5f7e 100644 --- a/src/main/java/com/gitblit/wicket/pages/ForksPage.java +++ b/src/main/java/com/gitblit/wicket/pages/ForksPage.java @@ -136,6 +136,9 @@ public class ForksPage extends RepositoryPage { protected List<FlatFork> flatten(ForkModel node, int level) {
List<FlatFork> list = new ArrayList<FlatFork>();
+ if (node == null) {
+ return list;
+ }
list.add(new FlatFork(node.repository, level));
if (!node.isLeaf()) {
for (ForkModel fork : node.forks) {
diff --git a/src/main/java/com/gitblit/wicket/pages/RootPage.java b/src/main/java/com/gitblit/wicket/pages/RootPage.java index b48f7224..6ed5a357 100644 --- a/src/main/java/com/gitblit/wicket/pages/RootPage.java +++ b/src/main/java/com/gitblit/wicket/pages/RootPage.java @@ -185,6 +185,11 @@ public abstract class RootPage extends BasePage { // navigation links List<NavLink> navLinks = new ArrayList<NavLink>(); if (!authenticateView || (authenticateView && isLoggedIn)) { + UserModel user = UserModel.ANONYMOUS; + if (isLoggedIn) { + user = GitBlitWebSession.get().getUser(); + } + navLinks.add(new PageNavLink(isLoggedIn ? "gb.myDashboard" : "gb.dashboard", MyDashboardPage.class, getRootPageParameters())); if (isLoggedIn && app().tickets().isReady()) { @@ -192,7 +197,9 @@ public abstract class RootPage extends BasePage { } navLinks.add(new PageNavLink("gb.repositories", RepositoriesPage.class, getRootPageParameters())); - navLinks.add(new PageNavLink("gb.filestore", FilestorePage.class, getRootPageParameters())); + if (user.canAdmin()) { + navLinks.add(new PageNavLink("gb.filestore", FilestorePage.class, getRootPageParameters())); + } navLinks.add(new PageNavLink("gb.activity", ActivityPage.class, getRootPageParameters())); if (allowLucene) { navLinks.add(new PageNavLink("gb.search", LuceneSearchPage.class)); @@ -202,11 +209,6 @@ public abstract class RootPage extends BasePage { addDropDownMenus(navLinks); } - UserModel user = UserModel.ANONYMOUS; - if (isLoggedIn) { - user = GitBlitWebSession.get().getUser(); - } - // add nav link extensions List<NavLinkExtension> extensions = app().plugins().getExtensions(NavLinkExtension.class); for (NavLinkExtension ext : extensions) { @@ -568,7 +570,7 @@ public abstract class RootPage extends BasePage { char[] password = RootPage.this.password.getObject().toCharArray(); HttpServletRequest request = ((WebRequest)RequestCycle.get().getRequest()).getHttpServletRequest(); - + UserModel user = app().authentication().authenticate(username, password, request.getRemoteAddr()); if (user == null) { error(getString("gb.invalidUsernameOrPassword")); diff --git a/src/site/roadmap.mkd b/src/site/roadmap.mkd deleted file mode 100644 index ea643218..00000000 --- a/src/site/roadmap.mkd +++ /dev/null @@ -1,8 +0,0 @@ -## Roadmap
-
-This is not exactly a formal roadmap but it is a priority list of what might be implemented in future releases.
-This list is volatile and may not reflect what will be in the next release.
-
-* Add support for Project owners/administrators (ticket-75)
-* Add Project create/update pages
-* Integrate improvements for git-flow (ticket-55)
diff --git a/src/site/siteindex.mkd b/src/site/siteindex.mkd index ae954bfa..aec5c42a 100644 --- a/src/site/siteindex.mkd +++ b/src/site/siteindex.mkd @@ -23,12 +23,9 @@ <tbody>
<tr><th>License</th><td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a></td></tr>
<tr><th>Sources</th><td><a href="${project.scmUrl}">GitHub</a></td></tr>
- <tr><th>Issues</th><td><a href="${project.issuesUrl}">GoogleCode</a></td></tr>
+ <tr><th>Issues</th><td><a href="${project.issuesUrl}">GitHub</a></td></tr>
<tr><th>Discussion</th><td><a href="${project.forumUrl}">Gitblit Group</a></td></tr>
- <tr><th>Google+</th><td><a href="${project.socialNetworkUrl}">Gitblit+</a></td></tr>
<tr><th>Ohloh</th><td><a target="_top" href="http://www.ohloh.net/p/gitblit"><img border="0" width="100" height="16" src="http://www.ohloh.net/p/gitblit/widgets/project_thin_badge.gif" alt="Ohloh project report for Gitblit" /></a></td></tr>
- <tr><th>Donations</th><td>If you enjoy Gitblit and want to support its development, please consider making a donation to <a href="http://www.stjude.org">St. Jude Children's Research Hospital</a>.
- <a href="http://www.stjude.org" alt="St. Jude Children's Research Hospital"><img style="padding-top:10px;" src="stjude_150x150.gif"/></a></td></tr>
</tbody>
</table>
</div>
|