use of com.gitblit.models.RepositoryCommit in project gitblit by gitblit.
the class CommitCache method getCommits.
/**
* Get all commits for the specified repository:branch since a specific date.
* These commits may be retrieved from the cache if the sinceDate is after
* the cacheCutoffDate.
*
* @param repositoryName
* @param repository
* @param branch
* @param sinceDate
* @return a list of commits
*/
public List<RepositoryCommit> getCommits(String repositoryName, Repository repository, String branch, Date sinceDate) {
long start = System.nanoTime();
Date cacheCutoffDate = getCutoffDate();
List<RepositoryCommit> list;
if (cacheDays > 0 && (sinceDate.getTime() >= cacheCutoffDate.getTime())) {
// request fits within the cache window
String repoKey = repositoryName.toLowerCase();
String branchKey = branch.toLowerCase();
RevCommit tip = JGitUtils.getCommit(repository, branch);
Date tipDate = JGitUtils.getCommitDate(tip);
ObjectCache<List<RepositoryCommit>> repoCache;
synchronized (cache) {
repoCache = cache.get(repoKey);
if (repoCache == null) {
repoCache = new ObjectCache<>();
cache.put(repoKey, repoCache);
}
}
synchronized (repoCache) {
List<RepositoryCommit> commits;
if (!repoCache.hasCurrent(branchKey, tipDate)) {
commits = repoCache.getObject(branchKey);
if (ArrayUtils.isEmpty(commits)) {
// we don't have any cached commits for this branch, reload
commits = get(repositoryName, repository, branch, cacheCutoffDate);
repoCache.updateObject(branchKey, tipDate, commits);
logger.debug(MessageFormat.format("parsed {0} commits from {1}:{2} since {3,date,yyyy-MM-dd} in {4} msecs", commits.size(), repositoryName, branch, cacheCutoffDate, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)));
} else {
// incrementally update cache since the last cached commit
ObjectId sinceCommit = commits.get(0).getId();
List<RepositoryCommit> incremental = get(repositoryName, repository, branch, sinceCommit);
logger.info(MessageFormat.format("incrementally added {0} commits to cache for {1}:{2} in {3} msecs", incremental.size(), repositoryName, branch, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)));
incremental.addAll(commits);
repoCache.updateObject(branchKey, tipDate, incremental);
commits = incremental;
}
} else {
// cache is current
commits = repoCache.getObject(branchKey);
// evict older commits outside the cache window
commits = reduce(commits, cacheCutoffDate);
// update cache
repoCache.updateObject(branchKey, tipDate, commits);
}
if (sinceDate.equals(cacheCutoffDate)) {
// Mustn't hand out the cached list; that's not thread-safe
list = new ArrayList<>(commits);
} else {
// reduce the commits to those since the specified date
list = reduce(commits, sinceDate);
}
}
logger.debug(MessageFormat.format("retrieved {0} commits from cache of {1}:{2} since {3,date,yyyy-MM-dd} in {4} msecs", list.size(), repositoryName, branch, sinceDate, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)));
} else {
// not caching or request outside cache window
list = get(repositoryName, repository, branch, sinceDate);
logger.debug(MessageFormat.format("parsed {0} commits from {1}:{2} since {3,date,yyyy-MM-dd} in {4} msecs", list.size(), repositoryName, branch, sinceDate, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)));
}
return list;
}
use of com.gitblit.models.RepositoryCommit in project gitblit by gitblit.
the class ActivityUtils method getRecentActivity.
/**
* Gets the recent activity from the repositories for the last daysBack days
* on the specified branch.
*
* @param settings
* the runtime settings
* @param repositoryManager
* the repository manager
* @param models
* the list of repositories to query
* @param daysBack
* the number of days back from Now to collect
* @param objectId
* the branch to retrieve. If this value is null or empty all
* branches are queried.
* @param timezone
* the timezone for aggregating commits
* @return
*/
public static List<Activity> getRecentActivity(IStoredSettings settings, IRepositoryManager repositoryManager, List<RepositoryModel> models, int daysBack, String objectId, TimeZone timezone) {
// Activity panel shows last daysBack of activity across all
// repositories.
Date thresholdDate = new Date(System.currentTimeMillis() - daysBack * TimeUtils.ONEDAY);
// Build a map of DailyActivity from the available repositories for the
// specified threshold date.
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
df.setTimeZone(timezone);
Calendar cal = Calendar.getInstance();
cal.setTimeZone(timezone);
// aggregate author exclusions
Set<String> authorExclusions = new TreeSet<String>();
authorExclusions.addAll(settings.getStrings(Keys.web.metricAuthorExclusions));
for (RepositoryModel model : models) {
if (!ArrayUtils.isEmpty(model.metricAuthorExclusions)) {
authorExclusions.addAll(model.metricAuthorExclusions);
}
}
Map<String, Activity> activity = new HashMap<String, Activity>();
for (RepositoryModel model : models) {
if (!model.isShowActivity()) {
// skip this repository
continue;
}
if (model.hasCommits && model.lastChange.after(thresholdDate)) {
if (model.isCollectingGarbage) {
continue;
}
Repository repository = repositoryManager.getRepository(model.name);
List<String> branches = new ArrayList<String>();
if (StringUtils.isEmpty(objectId)) {
for (RefModel local : JGitUtils.getLocalBranches(repository, true, -1)) {
if (!local.getDate().after(thresholdDate)) {
// branch not recently updated
continue;
}
branches.add(local.getName());
}
} else {
branches.add(objectId);
}
for (String branch : branches) {
String shortName = branch;
if (shortName.startsWith(Constants.R_HEADS)) {
shortName = shortName.substring(Constants.R_HEADS.length());
}
List<RepositoryCommit> commits = CommitCache.instance().getCommits(model.name, repository, branch, thresholdDate);
if (model.maxActivityCommits > 0 && commits.size() > model.maxActivityCommits) {
// trim commits to maximum count
commits = commits.subList(0, model.maxActivityCommits);
}
for (RepositoryCommit commit : commits) {
Date date = commit.getCommitDate();
String dateStr = df.format(date);
if (!activity.containsKey(dateStr)) {
// Normalize the date to midnight
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Activity a = new Activity(cal.getTime());
a.excludeAuthors(authorExclusions);
activity.put(dateStr, a);
}
activity.get(dateStr).addCommit(commit);
}
}
// close the repository
repository.close();
}
}
List<Activity> recentActivity = new ArrayList<Activity>(activity.values());
return recentActivity;
}
use of com.gitblit.models.RepositoryCommit in project gitblit by gitblit.
the class ReflogPanel method setup.
protected void setup(List<RefLogEntry> changes) {
ListDataProvider<RefLogEntry> dp = new ListDataProvider<RefLogEntry>(changes);
DataView<RefLogEntry> changeView = new DataView<RefLogEntry>("change", dp) {
private static final long serialVersionUID = 1L;
@Override
public void populateItem(final Item<RefLogEntry> changeItem) {
final RefLogEntry change = changeItem.getModelObject();
String dateFormat = app().settings().getString(Keys.web.datetimestampLongFormat, "EEEE, MMMM d, yyyy HH:mm Z");
TimeZone timezone = getTimeZone();
DateFormat df = new SimpleDateFormat(dateFormat);
df.setTimeZone(timezone);
Calendar cal = Calendar.getInstance(timezone);
String fullRefName = change.getChangedRefs().get(0);
String shortRefName = fullRefName;
String ticketId = null;
boolean isTag = false;
boolean isTicket = false;
if (shortRefName.startsWith(Constants.R_TICKET)) {
ticketId = fullRefName.substring(Constants.R_TICKET.length());
shortRefName = MessageFormat.format(getString("gb.ticketN"), ticketId);
isTicket = true;
} else if (shortRefName.startsWith(Constants.R_HEADS)) {
shortRefName = shortRefName.substring(Constants.R_HEADS.length());
} else if (shortRefName.startsWith(Constants.R_TAGS)) {
shortRefName = shortRefName.substring(Constants.R_TAGS.length());
isTag = true;
}
String fuzzydate;
TimeUtils tu = getTimeUtils();
Date changeDate = change.date;
if (TimeUtils.isToday(changeDate, timezone)) {
fuzzydate = tu.today();
} else if (TimeUtils.isYesterday(changeDate, timezone)) {
fuzzydate = tu.yesterday();
} else {
// calculate a fuzzy time ago date
cal.setTime(changeDate);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Date date = cal.getTime();
fuzzydate = getTimeUtils().timeAgo(date);
}
changeItem.add(new Label("whenChanged", fuzzydate + ", " + df.format(changeDate)));
Label changeIcon = new Label("changeIcon");
if (Type.DELETE.equals(change.getChangeType(fullRefName))) {
WicketUtils.setCssClass(changeIcon, "iconic-trash-stroke");
} else if (isTag) {
WicketUtils.setCssClass(changeIcon, "iconic-tag");
} else if (isTicket) {
WicketUtils.setCssClass(changeIcon, "fa fa-ticket");
} else {
WicketUtils.setCssClass(changeIcon, "iconic-upload");
}
changeItem.add(changeIcon);
if (change.user.username.equals(change.user.emailAddress) && change.user.emailAddress.indexOf('@') > -1) {
// username is an email address - 1.2.1 push log bug
changeItem.add(new Label("whoChanged", change.user.getDisplayName()));
} else if (change.user.username.equals(UserModel.ANONYMOUS.username)) {
// anonymous change
changeItem.add(new Label("whoChanged", getString("gb.anonymousUser")));
} else {
// link to user account page
changeItem.add(new LinkPanel("whoChanged", null, change.user.getDisplayName(), UserPage.class, WicketUtils.newUsernameParameter(change.user.username)));
}
boolean isDelete = false;
boolean isRewind = false;
String what;
String by = null;
switch(change.getChangeType(fullRefName)) {
case CREATE:
if (isTag) {
// new tag
what = getString("gb.pushedNewTag");
} else {
// new branch
what = getString("gb.pushedNewBranch");
}
break;
case DELETE:
isDelete = true;
if (isTag) {
what = getString("gb.deletedTag");
} else {
what = getString("gb.deletedBranch");
}
break;
case UPDATE_NONFASTFORWARD:
isRewind = true;
default:
what = MessageFormat.format(change.getCommitCount() > 1 ? getString("gb.pushedNCommitsTo") : getString("gb.pushedOneCommitTo"), change.getCommitCount());
if (change.getAuthorCount() == 1) {
by = MessageFormat.format(getString("gb.byOneAuthor"), change.getAuthorIdent().getName());
} else {
by = MessageFormat.format(getString("gb.byNAuthors"), change.getAuthorCount());
}
break;
}
changeItem.add(new Label("whatChanged", what));
changeItem.add(new Label("byAuthors", by).setVisible(!StringUtils.isEmpty(by)));
changeItem.add(new Label("refRewind", getString("gb.rewind")).setVisible(isRewind));
if (isDelete) {
// can't link to deleted ref
changeItem.add(new Label("refChanged", shortRefName));
} else if (isTag) {
// link to tag
changeItem.add(new LinkPanel("refChanged", null, shortRefName, TagPage.class, WicketUtils.newObjectParameter(change.repository, fullRefName)));
} else if (isTicket) {
// link to ticket
changeItem.add(new LinkPanel("refChanged", null, shortRefName, TicketsPage.class, WicketUtils.newObjectParameter(change.repository, ticketId)));
} else {
// link to tree
changeItem.add(new LinkPanel("refChanged", null, shortRefName, TreePage.class, WicketUtils.newObjectParameter(change.repository, fullRefName)));
}
int maxCommitCount = 5;
List<RepositoryCommit> commits = change.getCommits();
if (commits.size() > maxCommitCount) {
commits = new ArrayList<RepositoryCommit>(commits.subList(0, maxCommitCount));
}
// compare link
String compareLinkText = null;
if ((change.getCommitCount() <= maxCommitCount) && (change.getCommitCount() > 1)) {
compareLinkText = MessageFormat.format(getString("gb.viewComparison"), commits.size());
} else if (change.getCommitCount() > maxCommitCount) {
int diff = change.getCommitCount() - maxCommitCount;
compareLinkText = MessageFormat.format(diff > 1 ? getString("gb.nMoreCommits") : getString("gb.oneMoreCommit"), diff);
}
if (StringUtils.isEmpty(compareLinkText)) {
changeItem.add(new Label("compareLink").setVisible(false));
} else {
String endRangeId = change.getNewId(fullRefName);
String startRangeId = change.getOldId(fullRefName);
changeItem.add(new LinkPanel("compareLink", null, compareLinkText, ComparePage.class, WicketUtils.newRangeParameter(change.repository, startRangeId, endRangeId)));
}
ListDataProvider<RepositoryCommit> cdp = new ListDataProvider<RepositoryCommit>(commits);
DataView<RepositoryCommit> commitsView = new DataView<RepositoryCommit>("commit", cdp) {
private static final long serialVersionUID = 1L;
@Override
public void populateItem(final Item<RepositoryCommit> commitItem) {
final RepositoryCommit commit = commitItem.getModelObject();
// author gravatar
commitItem.add(new AvatarImage("commitAuthor", commit.getAuthorIdent(), null, 16, false));
// merge icon
if (commit.getParentCount() > 1) {
commitItem.add(WicketUtils.newImage("commitIcon", "commit_merge_16x16.png"));
} else {
commitItem.add(WicketUtils.newBlankImage("commitIcon"));
}
// short message
String shortMessage = commit.getShortMessage();
String trimmedMessage = shortMessage;
if (commit.getRefs() != null && commit.getRefs().size() > 0) {
trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS);
} else {
trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG);
}
LinkPanel shortlog = new LinkPanel("commitShortMessage", "list", trimmedMessage, CommitPage.class, WicketUtils.newObjectParameter(change.repository, commit.getName()));
if (!shortMessage.equals(trimmedMessage)) {
WicketUtils.setHtmlTooltip(shortlog, shortMessage);
}
commitItem.add(shortlog);
// commit hash link
int hashLen = app().settings().getInteger(Keys.web.shortCommitIdLength, 6);
LinkPanel commitHash = new LinkPanel("hashLink", null, commit.getName().substring(0, hashLen), CommitPage.class, WicketUtils.newObjectParameter(change.repository, commit.getName()));
WicketUtils.setCssClass(commitHash, "shortsha1");
WicketUtils.setHtmlTooltip(commitHash, commit.getName());
commitItem.add(commitHash);
}
};
changeItem.add(commitsView);
}
};
add(changeView);
}
use of com.gitblit.models.RepositoryCommit in project gitblit by gitblit.
the class DashboardPage method addCharts.
/**
* Creates the daily activity line chart, the active repositories pie chart,
* and the active authors pie chart
*
* @param recentChanges
* @param authorExclusions
* @param daysBack
*/
protected void addCharts(Fragment frag, List<DailyLogEntry> recentChanges, Set<String> authorExclusions, int daysBack) {
// activity metrics
Map<String, Metric> repositoryMetrics = new HashMap<String, Metric>();
Map<String, Metric> authorMetrics = new HashMap<String, Metric>();
// aggregate repository and author metrics
int totalCommits = 0;
for (RefLogEntry change : recentChanges) {
// aggregate repository metrics
String repository = StringUtils.stripDotGit(change.repository);
if (!repositoryMetrics.containsKey(repository)) {
repositoryMetrics.put(repository, new Metric(repository));
}
repositoryMetrics.get(repository).count += 1;
for (RepositoryCommit commit : change.getCommits()) {
totalCommits++;
String author = StringUtils.removeNewlines(commit.getAuthorIdent().getName());
String authorName = author.toLowerCase();
String authorEmail = StringUtils.removeNewlines(commit.getAuthorIdent().getEmailAddress()).toLowerCase();
if (!authorExclusions.contains(authorName) && !authorExclusions.contains(authorEmail)) {
if (!authorMetrics.containsKey(author)) {
authorMetrics.put(author, new Metric(author));
}
authorMetrics.get(author).count += 1;
}
}
}
String headerPattern;
if (daysBack == 1) {
// today
if (totalCommits == 0) {
headerPattern = getString("gb.todaysActivityNone");
} else {
headerPattern = getString("gb.todaysActivityStats");
}
} else {
// multiple days
if (totalCommits == 0) {
headerPattern = getString("gb.recentActivityNone");
} else {
headerPattern = getString("gb.recentActivityStats");
}
}
frag.add(new Label("feedheader", MessageFormat.format(headerPattern, daysBack, totalCommits, authorMetrics.size())));
if (app().settings().getBoolean(Keys.web.generateActivityGraph, true)) {
// build google charts
Charts charts = new Flotr2Charts();
// active repositories pie chart
Chart chart = charts.createPieChart("chartRepositories", getString("gb.activeRepositories"), getString("gb.repository"), getString("gb.commits"));
for (Metric metric : repositoryMetrics.values()) {
chart.addValue(metric.name, metric.count);
}
chart.setShowLegend(false);
String url = urlFor(SummaryPage.class, null).toString() + "?r=";
chart.setClickUrl(url);
charts.addChart(chart);
// active authors pie chart
chart = charts.createPieChart("chartAuthors", getString("gb.activeAuthors"), getString("gb.author"), getString("gb.commits"));
for (Metric metric : authorMetrics.values()) {
chart.addValue(metric.name, metric.count);
}
chart.setShowLegend(false);
charts.addChart(chart);
add(new HeaderContributor(charts));
frag.add(new Fragment("charts", "chartsFragment", this));
} else {
frag.add(new Label("charts").setVisible(false));
}
}
use of com.gitblit.models.RepositoryCommit in project gitblit by gitblit.
the class RefLogUtils method getDailyLog.
/**
* Returns a commit log grouped by day.
*
* @param repositoryName
* @param repository
* @param minimumDate
* @param offset
* @param maxCount
* if < 0, all entries are returned.
* @param the timezone to use when aggregating commits by date
* @return a list of grouped commit log entries
*/
public static List<DailyLogEntry> getDailyLog(String repositoryName, Repository repository, Date minimumDate, int offset, int maxCount, TimeZone timezone) {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
df.setTimeZone(timezone);
Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(repository);
Map<String, DailyLogEntry> tags = new HashMap<String, DailyLogEntry>();
Map<String, DailyLogEntry> pulls = new HashMap<String, DailyLogEntry>();
Map<String, DailyLogEntry> dailydigests = new HashMap<String, DailyLogEntry>();
String linearParent = null;
for (RefModel local : JGitUtils.getLocalBranches(repository, true, -1)) {
if (!local.getDate().after(minimumDate)) {
// branch not recently updated
continue;
}
String branch = local.getName();
List<RepositoryCommit> commits = CommitCache.instance().getCommits(repositoryName, repository, branch, minimumDate);
linearParent = null;
for (RepositoryCommit commit : commits) {
if (linearParent != null) {
if (!commit.getName().equals(linearParent)) {
// only follow linear branch commits
continue;
}
}
Date date = commit.getCommitDate();
String dateStr = df.format(date);
if (!dailydigests.containsKey(dateStr)) {
dailydigests.put(dateStr, new DailyLogEntry(repositoryName, date));
}
DailyLogEntry digest = dailydigests.get(dateStr);
if (commit.getParentCount() == 0) {
linearParent = null;
digest.updateRef(branch, ReceiveCommand.Type.CREATE);
} else {
linearParent = commit.getParents()[0].getId().getName();
digest.updateRef(branch, ReceiveCommand.Type.UPDATE, linearParent, commit.getName());
}
RepositoryCommit repoCommit = digest.addCommit(commit);
if (repoCommit != null) {
List<RefModel> matchedRefs = allRefs.get(commit.getId());
repoCommit.setRefs(matchedRefs);
if (!ArrayUtils.isEmpty(matchedRefs)) {
for (RefModel ref : matchedRefs) {
if (ref.getName().startsWith(Constants.R_TAGS)) {
// treat tags as special events in the log
if (!tags.containsKey(dateStr)) {
UserModel tagUser = newUserModelFrom(ref.getAuthorIdent());
Date tagDate = commit.getAuthorIdent().getWhen();
tags.put(dateStr, new DailyLogEntry(repositoryName, tagDate, tagUser));
}
RefLogEntry tagEntry = tags.get(dateStr);
tagEntry.updateRef(ref.getName(), ReceiveCommand.Type.CREATE);
RepositoryCommit rc = repoCommit.clone(ref.getName());
tagEntry.addCommit(rc);
} else if (ref.getName().startsWith(Constants.R_PULL)) {
// treat pull requests as special events in the log
if (!pulls.containsKey(dateStr)) {
UserModel commitUser = newUserModelFrom(ref.getAuthorIdent());
Date commitDate = commit.getAuthorIdent().getWhen();
pulls.put(dateStr, new DailyLogEntry(repositoryName, commitDate, commitUser));
}
RefLogEntry pullEntry = pulls.get(dateStr);
pullEntry.updateRef(ref.getName(), ReceiveCommand.Type.CREATE);
RepositoryCommit rc = repoCommit.clone(ref.getName());
pullEntry.addCommit(rc);
}
}
}
}
}
}
List<DailyLogEntry> list = new ArrayList<DailyLogEntry>(dailydigests.values());
list.addAll(tags.values());
//list.addAll(pulls.values());
Collections.sort(list);
return list;
}
Aggregations