Buster Posey hit a solo shot in the second for the Giants, who won for the third time in four games in the opener of a nine-game road trip.
Ryan Vogelsong (6-2) gave up just two hits over six innings before running into trouble in the seventh.
Dustin Ackley and Miguel Olivo both singled to start the seventh and Javier Lopez came on to relieve Vogelsong. Both runners eventually scored, but Sergio Romo retired Kyle Seager with a runner on second to end the inning.
Santiago Casilla worked the ninth for his 18th save.
Jason Vargas (7-6) gave up the four San Francisco runs on 10 hits in eight innings to suffer the loss.