use of org.locationtech.geogig.api.Platform in project GeoGig by boundlessgeo.
the class SquashOp method _call.
/**
* Executes the squash operation.
*
* @return the new head after modifying the history squashing commits
* @see org.locationtech.geogig.api.AbstractGeoGigOp#call()
*/
@Override
protected ObjectId _call() {
Preconditions.checkNotNull(since);
Preconditions.checkNotNull(until);
GraphDatabase graphDb = graphDatabase();
Repository repository = repository();
Platform platform = platform();
final Optional<Ref> currHead = command(RefParse.class).setName(Ref.HEAD).call();
Preconditions.checkState(currHead.isPresent(), "Repository has no HEAD, can't squash.");
Preconditions.checkState(currHead.get() instanceof SymRef, "Can't squash from detached HEAD");
final SymRef headRef = (SymRef) currHead.get();
final String currentBranch = headRef.getTarget();
Preconditions.checkState(index().isClean() && workingTree().isClean(), "You must have a clean working tree and index to perform a squash.");
Optional<ObjectId> ancestor = command(FindCommonAncestor.class).setLeft(since).setRight(until).call();
Preconditions.checkArgument(ancestor.isPresent(), "'since' and 'until' command do not have a common ancestor");
Preconditions.checkArgument(ancestor.get().equals(since.getId()), "Commits provided in wrong order");
Preconditions.checkArgument(!since.getParentIds().isEmpty(), "'since' commit has no parents");
// we get a a list of commits to apply on top of the squashed commits
List<RevCommit> commits = getCommitsAfterUntil();
ImmutableSet<Ref> refs = command(ForEachRef.class).setPrefixFilter(Ref.HEADS_PREFIX).call();
// we create a list of all parents of those squashed commits, in case they are
// merge commits. The resulting commit will have all these parents
//
// While iterating the set of commits to squash, we check that there are no branch starting
// points among them. Any commit with more than one child causes an exception to be thrown,
// since the squash operation does not support squashing those commits
Iterator<RevCommit> toSquash = command(LogOp.class).setSince(since.getParentIds().get(0)).setUntil(until.getId()).setFirstParentOnly(true).call();
List<ObjectId> firstParents = Lists.newArrayList();
List<ObjectId> secondaryParents = Lists.newArrayList();
final List<ObjectId> squashedIds = Lists.newArrayList();
RevCommit commitToSquash = until;
while (toSquash.hasNext()) {
commitToSquash = toSquash.next();
squashedIds.add(commitToSquash.getId());
Preconditions.checkArgument(graphDb.getChildren(commitToSquash.getId()).size() < 2, "The commits to squash include a branch starting point. Squashing that type of commit is not supported.");
for (Ref ref : refs) {
// In case a branch has been created but no commit has been made on it and the
// starting commit has just one child
Preconditions.checkArgument(!ref.getObjectId().equals(commitToSquash.getId()) || ref.getObjectId().equals(currHead.get().getObjectId()) || commitToSquash.getParentIds().size() > 1, "The commits to squash include a branch starting point. Squashing that type of commit is not supported.");
}
ImmutableList<ObjectId> parentIds = commitToSquash.getParentIds();
for (int i = 1; i < parentIds.size(); i++) {
secondaryParents.add(parentIds.get(i));
}
firstParents.add(parentIds.get(0));
}
Preconditions.checkArgument(since.equals(commitToSquash), "Cannot reach 'since' from 'until' commit through first parentage");
// We do the same check in the children commits
for (RevCommit commit : commits) {
Preconditions.checkArgument(graphDb.getChildren(commit.getId()).size() < 2, "The commits after the ones to squash include a branch starting point. This scenario is not supported.");
for (Ref ref : refs) {
// In case a branch has been created but no commit has been made on it
Preconditions.checkArgument(!ref.getObjectId().equals(commit.getId()) || ref.getObjectId().equals(currHead.get().getObjectId()) || commit.getParentIds().size() > 1, "The commits after the ones to squash include a branch starting point. This scenario is not supported.");
}
}
ObjectId newHead;
// rewind the head
newHead = since.getParentIds().get(0);
command(ResetOp.class).setCommit(Suppliers.ofInstance(newHead)).setMode(ResetMode.HARD).call();
// add the current HEAD as first parent of the resulting commit
// parents.add(0, newHead);
// Create new commit
List<ObjectId> parents = Lists.newArrayList();
parents.addAll(firstParents);
parents.addAll(secondaryParents);
ObjectId endTree = until.getTreeId();
CommitBuilder builder = new CommitBuilder(until);
Collection<ObjectId> filteredParents = Collections2.filter(parents, new Predicate<ObjectId>() {
@Override
public boolean apply(@Nullable ObjectId id) {
return !squashedIds.contains(id);
}
});
builder.setParentIds(Lists.newArrayList(filteredParents));
builder.setTreeId(endTree);
if (message == null) {
message = since.getMessage();
}
long timestamp = platform.currentTimeMillis();
builder.setMessage(message);
builder.setCommitter(resolveCommitter());
builder.setCommitterEmail(resolveCommitterEmail());
builder.setCommitterTimestamp(timestamp);
builder.setCommitterTimeZoneOffset(platform.timeZoneOffset(timestamp));
builder.setAuthorTimestamp(until.getAuthor().getTimestamp());
RevCommit newCommit = builder.build();
repository.objectDatabase().put(newCommit);
newHead = newCommit.getId();
ObjectId newTreeId = newCommit.getTreeId();
command(UpdateRef.class).setName(currentBranch).setNewValue(newHead).call();
command(UpdateSymRef.class).setName(Ref.HEAD).setNewValue(currentBranch).call();
workingTree().updateWorkHead(newTreeId);
index().updateStageHead(newTreeId);
// now put the other commits after the squashed one
newHead = addCommits(commits, currentBranch, newHead);
return newHead;
}
use of org.locationtech.geogig.api.Platform in project GeoGig by boundlessgeo.
the class SquashOp method addCommits.
private ObjectId addCommits(List<RevCommit> commits, String currentBranch, final ObjectId squashedId) {
final Platform platform = platform();
final Map<ObjectId, ObjectId> replacedCommits = Maps.newHashMap();
replacedCommits.put(until.getId(), squashedId);
ObjectId head = squashedId;
for (RevCommit commit : commits) {
CommitBuilder builder = new CommitBuilder(commit);
Collection<ObjectId> parents = Collections2.transform(commit.getParentIds(), new Function<ObjectId, ObjectId>() {
@Override
@Nullable
public ObjectId apply(@Nullable ObjectId id) {
if (replacedCommits.containsKey(id)) {
return replacedCommits.get(id);
} else {
return id;
}
}
});
builder.setParentIds(Lists.newArrayList(parents));
builder.setTreeId(commit.getTreeId());
long timestamp = platform.currentTimeMillis();
builder.setCommitterTimestamp(timestamp);
builder.setCommitterTimeZoneOffset(platform.timeZoneOffset(timestamp));
RevCommit newCommit = builder.build();
replacedCommits.put(commit.getId(), newCommit.getId());
objectDatabase().put(newCommit);
head = newCommit.getId();
ObjectId newTreeId = newCommit.getTreeId();
command(UpdateRef.class).setName(currentBranch).setNewValue(head).call();
command(UpdateSymRef.class).setName(Ref.HEAD).setNewValue(currentBranch).call();
workingTree().updateWorkHead(newTreeId);
index().updateStageHead(newTreeId);
}
return head;
}
use of org.locationtech.geogig.api.Platform in project GeoGig by boundlessgeo.
the class RepositoryTestCase method createInjector.
protected Context createInjector() {
Platform testPlatform = createPlatform();
GlobalContextBuilder.builder = new TestContextBuilder(testPlatform);
return GlobalContextBuilder.builder.build();
}
use of org.locationtech.geogig.api.Platform in project GeoGig by boundlessgeo.
the class ParseTimestamp method _call.
/**
* Parses a string with a timestamp
*
* @return a Long with the timestamp represented by the specified string
*/
@Override
protected Long _call() {
Preconditions.checkState(string != null, "String has not been set.");
try {
// see if it is a timestamp in milisecs
Long milis = new Long(string);
return milis;
} catch (NumberFormatException e) {
}
SimpleDateFormat formatter;
final Platform platform = platform();
if (string.equals("yesterday")) {
// from current time
try {
formatter = new SimpleDateFormat("dd/MM/yyyy");
Date today = new Date(platform.currentTimeMillis());
long todayOnlyDate = formatter.parse(formatter.format(today)).getTime();
long millisecsInOneDay = 60 * 60 * 24 * 1000;
long yesterday = todayOnlyDate - millisecsInOneDay;
return yesterday;
} catch (ParseException e) {
// shouldn't reach this
}
}
if (string.equals("today")) {
try {
formatter = new SimpleDateFormat("dd/MM/yyyy");
Date today = new Date(platform.currentTimeMillis());
long todayOnlyDate = formatter.parse(formatter.format(today)).getTime();
return todayOnlyDate;
} catch (ParseException e) {
// shouldn't reach this
}
}
// parse it as a git-like time reference
String[] tokens = string.split("\\.");
if (tokens.length % 2 != 0) {
if (tokens[tokens.length - 1].toLowerCase().equals("ago")) {
long currentTime = platform.currentTimeMillis();
int i;
for (i = 0; i < tokens.length - 1; i++) {
try {
double number = Double.parseDouble(tokens[i]);
i++;
String s = tokens[i].toLowerCase();
if (s.endsWith("s")) {
s = s.substring(0, s.length() - 1);
}
if (units.containsKey(s)) {
currentTime -= units.get(s) * number;
} else {
break;
}
} catch (Exception e) {
break;
}
}
if (i == tokens.length - 1) {
return currentTime;
}
}
}
// finally, try to parse it as a Date object
try {
long time = javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar(string).toGregorianCalendar().getTimeInMillis();
return time;
} catch (DatatypeConfigurationException e) {
} catch (IllegalArgumentException e) {
}
throw new IllegalArgumentException("Invalid timestamp string: " + string);
}
use of org.locationtech.geogig.api.Platform in project GeoGig by boundlessgeo.
the class DiffTreeTest method setUp.
@Before
public void setUp() throws Exception {
File workingDirectory = tempFolder.newFolder("mockWorkingDir");
Platform testPlatform = new TestPlatform(workingDirectory);
Context injector = Guice.createInjector(Modules.override(new GeogigModule()).with(new MemoryModule(testPlatform))).getInstance(Context.class);
geogit = new GeoGIG(injector);
assertNotNull(geogit.getOrCreateRepository());
diffTree = geogit.command(DiffTree.class);
SimpleFeatureType ft = DataUtilities.createType("points", "sp:String,ip:Integer,pp:Point:srid=3857");
revtype = RevFeatureTypeImpl.build(ft);
metadataId = revtype.getId();
geogit.getContext().objectDatabase().put(revtype);
}
Aggregations