Hamels allowed a leadoff double to Ryan Garko in the second inning and a single to pinch-hitter Rich Aurilia to start the ninth. He struck out nine and walked one in his fourth career shutout and second this season. The left-hander extended his scoreless innings streak to 19, tying a career best, and won for the first time since July 28 against Arizona.
Jonathan Sanchez was the hard-luck loser for the Giants. He allowed one run and three hits, striking out eight in six innings.
The NL East-leading Phillies have won 15 of 20. They entered with a 7-game lead over Atlanta.
The Giants came in tied with Colorado in the wild-card race.
For much of this season, Hamels hasn't pitched like the guy who was MVP of the NLCS and World Series last October. But he was outstanding in his previous start and dominated San Francisco.
Hamels tossed eight scoreless innings in Philadelphia's 4-1, extra-inning win at Pittsburgh last Wednesday.
He was in control right from the start of this one, mixing a sharp fastball with his trademark changeup and an effective curve.
Hamels retired 24 in a row after Garko's hit.
After Aurilia's single, Hamels picked off pinch-runner Andres Torres. He then walked pinch-hitter Pablo Sandoval, but struck out pinch-hitter Bengie Molina and retired Edgar Renteria on a foul pop to end it.
The offensively challenged Giants didn't have their top hitter, Sandoval, and cleanup hitter, Molina, in the starting lineup.
Sandoval is bothered by a right calf injury that sidelined him for three games in the middle of last week. Molina hasn't started the last seven games because of a tight right quadriceps.
Sanchez didn't allow a hit until Shane Victorino led off Philadelphia's fourth with a single to left. Victorino stole second, advanced to third on Chase Utley's groundout and scored when Howard ripped a double down the right-field line.
Hamels even picked up his first career stolen base in the fifth after failing to execute a sacrifice bunt. He reached on a fielder's choice and then swiped second base without a throw before Jimmy Rollins grounded out to end the inning.
It was the first stolen base by a Phillies pitcher since Curt Schilling had one in 1997.