A little underappreciated fact is that you can build a quaternion from the dot and cross product of 2 vectors directly:
The dot product of 2 vectors is the cosine of the angle between them and the cross product is the axis of the rotation with length equal to the sine of the angle between them.
ergo quat(dot(v1, v2), cross(v1, v2)) is the quaternion of the double angle You can get the proper quaternion by nlerping it with the unit quaternion.
Or in other words normalized(quat(1+dot(v1, v2), cross(v1, v2))) is the proper quaternion of the rotation of v1 to v2. Assuming v1 and v2 are unit length.
You can often delay the normalization step even, and let most operations just accumulate the length disparity and divide the squared length after converting to a matrix or applying it to a point. The only place you can't (to my knowledge) is when interpolating.