code: public NodeData getVersionableAncestor() throws RepositoryException
     {
        checkValid();
        NodeData node = nodeData();
        NodeTypeDataManager ntman = session.getWorkspace().getNodeTypesHolder();
  
        while (node.getParentIdentifier() != null)
        {
           if (ntman.isNodeType(Constants.MIX_VERSIONABLE, node.getPrimaryTypeName(), node.getMixinTypeNames()))
           {
              // mix:versionable has own jcr:isCheckedOut state
              return node;
           }
           else
           {
              // check on deeper ancestor
              NodeData ancestor = (NodeData)dataManager.getItemData(node.getParentIdentifier());
              if (ancestor == null)
              {
                 throw new RepositoryException("Parent not found for "
                    + locationFactory.createJCRPath(node.getQPath()).getAsString(false) + ". Parent id "
                    + node.getParentIdentifier());
              }
              else
              {
                 node = ancestor;
              }
           }
        }
  
        return null;
     }
docs: Get nearest versionable ancestor NodeData. If the node is mix:versionable this NodeData will be
  returned.
  
  @return NodeData of versionable ancestor or null if no versionable ancestor exists.
  @throws RepositoryException
  if error