upvote
First, you need backups

Second (for servers), etckeeper

reply

    #!/bin/sh
    
    errecho() {
        >&2 printf '%s\n' "$@"
    }
    
    if [ "$#" != 1 ] || [ -z "$1" ]
    then
        errecho 'Requires a single filename as the argument'
        exit 1
    fi
    
    ORIGINAL=$1
    if [ "${ORIGINAL#./}" == "$ORIGINAL" ] && [ "${ORIGINAL#/}" == "$ORIGINAL" ]
    then
        ORIGINAL=./"$ORIGINAL"
    fi
    
    # because of course the output of dirname can't be blindly joined with slash and the basename
    DIRNAME=$(dirname -- "$ORIGINAL")
    if [ "$DIRNAME" = / ]
    then
        DIRNAME=
    fi
    
    FILENAME=$(basename -- "$ORIGINAL")
    # because of course extracting the filename's extension is not supported out of the box
    case "$FILENAME" in
        .*.* )
            EXTENSION=.${FILENAME#.*.}
            BASENAME=$(printf '%s' "$FILENAME" | cut -c-$((${#FILENAME} - ${#EXTENSION})) )
            ;;
        .* )
            EXTENSION=
            BASENAME=$FILENAME
            ;;
        *.[^.]* )
            BASENAME=${FILENAME%%.*}
            EXTENSION=${FILENAME#*.}
            ;;
        * )
            BASENAME=${FILENAME%%.*}
            EXTENSION=$(printf '%s' "$FILENAME" | cut -c$((${#BASENAME} + 1))- )
            ;;
    esac
    
    if [ "$FILENAME" != "$BASENAME$EXTENSION" ] || [ -z "$BASENAME" ]
    then
        errecho 'Failed to properly split the extension from the filename:' "$FILENAME"
        exit 1
    fi
    
    TIMESTAMP=$(date --utc --date=@"$(stat --format %Y "$ORIGINAL")" +'_%Y-%m-%d_%H%M%S')
    if [ -z "$TIMESTAMP" ]
    then
        errecho 'Failed to get the timestamp of the file:' "$ORIGINAL"
        exit 1
    fi
    
    NEW_FILENAME=$(printf '%s/%s_%s%s' "$DIRNAME" "$BASENAME" "$TIMESTAMP" "$EXTENSION")
    
    if [ "$NEW_FILENAME" = "$ORIGINAL" ]
    then
        errecho 'Somehow the name for the backup is the same as the original file'
        exit 1
    fi
    
    # this preserves the timestamps somewhat better
    if ! mv --no-clobber --no-copy -- "$ORIGINAL" "$NEW_FILENAME"
    then
        errecho 'Failed to backup the file: ' "$ORIGINAL" "$NEW_FILENAME"
        exit 1
    fi
    
    if ! cp -- "$NEW_FILENAME" "$ORIGINAL"
    then
        errecho 'Failed to backup the file: ' "$ORIGINAL" "$NEW_FILENAME"
        mv --no-clobber --no-copy -- "$NEW_FILENAME" "$ORIGINAL"
    fi
Actually, nevermind that bullshit, you know what? I think I'd prefer to have an editor with locally persisted edit history instead.
reply