diff -Naur trunk.svn/S3/S3.py trunk/S3/S3.py
--- trunk.svn/S3/S3.py	2010-11-04 21:00:58.000000000 -0700
+++ trunk/S3/S3.py	2010-11-04 21:04:32.000000000 -0700
@@ -311,6 +311,24 @@
 		response = self.send_request(request)
 		return response
 
+	def object_replace(self, src_uri, dst_uri, extra_headers = None):
+		if src_uri.type != "s3":
+			raise ValueError("Expected URI type 's3', got '%s'" % src_uri.type)
+		if dst_uri.type != "s3":
+			raise ValueError("Expected URI type 's3', got '%s'" % dst_uri.type)
+		headers = SortedDict(ignore_case = True)
+		headers['x-amz-copy-source'] = "/%s/%s" % (src_uri.bucket(), self.urlencode_string(src_uri.object()))
+		headers['x-amz-metadata-directive'] = "REPLACE"
+		if self.config.acl_public:
+			headers["x-amz-acl"] = "public-read"
+		if self.config.reduced_redundancy:
+			headers["x-amz-storage-class"] = "REDUCED_REDUNDANCY"
+		if extra_headers:
+			headers.update(extra_headers)
+		request = self.create_request("OBJECT_PUT", uri = dst_uri, headers = headers)
+		response = self.send_request(request)
+		return response
+
 	def object_move(self, src_uri, dst_uri, extra_headers = None):
 		response_copy = self.object_copy(src_uri, dst_uri, extra_headers)
 		debug("Object %s copied to %s" % (src_uri, dst_uri))
diff -Naur trunk.svn/s3cmd trunk/s3cmd
--- trunk.svn/s3cmd	2010-11-04 20:12:34.000000000 -0700
+++ trunk/s3cmd	2010-11-04 21:00:36.000000000 -0700
@@ -558,9 +558,12 @@
 		output(u"File %s deleted" % item['object_uri_str'])
 
 def subcmd_cp_mv(args, process_fce, action_str, message):
-	if len(args) < 2:
+	if (len(args) < 2) and (action_str != 'replace'):
 		raise ParameterError("Expecting two or more S3 URIs for " + action_str)
-	dst_base_uri = S3Uri(args.pop())
+	if (action_str != 'replace'):
+		dst_base_uri = S3Uri(args.pop())
+	else:
+		dst_base_uri = S3Uri(args[0])
 	if dst_base_uri.type != "s3":
 		raise ParameterError("Destination must be S3 URI. To download a file use 'get' or 'sync'.")
 	destination_base = dst_base_uri.uri()
@@ -612,6 +615,10 @@
 	s3 = S3(Config())
 	subcmd_cp_mv(args, s3.object_copy, "copy", "File %(src)s copied to %(dst)s")
 
+def cmd_replace(args):
+	s3 = S3(Config())
+	subcmd_cp_mv(args, s3.object_replace, "replace", "File %(src)s headers updated")
+
 def cmd_mv(args):
 	s3 = S3(Config())
 	subcmd_cp_mv(args, s3.object_move, "move", "File %(src)s moved to %(dst)s")
@@ -1527,6 +1534,7 @@
 	{"cmd":"du", "label":"Disk usage by buckets", "param":"[s3://BUCKET[/PREFIX]]", "func":cmd_du, "argc":0},
 	{"cmd":"info", "label":"Get various information about Buckets or Files", "param":"s3://BUCKET[/OBJECT]", "func":cmd_info, "argc":1},
 	{"cmd":"cp", "label":"Copy object", "param":"s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]", "func":cmd_cp, "argc":2},
+	{"cmd":"replace", "label":"Update object headers", "param":"s3://BUCKET1/OBJECT1", "func":cmd_replace, "argc":1},
 	{"cmd":"mv", "label":"Move object", "param":"s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]", "func":cmd_mv, "argc":2},
 	{"cmd":"setacl", "label":"Modify Access control list for Bucket or Files", "param":"s3://BUCKET[/OBJECT]", "func":cmd_setacl, "argc":1},
 	{"cmd":"accesslog", "label":"Enable/disable bucket access logging", "param":"s3://BUCKET", "func":cmd_accesslog, "argc":1},
