public boolean delete(GeogigTransaction transaction, Feature f) throws Exception { final WorkingTree workTree = (transaction != null ? transaction.workingTree() : repo.workingTree()); Name name = f.getType().getName(); String localPart = name.getLocalPart(); String id = f.getIdentifier().getID(); boolean existed = workTree.delete(localPart, id); return existed; }
/** Inserts the feature to the index but does not stages it to be committed */ public ObjectId insert(GeogigTransaction transaction, Feature f) throws Exception { final WorkingTree workTree = (transaction != null ? transaction.workingTree() : repo.workingTree()); Name name = f.getType().getName(); String parentPath = name.getLocalPart(); Node ref = workTree.insert(parentPath, f); ObjectId objectId = ref.getObjectId(); return objectId; }
/** Inserts the Feature to the index and stages it to be committed. */ public ObjectId insertAndAdd(GeogigTransaction transaction, Feature f) throws Exception { ObjectId objectId = insert(transaction, f); if (transaction != null) { transaction.command(AddOp.class).call(); } else { geogig.command(AddOp.class).call(); } return objectId; }
private boolean repositoryChanged(Ref ref) { Optional<Ref> transactionOriginal = transaction .command(RefParse.class) .setName(ref.getName().replace("refs/", "orig/refs/")) .call(); if (transactionOriginal.isPresent()) { return !ref.getObjectId().equals(transactionOriginal.get().getObjectId()); } // Ref was created in transaction and on the repo return true; }
/** * Deletes a feature from the index * * @param f * @return * @throws Exception */ public boolean deleteAndAdd(GeogigTransaction transaction, Feature f) throws Exception { boolean existed = delete(transaction, f); if (existed) { if (transaction != null) { transaction.command(AddOp.class).call(); } else { geogig.command(AddOp.class).call(); } } return existed; }
/** * Ends the current transaction by either committing the changes or discarding them depending on * whether cancel is true or not. * * @return Boolean - true if the transaction was successfully closed */ @Override protected Boolean _call() { Preconditions.checkState( !(context instanceof GeogigTransaction), "Cannot end a transaction within a transaction!"); Preconditions.checkArgument(transaction != null, "No transaction was specified!"); try { if (!cancel) { updateRefs(); } } finally { // Erase old refs transaction.close(); } // Success return true; }
private ImmutableSet<Ref> getChangedRefs() { ImmutableSet<Ref> changedRefs = transaction.getChangedRefs(); return changedRefs; }
private void updateRefs() { final Optional<Ref> currHead = command(RefParse.class).setName(Ref.HEAD).call(); final String currentBranch; if (currHead.isPresent() && currHead.get() instanceof SymRef) { currentBranch = ((SymRef) currHead.get()).getTarget(); } else { currentBranch = ""; } ImmutableSet<Ref> changedRefs = getChangedRefs(); // Lock the repository try { refDatabase().lock(); } catch (TimeoutException e) { Throwables.propagate(e); } try { // Update refs for (Ref ref : changedRefs) { if (!ref.getName().startsWith(Ref.REFS_PREFIX)) { continue; } Ref updatedRef = ref; Optional<Ref> repoRef = command(RefParse.class).setName(ref.getName()).call(); if (repoRef.isPresent() && repositoryChanged(repoRef.get())) { if (rebase) { // Try to rebase transaction.command(CheckoutOp.class).setSource(ref.getName()).setForce(true).call(); try { transaction .command(RebaseOp.class) .setUpstream(Suppliers.ofInstance(repoRef.get().getObjectId())) .call(); } catch (RebaseConflictsException e) { Throwables.propagate(e); } updatedRef = transaction.command(RefParse.class).setName(ref.getName()).call().get(); } else { // sync transactions have to use merge to prevent divergent history transaction.command(CheckoutOp.class).setSource(ref.getName()).setForce(true).call(); try { transaction .command(MergeOp.class) .setAuthor(authorName.orNull(), authorEmail.orNull()) .addCommit(Suppliers.ofInstance(repoRef.get().getObjectId())) .call(); } catch (NothingToCommitException e) { // The repo commit is already in our history, this is a fast // forward. } updatedRef = transaction.command(RefParse.class).setName(ref.getName()).call().get(); } } LOGGER.debug( String.format( "commit %s %s -> %s", ref.getName(), ref.getObjectId(), updatedRef.getObjectId())); command(UpdateRef.class) .setName(ref.getName()) .setNewValue(updatedRef.getObjectId()) .call(); if (currentBranch.equals(ref.getName())) { // Update HEAD, WORK_HEAD and STAGE_HEAD command(UpdateSymRef.class).setName(Ref.HEAD).setNewValue(ref.getName()).call(); command(UpdateRef.class) .setName(Ref.WORK_HEAD) .setNewValue(updatedRef.getObjectId()) .call(); command(UpdateRef.class) .setName(Ref.STAGE_HEAD) .setNewValue(updatedRef.getObjectId()) .call(); } } // TODO: What happens if there are unstaged or staged changes in the repository when // a transaction is committed? } finally { // Unlock the repository refDatabase().unlock(); } }