McDonald (9-3) struck out 10 and walked none, winning his fourth straight start and lowering his sparkling ERA to 2.37.
The Pirates have won nine of 11 and are guaranteed at least a share of the NL Central lead through the All-Star break.
Ryan Vogelsong (7-4) couldn't quite match McDonald, allowing three runs and eight hits in seven innings. Ryan Theriot and Gregor Blanco had two hits apiece for the Giants, who have dropped six of eight.
NATIONALS 4, ROCKIES 1
It was the fifth victory in six games for the Nationals, who own the best record in the NL.
Colorado finished with four errors, tying a season high. Dexter Fowler had three hits for the Rockies, who have lost six of eight and totaled 14 runs in their last seven games.
Colorado starter Jeff Francis (2-2) gave up three runs and six hits in five-plus innings.
The Nationals announced during the game that Desmond will miss Tuesday's All-Star game with a left oblique strain. He has been dealing with the injury since mid-June and will use the break to rest.
CARDINALS 3, MARLINS 2
Allen Craig had three hits and Skip Schumaker added an RBI single in the fourth for the Cardinals, who have won five of seven. All-Star David Freese was hit by a pitch twice, walked and singled to reach base safely in all four trips.
Giancarlo Stanton left in the third inning with right knee discomfort and the Marlins said he would have arthroscopic surgery on Sunday, shelving one of baseball's best young sluggers for next week's All-Star festivities in Kansas City.
Lohse (9-2) allowed two runs and three hits to improve to 3-0 with a 2.08 ERA in three starts against Miami this season. Jason Motte pitched a shaky ninth inning for his 20th save.
Carlos Zambrano (4-7) gave up three runs and seven hits in five innings for the Marlins.
ASTROS 6, BREWERS 3
Milwaukee starter Zack Greinke (9-3) was looking for his 10th win; instead he was gone after four pitches -- ejected after spiking the ball following a close play at first base. Manager Ron Roenicke also was tossed for arguing the call and the Brewers were forced to piece together the game with six relievers.
METS 3, CUBS 1
Gee (6-7) yielded seven hits, struck out four and walked none. Bobby Parnell allowed a leadoff double to Anthony Rizzo, but retired the final three batters for his second save, striking out Steve Clevenger on a 101 mph fastball to end it.
Jeff Samardzija (6-8) pitched seven innings for the Cubs and was charged with three runs and seven hits.
Davis hit a two-run shot to right in the third inning as the Mets won for the seventh time in 10 games.
BRAVES 6, PHILLIES 3
The five-time defending NL East champions are freefalling since Chase Utley returned to the lineup, losing nine of 10. They just got Ryan Howard back on Friday night and have lost two in a row, though the former NL MVP didn't play in this loss.
Phillies starter Joe Blanton (7-8) allowed six runs and nine hits in 6 1-3 innings.
Copyright 2012 by The Associated Press
This story is from ESPN.com's automated news wire. Wire index
MORE MLB HEADLINES
- A-Rod met Bosch at ALCS, clinic crony says
- Yanks' Jeter takes batting practice in Tampa
- Hamilton drops to No. 7 spot in Angels lineup
- Davis launches 2 HRs as O's trounce Tigers