Search in sources :

Example 26 with Platform

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;
}
Also used : Platform(org.locationtech.geogig.api.Platform) GraphDatabase(org.locationtech.geogig.storage.GraphDatabase) CommitBuilder(org.locationtech.geogig.api.CommitBuilder) UpdateSymRef(org.locationtech.geogig.api.plumbing.UpdateSymRef) UpdateSymRef(org.locationtech.geogig.api.plumbing.UpdateSymRef) SymRef(org.locationtech.geogig.api.SymRef) RevCommit(org.locationtech.geogig.api.RevCommit) ObjectId(org.locationtech.geogig.api.ObjectId) UpdateRef(org.locationtech.geogig.api.plumbing.UpdateRef) Repository(org.locationtech.geogig.repository.Repository) UpdateRef(org.locationtech.geogig.api.plumbing.UpdateRef) ForEachRef(org.locationtech.geogig.api.plumbing.ForEachRef) UpdateSymRef(org.locationtech.geogig.api.plumbing.UpdateSymRef) Ref(org.locationtech.geogig.api.Ref) SymRef(org.locationtech.geogig.api.SymRef) FindCommonAncestor(org.locationtech.geogig.api.plumbing.FindCommonAncestor)

Example 27 with Platform

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;
}
Also used : UpdateSymRef(org.locationtech.geogig.api.plumbing.UpdateSymRef) Platform(org.locationtech.geogig.api.Platform) ObjectId(org.locationtech.geogig.api.ObjectId) CommitBuilder(org.locationtech.geogig.api.CommitBuilder) UpdateRef(org.locationtech.geogig.api.plumbing.UpdateRef) Nullable(javax.annotation.Nullable) RevCommit(org.locationtech.geogig.api.RevCommit)

Example 28 with Platform

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();
}
Also used : TestPlatform(org.locationtech.geogig.api.TestPlatform) Platform(org.locationtech.geogig.api.Platform)

Example 29 with Platform

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);
}
Also used : Platform(org.locationtech.geogig.api.Platform) Date(java.util.Date) DatatypeConfigurationException(javax.xml.datatype.DatatypeConfigurationException) ParseException(java.text.ParseException) DatatypeConfigurationException(javax.xml.datatype.DatatypeConfigurationException) ParseException(java.text.ParseException) SimpleDateFormat(java.text.SimpleDateFormat)

Example 30 with Platform

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);
}
Also used : Context(org.locationtech.geogig.api.Context) TestPlatform(org.locationtech.geogig.api.TestPlatform) Platform(org.locationtech.geogig.api.Platform) SimpleFeatureType(org.opengis.feature.simple.SimpleFeatureType) TestPlatform(org.locationtech.geogig.api.TestPlatform) File(java.io.File) GeogigModule(org.locationtech.geogig.di.GeogigModule) MemoryModule(org.locationtech.geogig.api.MemoryModule) GeoGIG(org.locationtech.geogig.api.GeoGIG) Before(org.junit.Before)

Aggregations

Platform (org.locationtech.geogig.api.Platform)41 File (java.io.File)27 TestPlatform (org.locationtech.geogig.api.TestPlatform)10 Before (org.junit.Before)7 Context (org.locationtech.geogig.api.Context)7 GeogigModule (org.locationtech.geogig.di.GeogigModule)6 GeoGIG (org.locationtech.geogig.api.GeoGIG)5 ObjectId (org.locationtech.geogig.api.ObjectId)5 Repository (org.locationtech.geogig.repository.Repository)5 IOException (java.io.IOException)4 UpdateRef (org.locationtech.geogig.api.plumbing.UpdateRef)4 UpdateSymRef (org.locationtech.geogig.api.plumbing.UpdateSymRef)4 CommitBuilder (org.locationtech.geogig.api.CommitBuilder)3 DefaultPlatform (org.locationtech.geogig.api.DefaultPlatform)3 MemoryModule (org.locationtech.geogig.api.MemoryModule)3 RevCommit (org.locationtech.geogig.api.RevCommit)3 RevTree (org.locationtech.geogig.api.RevTree)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 URL (java.net.URL)2 UnsupportedTerminal (jline.UnsupportedTerminal)2