A study of quaternions and the utility of FromToRotation is a bit more than a post here can contain, but I can give you a start on what seems so confusing.
First, consider transform.forward. This gives a point one unit along the local Z axis of the transform. It is where the face is pointing. That much you probably know, but focus on that though a moment. What happens if you apply a local rotation on the z axis? The object ‘rolls’, but the forward position still faces the same point.
Now reverse the viewpoint of the question. Given a vector from the object’s local origin, and assuming that’s the direction the object should be facing, what would the local Z angle be? It could be any angle, because there’s no information in this vector that could possibly tell you which way was “up” in that local coordinate system. The vector can only supply the direction to point from the face, but can’t tell you what angle along that axis the object was ‘tilted’ to.
Armed with that, reconsider the code you posted. Forward, taken from transform, is compared to another object’s forward from it’s transform. There is no information from either vector to identify the rotation of the object around the forward local axis. Any such angle would be valid, as long as the angles were correct which pointed to that forward vector.
Quaternion rotationDif will provide what seems to be an angle of difference between the two ‘forward’ vectors, and it does, but it does not include any information about which way is up. As a result, the eulerAngles you’ll get from the resulting rotation from your last line of code will not match the source. The face will point correctly, but the direction of “up” is not defined clearly. The larger the difference the “weirder” the result will seem.
If you change the source vectors from “forward” to “up”, the results will be different, and for small adjustments may seem closer, but again there’s lost information that you’re expecting. In the case of up, yaw isn’t clearly defined.
The problem is that you are expecting that the resulting quaternion in your last line of code should produce the same quaternion as the source object, but it can’t. There isn’t enough information to do that. If you were shooting a beam, which doesn’t actually have a face to be concerned about, you’d get a rotation that provides a way to hit a target, but if that beam were a bullet, it doesn’t matter how it “spins” along the axis it is moving - indeed, rifle bullets are supposed to spin to help improve accuracy. As that bullet spins the direction the bullet is traveling would not change. As the bullet is completely symetrical there’s no “face” to be concerned with. Such may be a more suitable use for “FromToRotation”, but you can’t expect the result to include information which duplicates the entire quaternion after the rotation in your last line of code. You’ll only “preserve” that portion of the information available from a pair of source vectors, which doesn’t include the orientation of the source quaternion along the axis of your reference, such as ‘forward’ can’t tell you which way is up.
What you’re expecting would require the use of both forward and up vectors applied to SetLookRotation.
The actual utility of FromToRotation is a bit questionable beyond pointing to something. I don’t think it is suitable for orienting one object to match another because not all information required is communicated through a pair of vectors.