Skip to content

Commit 697905c

Browse files
committed
fix for #967 filestore menu for all users
+ Filestore listing filtered by user view permissions + Configuration help for filestore relocated to website files + Added migration example
1 parent 0aecfc1 commit 697905c

File tree

10 files changed

+126
-38
lines changed

10 files changed

+126
-38
lines changed

Diff for: HOME.md

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ This documentation is the source content from which the [Gitblit website](http:/
3333
[[src/site/setup_viewer.mkd]]
3434
[[src/site/administration.mkd]]
3535
[[src/site/setup_scaling.mkd]]
36+
[[src/site/setup_filestore.mkd]]
37+
3638

3739
### Gitblit Tickets
3840

Diff for: build.xml

+1
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@
514514
<page name="mirrors" src="setup_mirrors.mkd" />
515515
<page name="scaling" src="setup_scaling.mkd" />
516516
<page name="fail2ban" src="setup_fail2ban.mkd" />
517+
<page name="filestore (Git LFS)" src="setup_filestore.mkd" />
517518
<divider />
518519
<page name="Gitblit as a viewer" src="setup_viewer.mkd" />
519520
</menu>

Diff for: src/main/java/com/gitblit/manager/FilestoreManager.java

+28-3
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ public class FilestoreManager implements IFilestoreManager {
7777
private final Logger logger = LoggerFactory.getLogger(getClass());
7878

7979
private final IRuntimeManager runtimeManager;
80+
81+
private final IRepositoryManager repositoryManager;
8082

8183
private final IStoredSettings settings;
8284

@@ -93,8 +95,10 @@ public class FilestoreManager implements IFilestoreManager {
9395

9496
@Inject
9597
FilestoreManager(
96-
IRuntimeManager runtimeManager) {
98+
IRuntimeManager runtimeManager,
99+
IRepositoryManager repositoryManager) {
97100
this.runtimeManager = runtimeManager;
101+
this.repositoryManager = repositoryManager;
98102
this.settings = runtimeManager.getSettings();
99103
}
100104

@@ -324,8 +328,29 @@ public FilestoreModel.Status downloadBlob(String oid, UserModel user, Repository
324328
}
325329

326330
@Override
327-
public List<FilestoreModel> getAllObjects() {
328-
return new ArrayList<FilestoreModel>(fileCache.values());
331+
public List<FilestoreModel> getAllObjects(UserModel user) {
332+
333+
final List<RepositoryModel> viewableRepositories = repositoryManager.getRepositoryModels(user);
334+
List<String> viewableRepositoryNames = new ArrayList<String>(viewableRepositories.size());
335+
336+
for (RepositoryModel repository : viewableRepositories) {
337+
viewableRepositoryNames.add(repository.name);
338+
}
339+
340+
if (viewableRepositoryNames.size() == 0) {
341+
return null;
342+
}
343+
344+
final Collection<FilestoreModel> allFiles = fileCache.values();
345+
List<FilestoreModel> userViewableFiles = new ArrayList<FilestoreModel>(allFiles.size());
346+
347+
for (FilestoreModel file : allFiles) {
348+
if (file.isInRepositoryList(viewableRepositoryNames)) {
349+
userViewableFiles.add(file);
350+
}
351+
}
352+
353+
return userViewableFiles;
329354
}
330355

331356
@Override

Diff for: src/main/java/com/gitblit/manager/GitblitManager.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1274,8 +1274,8 @@ public FilestoreModel.Status downloadBlob(String oid, UserModel user, Repository
12741274
}
12751275

12761276
@Override
1277-
public List<FilestoreModel> getAllObjects() {
1278-
return filestoreManager.getAllObjects();
1277+
public List<FilestoreModel> getAllObjects(UserModel user) {
1278+
return filestoreManager.getAllObjects(user);
12791279
}
12801280

12811281
@Override

Diff for: src/main/java/com/gitblit/manager/IFilestoreManager.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public interface IFilestoreManager extends IManager {
3737

3838
FilestoreModel.Status downloadBlob(String oid, UserModel user, RepositoryModel repo, OutputStream streamOut );
3939

40-
List<FilestoreModel> getAllObjects();
40+
List<FilestoreModel> getAllObjects(UserModel user);
4141

4242
File getStorageFolder();
4343

Diff for: src/main/java/com/gitblit/models/FilestoreModel.java

+9
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,15 @@ public synchronized void removeRepository(String repo) {
111111
repositories.remove(repo);
112112
}
113113

114+
public synchronized boolean isInRepositoryList(List<String> repoList) {
115+
for (String name : repositories) {
116+
if (repoList.contains(name)) {
117+
return true;
118+
}
119+
}
120+
return false;
121+
}
122+
114123
public static enum Status {
115124

116125
Deleted(-30),

Diff for: src/main/java/com/gitblit/wicket/pages/FilestorePage.java

+11-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.text.DateFormat;
1919
import java.text.MessageFormat;
2020
import java.text.SimpleDateFormat;
21+
import java.util.ArrayList;
2122
import java.util.List;
2223

2324
import org.apache.commons.io.FileUtils;
@@ -31,27 +32,35 @@
3132
import com.gitblit.Constants;
3233
import com.gitblit.models.FilestoreModel;
3334
import com.gitblit.models.UserModel;
35+
import com.gitblit.wicket.CacheControl;
3436
import com.gitblit.wicket.FilestoreUI;
37+
import com.gitblit.wicket.GitBlitWebSession;
3538
import com.gitblit.wicket.RequiresAdminRole;
3639
import com.gitblit.wicket.WicketUtils;
40+
import com.gitblit.wicket.CacheControl.LastModified;
3741

3842
/**
3943
* Page to display the current status of the filestore.
4044
* Certain errors also displayed to aid in fault finding
4145
*
4246
* @author Paul Martin
4347
*/
44-
@RequiresAdminRole
48+
@CacheControl(LastModified.ACTIVITY)
4549
public class FilestorePage extends RootPage {
4650

4751
public FilestorePage() {
4852
super();
4953
setupPage("", "");
5054

51-
final List<FilestoreModel> files = app().filestore().getAllObjects();
55+
final UserModel user = (GitBlitWebSession.get().getUser() == null) ? UserModel.ANONYMOUS : GitBlitWebSession.get().getUser();
5256
final long nBytesUsed = app().filestore().getFilestoreUsedByteCount();
5357
final long nBytesAvailable = app().filestore().getFilestoreAvailableByteCount();
58+
List<FilestoreModel> files = app().filestore().getAllObjects(user);
5459

60+
if (files == null) {
61+
files = new ArrayList<FilestoreModel>();
62+
}
63+
5564
String message = MessageFormat.format(getString("gb.filestoreStats"), files.size(),
5665
FileUtils.byteCountToDisplaySize(nBytesUsed), FileUtils.byteCountToDisplaySize(nBytesAvailable) );
5766

@@ -64,7 +73,6 @@ public FilestorePage() {
6473
helpLink.add(new Label("helpMessage", getString("gb.filestoreHelp")));
6574
add(helpLink);
6675

67-
6876
DataView<FilestoreModel> filesView = new DataView<FilestoreModel>("fileRow",
6977
new ListDataProvider<FilestoreModel>(files)) {
7078
private static final long serialVersionUID = 1L;

Diff for: src/main/java/com/gitblit/wicket/pages/FilestoreUsage.html

+8-26
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@
1212
<div class="span10 offset1">
1313

1414
<div class="alert alert-danger">
15-
<h3><center>Using the Filestore</center></h3>
15+
<h3><center>Using the filestore</center></h3>
1616
<p>
17-
<strong>All clients intending to use the filestore must first install the <a href="https://git-lfs.github.com/">Git-LFS Client</a> and then run <code>git lfs init</code> to register the hooks globally.</strong><br/>
18-
<i>This version of GitBlit has been verified with Git-LFS client version 0.6.0 which requires Git v1.8.2 or higher.</i>
17+
<strong>All clients intending to use the filestore must first install the <a href="https://git-lfs.github.com/">Git-LFS Client</a> and then run <code>git lfs install</code></strong><br/>
18+
<p>
19+
If using password authentication it is recommended that you configure the <a href="https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage">git credential storage</a> to avoid Git-LFS asking for your password on each file<br/>
20+
On Windows for example: <code>git config --global credential.helper wincred</code>
21+
</p>
1922
</p>
2023
</div>
2124

2225
<h3>Clone</h3>
2326
<p>
24-
Just <code>git clone</code> as usual, no further action is required as GitBlit is configured to use the default Git-LFS end point <code>{repository}/info/lfs/objects/</code>.<br/>
27+
Just <code>git clone</code> as usual, no further action is required as Gitblit is configured to use the default Git-LFS end point <code>{repository}/info/lfs/objects/</code>.<br/>
2528
<i>If the repository uses a 3rd party Git-LFS server you will need to <a href="https://github.com/github/git-lfs/blob/master/docs/spec.md#the-server">manually configure the correct endpoints</a></i>.
2629
</p>
2730

@@ -38,28 +41,7 @@ <h3>Learn more...</h3>
3841
<p><a href="https://github.com/github/git-lfs/blob/master/docs/spec.md">See the current Git-LFS specification for further details</a>.</p>
3942
<br />
4043

41-
<div class="alert alert-warn">
42-
<h3><center>Limitations & Warnings</center></h3>
43-
<p>GitBlit currently provides a server-only implementation of the opensource Git-LFS API, <a href="https://github.com/github/git-lfs/wiki/Implementations">other implementations</a> are available.<br/>
44-
However, until <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=470333">JGit provides Git-LFS client capabilities</a> some GitBlit features may not be fully supported when using the filestore.
45-
Notably:
46-
<ul>
47-
<li>Mirroring a repository that uses Git-LFS - Only the pointer files, not the large files, are mirrored.</li>
48-
<li>Federation - Only the pointer files, not the large files, are transfered.</li>
49-
</ul>
50-
</p>
51-
</div>
52-
53-
<div class="alert alert-info">
54-
<h3><center>GitBlit Configuration</center></h3>
55-
<p>GitBlit provides the following configuration items when using the filestore:
56-
<h4>filestore.storageFolder</h4>
57-
<p>Defines the path on the server where filestore objects are to be saved. This defaults to <code>${baseFolder}/lfs</code></p>
58-
<h4>filestore.maxUploadSize</h4>
59-
<p>Defines the maximum allowable size that can be uploaded to the filestore. Once a file is uploaded it will be unaffected by later changes in this property. This defaults to <code>-1</code> indicating no limits.</p>
60-
</p>
61-
</div>
62-
44+
6345
</div>
6446
</div>
6547
</div>

Diff for: src/main/java/com/gitblit/wicket/pages/RootPage.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,9 @@ public void renderHead(IHeaderResponse response) {
197197
}
198198
navLinks.add(new PageNavLink("gb.repositories", RepositoriesPage.class,
199199
getRootPageParameters()));
200-
if (user.canAdmin()) {
201-
navLinks.add(new PageNavLink("gb.filestore", FilestorePage.class, getRootPageParameters()));
202-
}
200+
201+
navLinks.add(new PageNavLink("gb.filestore", FilestorePage.class, getRootPageParameters()));
202+
203203
navLinks.add(new PageNavLink("gb.activity", ActivityPage.class, getRootPageParameters()));
204204
if (allowLucene) {
205205
navLinks.add(new PageNavLink("gb.search", LuceneSearchPage.class));

Diff for: src/site/setup_filestore.mkd

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
## Configure Git Large File Storage
2+
3+
Gitblit provides a filestore that supports the [Git Large File Storage (LFS) API](https://git-lfs.github.com/).
4+
5+
### Server Configuration
6+
7+
Gitblit is configured to work straight away. However you may want to update the following in `gitblit.properties`:
8+
9+
<table class="table">
10+
<thead>
11+
<tr><th>parameter</th><th>value</th><th>description</th></tr>
12+
</thead>
13+
<tbody>
14+
<tr>
15+
<th>filestore.storageFolder</th><td>${baseFolder}/lfs</td>
16+
<td>The path on the server where filestore objects are to be saved.</td>
17+
</tr>
18+
<tr>
19+
<th>filestore.maxUploadSize</th><td>-1</td>
20+
<td>The maximum allowable size that can be uploaded to the filestore. Once a file is uploaded it will be unaffected by later changes in this property. The default of -1 indicates no limits.</td>
21+
</tr>
22+
</tbody>
23+
</table>
24+
25+
26+
### Limitations
27+
28+
Gitblit currently provides a server-only implementation of the opensource Git LFS API.
29+
30+
1. Files in the filestore are not currently searchable by Lucene.
31+
2. Mirroring a repository that uses Git LFS will only mirror the pointer files, not the large files.
32+
3. Federation - Only the pointer files, not the large files, are transfered.
33+
34+
Items 2 & 3 are pending [JGit Git LFS client capabilities](https://bugs.eclipse.org/bugs/show_bug.cgi?id=470333).
35+
36+
37+
### How does it work?
38+
39+
1. Files that should be handled by Git LFS are defined in the `.gitattributes` file.
40+
2. Git LFS installs a pre-commit hook when installed `git lfs install`.
41+
3. When a commit is made the pre-commit hook replaces the defined Git LFS files with a pointer file containing metadata about the file so that it can be found later.
42+
4. When a commit is pushed, the changeset is sent to the git repository and the large files are sent to the filestore.
43+
44+
For further details check out the [Git LFS specification](https://github.com/github/git-lfs/blob/master/docs/spec.md).
45+
46+
### Convert/Migrate existing repository
47+
48+
It is possible to migrate an existing repository containing large files to one that leverages the filestore. However, commit hash history will be altered.
49+
50+
The following command may be run on a local repository:
51+
52+
git filter-branch --prune-empty --tree-filter '
53+
git lfs track "*.docx" "*.pdf" > /dev/null
54+
git add .gitattributes
55+
git ls-files | xargs -d "\n" git check-attr filter | grep "filter: lfs" | sed -r "s/(.*): filter: lfs/\1/" | xargs -d "\n" -r bash -c "git rm -f --cached \"\$@\"; git add \"\$@\"" bash \
56+
' --tag-name-filter cat -- --all
57+
58+
59+
### Further Considerations
60+
61+
While [other Git LFS implementations are available](https://github.com/github/git-lfs/wiki/Implementations) as there is no current [JGit LFS client capability](https://bugs.eclipse.org/bugs/show_bug.cgi?id=470333), Gitblit will be unable to access them.

0 commit comments

Comments
 (0)