I have figured out a solution:
1) This is not perfect, see my (2) below.
Without any speed_factor (interpolating by default amount):
func _process(delta):
var angle_to_target = int( rad_to_deg( get_angle_to(target_body) ) )
if(angle_to_target > 0): #rotate counter-clockwise if the target is on your left
global_rotation += 1 * delta
else: #rotate clockwise if the target is on your right
global_rotation -= 1 * delta
This is not perfect!
Basically, if our angle to target is not 0 (we aren't facing it perfectly), we'll rotate ourselves towards it by unit amount every frame, thus gradually correcting our angle towards it. This means every frame, our angle_to_target will reduce because we're gradually turning towards it. However, if our angle_to_target is very close but still greater than zero, rotating by + (1 * delta) may overcorrect our angle resulting in angle_to_target becoming < 0 (we overdid our rotation towards it, and now we have to rotate back). In that case, the else block will execute and we'll rotate back by - (1 * delta) which may again overcorrect our angle to positive direction requiring us to rotate in the opposite direction again, and so on...
This will result in a "jitter/vibration" as our body closes in on facing the target but can never reduce the angle perfectly to 0 (it'll either overcorrect it in the positive direction, or in the negative direction).
To solve that, we should take a range of rotation values which is greater than the amount we are correcting it by, and if our angle reaches that range, instead of interpolating, we simply look_at(target_body) directly.
2) In my updated code, not only are we addressing the jitter, we are also using an optional speed factor to rotate it faster or slower as we wish:
func _process(delta):
var speed_factor = 5
var angle_to_target = int( rad_to_deg( get_angle_to(target_body) ) )
#lets take an angle range of 2 to -2 degrees (just make sure this range is bigger than the amount of rotation you're doing with adding/subtracting delta * speed_factor to our global_rotation, otherwise you'll get the jitter again)
#So,
if(angle_to_target <= 2 and angle_to_target >= -2): #if its close enough, we don't need to interpolate, just look at it directly, so no chance of overcorrection
look_at(target_body)
elif(angle_to_target > 2): #rotate counter-clockwise
global_rotation += 1 * delta * speed_factor
else: #i.e., if angle_to_target < -2, #rotate clockwise
global_rotation -= 1 * delta * speed_factor
WARNING: Make sure your angle range (here 2 to -2 deg) is greater than delta * speed_factor to avoid jitter/overcorrection. If you're not using speed_factor, make sure your angle range is higher than delta to avoid jitter/overcorrection.
Still, even this is not perfect, since the speed_factor isn't effective when we use look_at(), but its good enough for me.