Yes but that will only apply if the voltage you are pulling it up to is above the zero / one threshold voltage. Otherwise a pull up is not going to cut it.
Well that applies to anything digital signal regardless of whether you are using a internal or external pull-up resistor or neither.
Even so you erode noise margin by only pulling up to a lower voltage so in most cases you are better off using a level shifter.
Obviously that's the best solution in any scenario but it costs more in parts and board space. For something like a small low speed I2C bus, a resistor is fine.
An ATmega running at 5V with an I2C bus interface to a 3.3V device would require external pull-up resistors connected to 3.3V
But the bus would still be held at +5vdc due to the active sourcing output of the 5 volt mega's output pin. Current would flow through the pull-up from 3.3v to 5v, but the bus side of the resistor would still be at +5vdc, or am I missing something stupid?
I2C signals are bidirectional, so at times the 5vdc system side has to be an output and will not be constrained to the pull-ups 3.3vdc value. I guess most here are just considering the 5vdc system side as being an input where the bus pull-up is the only thing defining the logic high voltage level.
On a I2C bus, absolutely NO device is ever allowed to drive the bus anything but low.
At the physical layer, both SCL & SDA lines are of open-drain design, thus, pull-up resistors are needed. Pulling the line to ground is considered a logical zero while letting the line float is a logical one. This is used as a channel access method. High speed systems (and some others) also add a current source pull up, at least on SCL; this supports faster rise times and higher bus capacitance. Transitions for data bits are always performed while the clock is low, transitions while it is high indicate start and stop bits.
When one node is transmitting a logical one (i.e., letting the line float to Vdd) and another transmits a logical zero then the first node can sense this because the line is not in a logical one state — it is not pulled up to Vdd. When used on SCL, this is called "clock stretching" and gives slaves a flow control mechanism. When used on SDA, this is called arbitration and ensures there is only one transmitter at a time.