that could be caused by post revision being saved, and you should use wp_insert_post_data
anytime you want to do something before the post is saved, here is an example plugin i just cooked up to test it and it looks like this:
<?php
/*
Plugin Name: wpse37901
Plugin URI: http://en.bainternet.info
Description: answer to http://wordpress.stackexchange.com/questions/37901/save-both-current-and-new-version-of-post-meta
Version: 1.0
Author: Bainternet
Author URI: http://en.bainternet.info
*/
add_action('save_post', 'sidebar_title_update');
function sidebar_title_update($post_id) {
// verify if this is an auto save routine.
// If it is our form has not been submitted, so we dont want to do anything
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if ( !wp_verify_nonce( $_POST['wpse37901_noncename'], plugin_basename( __FILE__ ) ) )
return;
// Check permissions
if ( 'post' == $_POST['post_type'] )
{
if ( !current_user_can( 'edit_post', $post_id ) )
return;
}else{
return;
}
// OK, we're authenticated: we need to find and save the data
if (isset($_POST['sidebar'])){
//save new
update_post_meta($post_id, "sidebar", $_POST["sidebar"]); // new sidebar
}
}
add_action( 'add_meta_boxes', 'wpse37901_add_custom_box' );
function wpse37901_add_custom_box() {
add_meta_box(
'wpse37901_sectionid',
__( 'wpse37901 test field'),
'wpse37901_inner_custom_box',
'post'
);
}
add_action('wp_insert_post_data','wpse37901_store_revision');
function wpse37901_store_revision($data,$postarr){
global $post;
if ($data['post_type'] !== 'revision' && isset($_POST['sidebar'])){
//save old
//get last saved data
$sidebar_old = get_post_meta($post->ID, 'sidebar', true);
//only store if value updated
if ($_POST['sidebar'] != $sidebar_old){
//get stored revisions
$sidebar_old_saved = get_post_meta($post->ID, 'sidebar_old', true);
//add last to revisions
$sidebar_old_saved[] = array('date' => date("j, n, Y H:i:s"), 'value' =>$sidebar_old);
//update revisions array
update_post_meta($post->ID, "sidebar_old", $sidebar_old_saved);
}
}
return $data;
}
function wpse37901_inner_custom_box( $post ) {
// Use nonce for verification
wp_nonce_field( plugin_basename( __FILE__ ), 'wpse37901_noncename' );
$sidebar_saved = get_post_meta($post->ID, 'sidebar', true);
// The actual fields for data entry
echo '<label for="sidebar">';
_e("For testing");
echo '</label> ';
echo '<input type="text" id="sidebar" name="sidebar" value="'.$sidebar_saved.'" size="25" />';
$sidebar_revisions = get_post_meta($post->ID, 'sidebar_old', true);
if (!empty($sidebar_revisions)){
if (is_array($sidebar_revisions)){
echo '<ul>';
foreach($sidebar_revisions as $r){
echo '<li>'.$r['date'].' : '.$r['value'].'</li>';
}
echo '</ul>';
}
}
}