SAN FRANCISCO -- Matt Cain's winless drought is over, even though the Giants' three-time All-Star pitcher is still struggling with some of his mechanics.
After nearly seven weeks of frustration, Cain isn't about to complain.
Cain (1-3) earned his first win of the season despite another shaky outing at AT&T Park. The former San Francisco ace gave up two home runs and allowed all the Marlins' scoring in the first three innings before settling down to pitch into the eighth.
"He didn't cave in," Giants manager Bruce Bochy said. "He gave up four runs in the first three innings and here he is in the eighth. It says a lot about him. Good for him. It's got to be a good feeling."
Cain hadn't won since Aug. 17, 2013 -- a string of 11 consecutive starts.
It looked like the drought might continue after Cain was nearly knocked out of the game in the third inning, but he stuck around long enough to get the win in his second outing since slicing the index finger on his right hand.
After giving up two home runs to the first seven batters he faced, Cain settled down to allowed six hits over 7 2/3 uneven innings. He struck out seven and walked three.
"I made some bad pitches and those guys really capitalized on it," Cain said. "I was making good pitches other than that. I just needed to eliminate the big one that kept costing me."
Mike Morse homered for the second consecutive game and drove in three runs while Hunter Pence added three hits and scored twice for the Giants, who trailed by three runs before rallying to bail out Cain.
Garrett Jones hit his sixth home run for Miami.
The Marlins had won 12 of their last 15 games at the Giants' waterfront ballpark and were comfortably ahead 4-1 before San Francisco's comeback.
"We swung the bats great in the first three innings," Miami manager Mike Redmond said. "We have to do a better job of shutting them down after we score. We have to do a better job of executing our pitches and shutting them down."
Morse, who finished with three hits, cut the gap to 4-3 when he hit a two-run home run off Miami starter Nathan Eovaldi (2-2) in the third.
The Giants took the lead for good in the fifth after Angel Pagan drew a leadoff walk and Pence singled. Posey followed with his towering drive to right-center. Morse added an RBI single.
Miami couldn't capitalize off the quick start and was held scoreless over the final six innings.
The Marlins announced before the game that ace Jose Fernandez will have Tommy John surgery Friday, ending the season for the reigning NL Rookie of the Year.
"Our focus is to get him back," Redmond said. "I'm glad he's having it done and starting his recovery process. Obviously it's a big blow for us."
Giancarlo Stanton singled in the fifth to extend his 17-game hitting streak but the Marlins dropped to 2-6 on their 11-game road trip.
Cain fell behind early after giving up a solo home run to Derek Dietrich with one out in the first.
Miami added two runs in the second on Jones' two-run homer, then made it 4-1 on Casey McGehee's RBI double in the third.
Eovaldi gave up an RBI groundout to Brandon Hicks in the second then retired four straight following Morse's home run until the Giants' broke the game open in the fifth. Eovaldi allowed nine hits and six runs over 4 1/3 innings.
Pablo Sandoval went 1 for 4 in his return to the Giants lineup after leaving Sunday's win over Atlanta with a sore toe. ... RHP Anthony DeSclafani, who made his major league debut Sunday in Fernandez's place, will remain in the Marlins' rotation for now. ... RHP Henderson Alvarez (2-3) pitches Friday and makes his second career start against the Giants. ... Tim Hudson was scheduled to pitch for San Francisco but has been scratched due to a hip strain. RHP Yusmeiro Petit (2-1) will start in Hudson's place.