After many large, ugly iterations and weird edge cases over the years, I now have a concise section of my .bashrc dedicated to this.
First, you must comment out or remove this section of your .bashrc (default for Ubuntu). If you don’t, then certain environments (like running screen sessions) will still truncate your history:
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
# HISTSIZE=1000
# HISTFILESIZE=2000
Second, add this to the bottom of your .bashrc:
# Eternal bash history.
# ---------------------
# Undocumented feature which sets the size to "unlimited".
# http://stackoverflow.com/questions/9457233/unlimited-bash-history
export HISTFILESIZE=
export HISTSIZE=
export HISTTIMEFORMAT="[%F %T] "
# Change the file location because certain bash sessions truncate .bash_history file upon close.
# http://superuser.com/questions/575479/bash-history-truncated-to-500-lines-on-each-login
export HISTFILE=~/.bash_eternal_history
# Force prompt to write history after every command.
# http://superuser.com/questions/20900/bash-history-loss
PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
Note: every command is written immediately after it’s run, so if you accidentally paste a password you cannot just “kill -9 %%” to avoid the history write, you’ll need to remove it manually.
Also note that each bash session will load the full history file in memory, but even if your history file grows to 10MB (which will take a long, long time) you won’t notice much of an effect on your bash startup time.