Using Object Versioning

Go to concepts

This page describes how to set up Object Versioning and gives examples of using Object Versioning.

Setting up Object Versioning

The following sections show how to turn Object Versioning on and off using the gsutil tool, the JSON API, and the XML API. Object Versioning cannot currently be controlled using the Google Cloud Console.

Enabling Object Versioning

To enable Object Versioning on a bucket:

gsutil

Use the gsutil versioning set on command:

gsutil versioning set on gs://[BUCKET_NAME]

Where [BUCKET_NAME] is the name of the relevant bucket. For example, my-bucket.

Code samples

C++

For more information, see the Cloud Storage C++ API reference documentation.

namespace gcs = google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string bucket_name) {
  StatusOr<gcs::BucketMetadata> original =
      client.GetBucketMetadata(bucket_name);

  if (!original) throw std::runtime_error(original.status().message());
  StatusOr<gcs::BucketMetadata> patched_metadata = client.PatchBucket(
      bucket_name,
      gcs::BucketMetadataPatchBuilder().SetVersioning(
          gcs::BucketVersioning{true}),
      gcs::IfMetagenerationMatch(original->metageneration()));

  if (!patched_metadata) {
    throw std::runtime_error(patched_metadata.status().message());
  }

  if (patched_metadata->versioning().has_value()) {
    std::cout << "Object versioning for bucket " << bucket_name << " is "
              << (patched_metadata->versioning()->enabled ? "enabled"
                                                          : "disabled")
              << "\n";
  } else {
    std::cout << "Object versioning for bucket " << bucket_name
              << " is disabled.\n";
  }
}

Java

For more information, see the Cloud Storage Java API reference documentation.

import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

public class EnableBucketVersioning {
  public static void enableBucketVersioning(String projectId, String bucketName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    Bucket bucket = storage.get(bucketName);
    bucket.toBuilder().setVersioningEnabled(true).build().update();

    System.out.println("Versioning is now enabled for bucket " + bucketName);
  }
}

REST APIs

JSON API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Create a .json file that contains the following information:

    {
      "versioning": {
        "enabled": true
      }
    }
  3. Use cURL to call the JSON API with a PATCH Bucket request:

    curl -X PATCH --data-binary @[JSON_FILE_NAME].json \
      -H "Authorization: Bearer [OAUTH2_TOKEN]" \
      -H "Content-Type: application/json" \
      "https://storage.googleapis.com/storage/v1/b/[BUCKET_NAME]?fields=versioning"

    Where:

    • [JSON_FILE_NAME] is the file you created in Step 2.
    • [OAUTH2_TOKEN] is the access token you created in Step 1.
    • [BUCKET_NAME] is the name of the relevant bucket. For example, my-bucket.

XML API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Create an .xml file that contains the following information:

    <VersioningConfiguration>
      <Status>Enabled</Status>
    </VersioningConfiguration>
  3. Use cURL to call the XML API, with a PUT Bucket request and versioning query string parameter:

    curl -X PUT --data-binary @[XML_FILE_NAME].xml \
      -H "Authorization: Bearer [OAUTH2_TOKEN]" \
      "https://storage.googleapis.com/[BUCKET_NAME]?versioning"

    Where:

    • [XML_FILE_NAME] is the file you created in Step 2.
    • [OAUTH2_TOKEN] is the access token you created in Step 1.
    • [BUCKET_NAME] is the name of the relevant bucket. For example, my-bucket.

Once Object Versioning is enabled, Cloud Storage creates a noncurrent version of an object each time the live version of the object is overwritten or deleted.

Disabling Object Versioning

To disable Object Versioning on a bucket:

gsutil

Use the gsutil versioning set off command:

gsutil versioning set off gs://[BUCKET_NAME]

Where [BUCKET_NAME] is the name of the relevant bucket. For example, my-bucket.

Code samples

C++

For more information, see the Cloud Storage C++ API reference documentation.

namespace gcs = google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string bucket_name) {
  StatusOr<gcs::BucketMetadata> original =
      client.GetBucketMetadata(bucket_name);

  if (!original) throw std::runtime_error(original.status().message());
  StatusOr<gcs::BucketMetadata> patched_metadata = client.PatchBucket(
      bucket_name,
      gcs::BucketMetadataPatchBuilder().SetVersioning(
          gcs::BucketVersioning{false}),
      gcs::IfMetagenerationMatch(original->metageneration()));

  if (!patched_metadata) {
    throw std::runtime_error(patched_metadata.status().message());
  }

  if (patched_metadata->versioning().has_value()) {
    std::cout << "Object versioning for bucket " << bucket_name << " is "
              << (patched_metadata->versioning()->enabled ? "enabled"
                                                          : "disabled")
              << "\n";
  } else {
    std::cout << "Object versioning for bucket " << bucket_name
              << " is disabled.\n";
  }
}

Java

For more information, see the Cloud Storage Java API reference documentation.

import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

public class DisableBucketVersioning {
  public static void disableBucketVersioning(String projectId, String bucketName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    Bucket bucket = storage.get(bucketName);
    bucket.toBuilder().setVersioningEnabled(false).build().update();

    System.out.println("Versioning is now disabled for bucket " + bucketName);
  }
}

REST APIs

JSON API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Create a .json file that contains the following information:

    {
      "versioning": {
        "enabled": false
      }
    }
  3. Use cURL to call the JSON API with a PATCH Bucket request:

    curl -X PATCH --data-binary @[JSON_FILE_NAME].json \
      -H "Authorization: Bearer [OAUTH2_TOKEN]" \
      -H "Content-Type: application/json" \
      "https://storage.googleapis.com/storage/v1/b/[BUCKET_NAME]?fields=versioning"

    Where:

    • [JSON_FILE_NAME] is the file you created in Step 2.
    • [OAUTH2_TOKEN] is the access token you created in Step 1.
    • [BUCKET_NAME] is the name of the relevant bucket. For example, my-bucket.

XML API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Create an .xml file that contains the following information:

    <VersioningConfiguration>
      <Status>Suspended</Status>
    </VersioningConfiguration>
  3. Use cURL to call the XML API, with a PUT Bucket request and versioning query string parameter:

    curl -X PUT --data-binary @[XML_FILE_NAME].xml \
      -H "Authorization: Bearer [OAUTH2_TOKEN]" \
      "https://storage.googleapis.com/[BUCKET_NAME]?versioning"

    Where:

    • [XML_FILE_NAME] is the file you created in Step 2.
    • [OAUTH2_TOKEN] is the access token you created in Step 1.
    • [BUCKET_NAME] is the name of the relevant bucket. For example, my-bucket.

Checking whether Object Versioning is enabled

To check whether Object Versioning is enabled on a bucket:

gsutil

Use the gsutil versioning get command:

gsutil versioning get gs://[BUCKET_NAME]

Where [BUCKET_NAME] is the name of the relevant bucket. For example, my-bucket.

The response looks like the following if Object Versioning is enabled:

gs://[BUCKET_NAME]: Enabled

REST APIs

JSON API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Use cURL to call the JSON API with a GET Bucket request:

    curl -X GET \
      -H "Authorization: Bearer [OAUTH2_TOKEN]" \
      "https://storage.googleapis.com/storage/v1/b/[BUCKET_NAME]?fields=versioning"

    Where:

    • [OAUTH2_TOKEN] is the access token you created in Step 1.
    • [BUCKET_NAME] is the name of the relevant bucket. For example, my-bucket.

XML API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Use cURL to call the XML API, with a GET Bucket request and versioning query string parameter:

    curl -X GET \
      -H "Authorization: Bearer [OAUTH2_TOKEN]" \
      "https://storage.googleapis.com/[BUCKET_NAME]?versioning"

    Where:

    • [OAUTH2_TOKEN] is the access token you created in Step 1.
    • [BUCKET_NAME] is the name of the relevant bucket. For example, my-bucket.

Working with versioned objects

The following sections show how to work with versioned objects. For an in-depth example of working with Object Versioning, see Object Versioning example.

Listing noncurrent object versions

To list both live and noncurrent versions of an object and view their generation numbers:

gsutil

Use the gsutil ls -a command:

gsutil ls -a gs://[BUCKET_NAME]

Where [BUCKET_NAME] is the name of the relevant bucket. For example, my-bucket.

The response looks like the following example:

gs://[BUCKET_NAME]/[OBJECT_NAME1]#[GENERATION_NUMBER1]
gs://[BUCKET_NAME]/[OBJECT_NAME1]#[GENERATION_NUMBER2]
gs://[BUCKET_NAME]/[OBJECT_NAME1]#[GENERATION_NUMBER3]
...

Code samples

C++

For more information, see the Cloud Storage C++ API reference documentation.

namespace gcs = google::cloud::storage;
[](gcs::Client client, std::string bucket_name) {
  for (auto&& object_metadata :
       client.ListObjects(bucket_name, gcs::Versions{true})) {
    if (!object_metadata) {
      throw std::runtime_error(object_metadata.status().message());
    }

    std::cout << "bucket_name=" << object_metadata->bucket()
              << ", object_name=" << object_metadata->name()
              << ", generation=" << object_metadata->generation() << "\n";
  }
}

Java

For more information, see the Cloud Storage Java API reference documentation.

import com.google.api.gax.paging.Page;
import com.google.cloud.storage.Blob;
import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

public class ListObjectsWithOldVersions {
  public static void listObjectsWithOldVersions(String projectId, String bucketName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";
    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    Bucket bucket = storage.get(bucketName);
    Page<Blob> blobs = bucket.list(Storage.BlobListOption.versions(true));

    for (Blob blob : blobs.iterateAll()) {
      System.out.println(blob.getName() + "," + blob.getGeneration());
    }
  }
}

REST APIs

JSON API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Use cURL to call the JSON API with a LIST Object request:

    curl -X GET \
      -H "Authorization: Bearer [OAUTH2_TOKEN]" \
      "https://storage.googleapis.com/storage/v1/b/[BUCKET_NAME]/o?versions=true"

    Where:

    • [OAUTH2_TOKEN] is the access token you created in Step 1.
    • [BUCKET_NAME] is the name of the relevant bucket. For example, my-bucket.

Noncurrent versions of objects have a timeDeleted property.

XML API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Use cURL to call the XML API, with a GET Bucket request and versions query string parameter:

    curl -X GET \
      -H "Authorization: Bearer [OAUTH2_TOKEN]" \
      "https://storage.googleapis.com/[BUCKET_NAME]?versions"

    Where:

    • [OAUTH2_TOKEN] is the access token you created in Step 1.
    • [BUCKET_NAME] is the name of the relevant bucket. For example, my-bucket.

There are a few differences in the results of the GET request when using the versions query parameter compared to not using it. Specifically, Cloud Storage returns the following information when you include a versions query parameter in your request:

  • A Version element that contains information about each object.
  • A DeletedTime element that contains the time the object version became noncurrent (deleted or overwritten).
  • An `IsLatest element that indicates if the specific object is the latest version.
  • A NextGenerationMarker element is returned if the listing of objects is a partial listing, which occurs when you have many object versions in a bucket. Use the value of this element in the generationmarker query parameter of subsequent requests in order to resume from your last point. The generationmarker query parameter is used in the same way that you use the marker query parameter to page through a listing for a nonversioned bucket.

Accessing noncurrent object versions

To use the noncurrent version of an object when performing tasks such as downloading the object, viewing its metadata, or updating its metadata:

gsutil

  1. Append the generation number of the noncurrent version to the object name:

    [OBJECT_NAME]#[GENERATION_NUMBER]

    Where:

    • [OBJECT_NAME] is the name of the noncurrent version. For example, pets/dog.png.
    • [GENERATION_NUMBER] is the generation number for the noncurrent version. For example, 1560468815691234.
  2. Using the string from step 1, proceed as you normally would for the live version of the object.

REST APIs

JSON API

  1. Append the generation number of the noncurrent version to the URI for the object:

    https://storage.googleapis.com/storage/v1/b/[BUCKET_NAME]/o/[OBJECT_NAME]?generation=[GENERATION_NUMBER]

    Where:

    • [BUCKET_NAME] is the name of the bucket containing the noncurrent version. For example, my-bucket.
    • [OBJECT_NAME] is the name of the noncurrent version. For example, pets/dog.png.
    • [GENERATION_NUMBER] is the generation number for the noncurrent version. For example, 1560468815691234.
  2. Using the URI from step 1, proceed as you normally would for the live version of the object.

XML API

  1. Append the generation number of the noncurrent version to the URI for the object:

    https://storage.googleapis.com/[BUCKET_NAME]/[OBJECT_NAME]?generation=[GENERATION_NUMBER]

    Where:

    • [BUCKET_NAME] is the name of the bucket containing the noncurrent version. For example, my-bucket.
    • [OBJECT_NAME] is the name of the noncurrent version. For example, pets/dog.png.
    • [GENERATION_NUMBER] is the generation number for the noncurrent version. For example, 1560468815691234.
  2. Using the URI from step 1, proceed as you normally would for the live version of the object.

Copying noncurrent object versions

To copy a noncurrent version of an object:

gsutil

Use the gsutil cp command:

gsutil cp gs://[SOURCE_BUCKET_NAME]/[SOURCE_OBJECT_NAME]#[GENERATION_NUMBER] gs://[DESTINATION_BUCKET_NAME]/[DESTINATION_OBJECT_NAME]

Where:

  • [SOURCE_BUCKET_NAME] is the name of the bucket containing the noncurrent version you want to copy. For example, my-bucket.
  • [SOURCE_OBJECT_NAME] is the name of the noncurrent version you want to copy. For example, pets/dog.png.
  • [GENERATION_NUMBER] is the generation number for the noncurrent version you want to copy. For example,1560468815691234.
  • [DESTINATION_BUCKET_NAME] is the name of the bucket where you want to copy the noncurrent version. For example, my-bucket.
  • [DESTINATION_OBJECT_NAME] is the name of the noncurrent version copy. For example, pets/shiba.png.

If successful, the response looks like the following example:

Operation completed over 1 objects/58.8 KiB.

Code samples

C++

For more information, see the Cloud Storage C++ API reference documentation.

namespace gcs = google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string source_bucket_name,
   std::string source_object_name, std::string destination_bucket_name,
   std::string destination_object_name,
   std::int64_t source_object_generation) {
  StatusOr<gcs::ObjectMetadata> new_copy_meta =
      client.CopyObject(source_bucket_name, source_object_name,
                        destination_bucket_name, destination_object_name,
                        gcs::SourceGeneration{source_object_generation});

  if (!new_copy_meta) {
    throw std::runtime_error(new_copy_meta.status().message());
  }

  std::cout << "Successfully copied " << source_object_name << " generation "
            << source_object_generation << " in bucket " << source_bucket_name
            << " to bucket " << new_copy_meta->bucket() << " with name "
            << new_copy_meta->name()
            << ".\nThe full metadata after the copy is: " << *new_copy_meta
            << "\n";
}

Java

For more information, see the Cloud Storage Java API reference documentation.

import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

public class CopyOldVersionOfObject {
  public static void copyOldVersionOfObject(
      String projectId,
      String bucketName,
      String objectToCopy,
      long generationToCopy,
      String newObjectName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    // The ID of the GCS object to copy an old version of
    // String objectToCopy = "your-object-name";

    // The generation of objectToCopy to copy
    // long generationToCopy = 1579287380533984;

    // What to name the new object with the old data from objectToCopy
    // String newObjectName = "your-new-object";

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    Storage.CopyRequest copyRequest =
        Storage.CopyRequest.newBuilder()
            .setSource(BlobId.of(bucketName, objectToCopy, generationToCopy))
            .setTarget(BlobId.of(bucketName, newObjectName))
            .build();
    storage.copy(copyRequest);

    System.out.println(
        "Generation "
            + generationToCopy
            + " of object "
            + objectToCopy
            + " in bucket "
            + bucketName
            + " was copied to "
            + newObjectName);
  }
}

REST APIs

JSON API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Use cURL to call the JSON API with a POST Object request:

    curl -X POST \
      -H "Authorization: Bearer [OAUTH2_TOKEN]" \
      -H "Content-Length: 0" \
      "https://storage.googleapis.com/upload/storage/v1/b/[SOURCE_BUCKET_NAME]/o/[SOURCE_OBJECT_NAME]/rewriteTo/b/[DESTINATION_BUCKET_NAME]/o/[NAME_OF_COPY]?sourceGeneration=[GENERATION_NUMBER]"

    Where:

    • [OAUTH2_TOKEN] is the access token you generated in Step 1.
    • [SOURCE_BUCKET_NAME] is the name of the bucket containing the noncurrent version you want to copy. For example, my-bucket.
    • [SOURCE_OBJECT_NAME] is the name of the noncurrent version you want to copy. For example, pets/dog.png.
    • [DESTINATION_BUCKET_NAME] is the name of the bucket where you want to copy the noncurrent version. For example, my-bucket.
    • [NAME OF COPY] is the name of the noncurrent version copy. For example, pets/shiba.png.
    • [GENERATION_NUMBER] is the generation number for the noncurrent version you want to copy. For example,1560468815691234.

XML API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Use cURL to call the XML API, with a PUT Object request:

    curl -X PUT \
      -H "Authorization: Bearer [OAUTH2_TOKEN]" \
      -H "x-goog-copy-source: [SOURCE_BUCKET_NAME]/[SOURCE_OBJECT_NAME]" \
      -H "x-goog-copy-source-generation:[GENERATION_NUMBER]" \
      "https://storage.googleapis.com/[DESTINATION_BUCKET_NAME]/[NAME_OF_COPY]"

    Where:

    • [OAUTH2_TOKEN] is the access token you generated in Step 1.
    • [SOURCE_BUCKET_NAME] is the name of the bucket containing the noncurrent version you want to copy. For example, my-bucket.
    • [SOURCE_OBJECT_NAME] is the name of the noncurrent version you want to copy. For example, pets/dog.png.
    • [GENERATION_NUMBER] is the generation number for the noncurrent version you want to copy. For example,1560468815691234.
    • [DESTINATION_BUCKET_NAME] is the name of the bucket where you want to copy the noncurrent version. For example, my-bucket.
    • [NAME OF COPY] is the name of the noncurrent version copy. For example, pets/shiba.png.

Deleting noncurrent object versions

To delete a noncurrent version of an object:

gsutil

Use the gsutil rm command:

gsutil rm gs://[BUCKET_NAME]/[OBJECT_NAME]#[GENERATION_NUMBER]

Where:

  • [BUCKET_NAME] is the name of the bucket containing the noncurrent version you want to delete. For example, my-bucket.
  • [OBJECT_NAME] is the name of the noncurrent version you want to delete. For example, pets/dog.png.
  • [GENERATION_NUMBER] is the generation number for the noncurrent version you want to delete. For example,1560468815691234.

If successful, the response looks like the following example:

Operation completed over 1 objects.

Code samples

C++

For more information, see the Cloud Storage C++ API reference documentation.

namespace gcs = google::cloud::storage;
[](gcs::Client client, std::string bucket_name, std::string object_name,
   std::int64_t object_version) {
  google::cloud::Status status = client.DeleteObject(
      bucket_name, object_name, gcs::Generation{object_version});

  if (!status.ok()) throw std::runtime_error(status.message());
  std::cout << "Deleted " << object_name << " generation " << object_version
            << " in bucket " << bucket_name << "\n";
}

Java

For more information, see the Cloud Storage Java API reference documentation.

import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

public class DeleteOldVersionOfObject {
  public static void deleteOldVersionOfObject(
      String projectId, String bucketName, String objectName, long generationToDelete) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    // The ID of your GCS object
    // String objectName = "your-object-name";

    // The generation of objectName to delete
    // long generationToDelete = 1579287380533984;

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    storage.delete(BlobId.of(bucketName, objectName, generationToDelete));

    System.out.println(
        "Generation "
            + generationToDelete
            + " of object "
            + objectName
            + " was deleted from "
            + bucketName);
  }
}

REST APIs

JSON API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Use cURL to call the JSON API with a DELETE Object request:

    curl -X DELETE \
      -H "Authorization: Bearer [OAUTH2_TOKEN]" \
      "https://storage.googleapis.com/storage/v1/b/[BUCKET_NAME]/o/[OBJECT_NAME]?generation=[GENERATION_NUMBER]"

    Where:

    • [OAUTH2_TOKEN] is the access token you generated in Step 1.
    • [BUCKET_NAME] is the name of the bucket containing the noncurrent version you want to delete. For example, my-bucket.
    • [OBJECT_NAME] is the name of the noncurrent version you want to delete. For example, pets/dog.png.
    • [GENERATION_NUMBER] is the generation number for the noncurrent version you want to delete. For example,1560468815691234.

XML API

  1. Get an authorization access token from the OAuth 2.0 Playground. Configure the playground to use your own OAuth credentials.
  2. Use cURL to call the XML API, with a DELETE Object request:

    curl -X DELETE \
      -H "Authorization: Bearer [OAUTH2_TOKEN]" \
      "https://storage.googleapis.com/[BUCKET_NAME]/[OBJECT_NAME]?generation=[GENERATION_NUMBER]"

    Where:

    • [OAUTH2_TOKEN] is the access token you generated in Step 1.
    • [BUCKET_NAME] is the name of the bucket containing the noncurrent version you want to delete. For example, my-bucket.
    • [OBJECT_NAME] is the name of the noncurrent version you want to delete. For example, pets/dog.png.
    • [GENERATION_NUMBER] is the generation number for the noncurrent version you want to delete. For example,1560468815691234.