Rename and move folders

This page describes how to rename and move folders in a bucket with hierarchical namespace enabled.

The rename operation recursively renames a folder, its child folders, and associated resources including objects and managed folders in a single, atomic action.

The rename operation is atomic. The operation either completes successfully and moves resources to their new path or fails with an error. In case of an error, all resources are restored to their original state.

In a bucket with hierarchical namespace enabled, renaming a folder is a metadata-only operation. It does not involve physically moving or copying the objects within the folder, so no object copy costs are incurred.

However, in a bucket without hierarchical namespace enabled, folders are simulated. Renaming or moving a simulated folder requires copying and deleting each object within it. If your folder contains many objects, the rename process can be inefficient and costly. Renaming or moving a simulated folder is also non-atomic, meaning if the process fails, your bucket might be left in an inconsistent state, with only some objects moved.

During the folder rename process, you can read and list the resources being renamed. However, you cannot run write operations on the affected resources.

The folder rename operation initiates a long-running operation on a bucket.

Required roles

In order to get the required permissions for renaming or moving folders in buckets, ask your administrator to grant you the Storage Object User (roles/storage.objectUser) IAM role on the bucket.

For more information about granting roles on projects, see Manage access to projects.

To see the exact permissions that are required, expand the Required permissions section:

Required permissions

  • storage.folders.rename
    • This permission is needed on the source folder.
  • storage.folders.create
    • This permission is needed on the destination folder.

You can also get the preceding permissions with other custom roles or predefined roles. For a more permissive role that lets you manage folders in addition to renaming folders, ask your administrator to grant you one of the following roles:

  • Storage Folder Admin (roles/storage.folderAdmin)
  • Storage Object Admin (roles/storage.objectAdmin)
  • Storage Admin (roles/storage.admin)

To see which roles are associated with which permissions, see IAM roles for Cloud Storage.

Rename and move a folder

Console

  1. In the Google Cloud console, go to the Cloud Storage Buckets page.

    Go to Buckets

  2. In the bucket list, click the name of the bucket that contains the folder you want to move or rename.

  3. In the Bucket details page, find the folder you want to move or rename.

  4. If you want to rename the folder, do the following:

    1. Click the folder's More actions menu.

    2. Click Rename folder.

    3. In the overlay window that appears, enter a new name for the folder.

    4. Click Rename.

  5. If you want to move the folder into a different folder, do the following:

    1. Click the folder's More actions menu.

    2. Click Move folder.

    3. In the overlay window that appears, click Browse.

    4. Select the destination folder for the folder you are moving. You can also click to create a new folder before you select it as the destination folder.

    5. Click Select.

    6. Click Move.

To learn how to get detailed error information about failed Cloud Storage operations in the Google Cloud console, see Troubleshooting.

Command line

To rename or move folders within a bucket with hierarchical namespace, run the following command:

gcloud storage mv gs://BUCKET_NAME/FOLDER1 gs://BUCKET_NAME/FOLDER2

Where:

  • BUCKET_NAME is the name of the bucket that contains the folder you want to rename or move. For example, my-bucket.
  • FOLDER1 is the name of the original folder that you want to rename or move. For example, my-src-folder.
  • FOLDER2 is the new name of the destination folder. For example, my-dest-folder. If the new name you choose is already being used by an existing folder, the original folder is moved inside the existing folder, becoming a child folder. For example, if you rename my-dest-folder to my-dest-folder1 (and my-dest-folder1 already exists), the result is my-dest-folder1/my-dest-folder/. If the new name you choose doesn't already exist, the original folder is renamed to match the new name.

The response looks like the following example:

Copying gs://my-bucket/my-src-folder to gs://hns-bucket/my-dest-folder...

Client libraries

C++

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

To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.

namespace storagecontrol = google::cloud::storagecontrol_v2;
[](storagecontrol::StorageControlClient client,
   std::string const& bucket_name, std::string const& source_folder_id,
   std::string const& dest_folder_id) {
  auto name = std::string{"projects/_/buckets/"} + bucket_name + "/folders/" +
              source_folder_id;
  // Start a rename operation and block until it completes. Real applications
  // may want to setup a callback, wait on a coroutine, or poll until it
  // completes.
  auto renamed = client.RenameFolder(name, dest_folder_id).get();
  if (!renamed) throw std::move(renamed).status();

  std::cout << "Renamed: " << source_folder_id << " to: " << dest_folder_id
            << "\n";
}

Go

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

To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.

import (
	"context"
	"fmt"
	"io"
	"time"

	control "cloud.google.com/go/storage/control/apiv2"
	"cloud.google.com/go/storage/control/apiv2/controlpb"
)

// renameFolder changes the name of an existing folder.
func renameFolder(w io.Writer, bucket, src, dst string) error {
	// bucket := "bucket-name"
	// src := "original-folder-name"
	// dst := "new-folder-name"

	ctx := context.Background()
	client, err := control.NewStorageControlClient(ctx)
	if err != nil {
		return fmt.Errorf("NewStorageControlClient: %w", err)
	}
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*30)
	defer cancel()

	// Construct source folder path including the bucket name.
	srcPath := fmt.Sprintf("projects/_/buckets/%v/folders/%v", bucket, src)

	req := &controlpb.RenameFolderRequest{
		Name:                srcPath,
		DestinationFolderId: dst,
	}
	op, err := client.RenameFolder(ctx, req)
	if err != nil {
		return fmt.Errorf("RenameFolder(%q): %w", srcPath, err)
	}

	// Wait for long-running operation to complete.
	f, err := op.Wait(ctx)
	if err != nil {
		return fmt.Errorf("waiting for RenameFolder: %w", err)
	}

	fmt.Fprintf(w, "folder %v moved to new path %v", srcPath, f.Name)
	return nil
}

Java

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

To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.


import com.google.api.gax.longrunning.OperationFuture;
import com.google.storage.control.v2.Folder;
import com.google.storage.control.v2.FolderName;
import com.google.storage.control.v2.RenameFolderMetadata;
import com.google.storage.control.v2.RenameFolderRequest;
import com.google.storage.control.v2.StorageControlClient;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public final class RenameFolder {

  public static void renameFolder(
      String bucketName, String sourceFolderName, String destinationFolderName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // The name of the bucket
    // String bucketName = "your-unique-bucket-name";

    // The name of the folder within the bucket
    // String sourceFolderName = "your-unique-source-folder-name";

    // The new name of the folder within the bucket
    // String destinationFolderName = "your-unique-destination-folder-name";

    try (StorageControlClient storageControl = StorageControlClient.create()) {

      // Set project to "_" to signify globally scoped bucket
      String sourceFolderResourceName = FolderName.format("_", bucketName, sourceFolderName);
      RenameFolderRequest request =
          RenameFolderRequest.newBuilder()
              .setName(sourceFolderResourceName)
              .setDestinationFolderId(destinationFolderName)
              .build();

      OperationFuture<Folder, RenameFolderMetadata> renameOperation =
          storageControl.renameFolderAsync(request);

      Folder destinationFolder = renameOperation.get(30, TimeUnit.SECONDS);

      System.out.printf(
          "Renamed folder from %s to %s%n", sourceFolderResourceName, destinationFolder.getName());
    }
  }
}

Node.js

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

To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */

// The name of your GCS bucket
// const bucketName = 'bucketName';

// The source folder name
// const sourceFolderName = 'currentFolderName';

// The destination folder ID
// const destinationFolderName = 'destinationFolderName';

// Imports the Control library
const {StorageControlClient} = require('@google-cloud/storage-control').v2;

// Instantiates a client
const controlClient = new StorageControlClient();

async function callRenameFolder() {
  const folderPath = controlClient.folderPath(
    '_',
    bucketName,
    sourceFolderName
  );

  // Create the request
  const request = {
    name: folderPath,
    destinationFolderId: destinationFolderName,
  };

  // Run request
  await controlClient.renameFolder(request);
  console.log(
    `Renamed folder ${sourceFolderName} to ${destinationFolderName}.`
  );
}

callRenameFolder();

PHP

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

To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.

use Google\Cloud\Storage\Control\V2\Client\StorageControlClient;
use Google\Cloud\Storage\Control\V2\RenameFolderRequest;

/**
 * Rename a folder in an existing bucket.
 *
 * @param string $bucketName The name of your Cloud Storage bucket.
 *        (e.g. 'my-bucket')
 * @param string $sourceFolder The source folder ID.
 *        (e.g. 'my-folder')
 * @param string $destinationFolder The destination folder ID.
 *        (e.g. 'my-folder')
 */
function rename_folder(string $bucketName, string $sourceFolder, string $destinationFolder): void
{
    $storageControlClient = new StorageControlClient();

    // Set project to "_" to signify global bucket
    $formattedName = $storageControlClient->folderName('_', $bucketName, $sourceFolder);

    $request = new RenameFolderRequest([
        'name' => $formattedName,
        'destination_folder_id' => $destinationFolder,
    ]);

    $storageControlClient->renameFolder($request);

    printf('Renamed folder %s to %s', $sourceFolder, $destinationFolder);
}

Python

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

To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.

from google.cloud import storage_control_v2


def rename_folder(
    bucket_name: str, source_folder_name: str, destination_folder_name: str
) -> None:
    # The ID of your GCS bucket
    # bucket_name = "your-unique-bucket-name"
    #
    # The source folder ID
    # source_folder_name = "current-folder-name"
    #
    # The destination folder ID
    # destination_folder_name = "new-folder-name"

    storage_control_client = storage_control_v2.StorageControlClient()
    # The storage bucket path uses the global access pattern, in which the "_"
    # denotes this bucket exists in the global namespace.
    source_folder_path = storage_control_client.folder_path(
        project="_", bucket=bucket_name, folder=source_folder_name
    )

    request = storage_control_v2.RenameFolderRequest(
        name=source_folder_path,
        destination_folder_id=destination_folder_name,
    )

    operation = storage_control_client.rename_folder(request=request)
    operation.result(60)

    print(f"Renamed folder {source_folder_name} to {destination_folder_name}")

Ruby

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

To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.

def rename_folder bucket_name:, source_folder_id:, destination_folder_id:
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"
  #
  # The source folder ID
  # source_folder_id = "current-folder-id"
  #
  # The destination folder ID, e.g. foo/bar/
  # destination_folder_id = "destination-folder-id"

  require "google/cloud/storage/control"

  storage_control = Google::Cloud::Storage::Control.storage_control

  # The storage folder path uses the global access pattern, in which the "_"
  # denotes this bucket exists in the global namespace.
  folder_path = storage_control.folder_path project: "_", bucket: bucket_name, folder: source_folder_id

  request = Google::Cloud::Storage::Control::V2::RenameFolderRequest.new name: folder_path,
                                                                         destination_folder_id: destination_folder_id

  storage_control.rename_folder request

  puts "Renamed folder #{source_folder_id} to #{destination_folder_id}"
end

REST APIs

JSON API

  1. Have gcloud CLI installed and initialized, which lets you generate an access token for the Authorization header.

  2. Use cURL to call the JSON API with a request to rename folders:

    curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/folders/SOURCE_PATH/renameTo/folders/DESTINATION_PATH"

    Where:

    • BUCKET_NAME is the name of the bucket that contains the folder that you want to rename or move. For example, my-bucket.
    • SOURCE_PATH is the URL-encoded path of the source folder. For example, my-src-folder/ URL-encoded as my-src-folder%2F.
    • DESTINATION_PATH is the URL-encoded path of the destination folder. For example, my-dest-folder/ URL-encoded as my-dest-folder%2F.

Next steps

Try it for yourself

If you're new to Google Cloud, create an account to evaluate how Cloud Storage performs in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.

Try Cloud Storage free