Match ends, FC Porto 0, Manchester City 0.
Manchester City had a late goal against Porto ruled out but a draw was enough for them to secure top spot in Champions League Group C.
It seemed that after a frustrating 80 minutes substitute Gabriel Jesus had broken the deadlock when he tapped home after his initial header had been saved, but the effort was ruled out because Joao Cancelo was offside.
The rest of the match saw exceptional goalkeeper Agustin Marchesin and his deep-lying five-man defence soak up incessant pressure from Pep Guardiola's side, who came into the match having put five goals past Burnley at the weekend and with a 100% record in the group.
The Argentine keeper made three superb saves. He twice denied Spanish forward Ferran Torres, pushing one effort wide of the post in the first half before blocking a spectacular overhead kick after the break.
Porto's stopper also denied Raheem Sterling by rushing out to block his attempt on goal. The England winger went close again when he cut in and fired a low shot which was cleared off the line by Zaidu Sanusi.
The point also saw Porto qualify from the group.
City kept at bay by marvellous Marchesin
Guardiola was insistent in the build-up that his side were determined to win Group C with victory at Porto.
He recalled that the Portuguese champions had given his side a stiff test and physical workout during the 3-1 win at Etihad Stadium in October, and perhaps with all that in mind the Catalan coach picked a strong attack featuring Raheem Sterling, Phil Foden and the in-form Ferran Torres, who was seeking his fourth successive goal in the competition.
But Porto coach Sergio Conceicao also knew that if his team could somehow avoid defeat then his own side would also qualify to the knockout round. So it was no surprise when the home side set up a barricade in front of Marchesin, although the way the keeper performed he could have kept City to nil without a backline.
The Argentine's saves from Torres and Sterling were brilliant and also showed brilliant reflexes to push Jesus' initial header onto the bar before the Brazilian tapped home.
With Lady Luck on his side the goal was ruled out after replays showed Cancelo, who provided the assist, was offside by fractions in the build-up.
Who might keep their place for the game against Fulham?
Neither Phil Foden nor Bernardo Silva are currently first names on the team-sheet, although the English youngster seem the more likelier of the two to make Saturday's XI.
The 20-year-old hugged the left side of the pitch and produced an effervescent display, setting up Torres in the first half for his strike which was saved by the Porto stopper.
Silva was one of the headline acts of the team two seasons ago, but has only featured in six domestic league games this campaign. The 26-year-old covered every area of the pitch but appeared to lack the attacking conviction he previously had, and in the first half received instructions from his manager which seemed to suggest he should show more endeavour.
Sterling could be most likely to break back into the side. He did not feature against Burnley, but on Tuesday managed five efforts on target, including one shot saved by Marchesin and an effort cleared off the line.
'Big congratulations to the team' - reaction
Manchester City boss Pep Guardiola: "They are one of the best teams in Portugal with the quality they have. We played exceptionally well.
"We came here to finish first. We played with huge personality, with courage. It is not easy with eight players in the box - even with that, we created enough chances to win. This is the most important thing.
"Big congratulations to the team for the group stage. In this period, this year especially, the Champions League was tricky.
"In all the games away we have played a really high level. In general, I am more than delighted with the performance in these games. We have one left, nothing to play for, just to maintain the rhythm. Now it is time to forget Champions League and focus on the Premier League."
Porto coach Sergio Conceicao: "We have raised standards high in the name of Portugal. We showed good moments of defensive organisation. It was difficult to get up front as we wanted, much because of City, who react well when they lose the ball."
Eighteen shots but no goals - stats
- Porto remain winless in their last six Champions League games against English sides (D2 L4), failing to score in four of those games.
- City have progressed to the knock-out stages as group winners for the fifth time in the last six seasons, only failing to do so in 2016-17 (progressing as runners-up to Barcelona).
- Porto have ended a run of 14 Champions League home games without a draw, since September 2016 (1-1 v Copenhagen).
- City have kept four consecutive clean sheets in the Champions League for the first time, as many as they managed in the group stages in their last two campaigns combined (four).
- Guardiola has seen his side draw 0-0 in the Champions League for the first time in 59 games since a nil-nil against Shakhtar Donetsk in February 2015 when manager of Bayern Munich.
- City had 18 shots today, their most attempts at goal without scoring in a Champions League match.
City host Fulham on Saturday in the Premier League (15:00 GMT).
- 18Manafá JancóSubstituted forChipela Gomesat 72'minutes
- 4Monteiro Pinto Leite
- 25OtávioSubstituted forVieiraat 87'minutes
- 11MaregaBooked at 69minsSubstituted forde Lima Barbosaat 72'minutes
- 17JM CoronaSubstituted forDíazat 63'minutes
- 14Morais Ramos
- 21Silva Baró
- 23Neto Lopes
- 28Felipe Anderson
- 30de Lima Barbosa
- 31Chipela Gomes
- 99Meireles Costa
- 3Rúben Dias
- 16RodriBooked at 51mins
- 20Bernardo Silva
- 21TorresSubstituted forGabriel Jesusat 71'minutes
- 9Gabriel Jesus
- 17De Bruyne
- Björn Kuipers
- Shots on Target
Second Half ends, FC Porto 0, Manchester City 0.
Attempt missed. Eric García (Manchester City) header from the centre of the box misses to the left. Assisted by Fernandinho with a headed pass following a set piece situation.
Phil Foden (Manchester City) wins a free kick on the right wing.
Foul by Zaidu Sanusi (FC Porto).
Oleksandr Zinchenko (Manchester City) wins a free kick on the left wing.
Foul by Fábio Vieira (FC Porto).
Phil Foden (Manchester City) wins a free kick in the attacking half.
Foul by Zaidu Sanusi (FC Porto).
Gabriel Jesus (Manchester City) wins a free kick in the attacking half.
Foul by Diogo Leite (FC Porto).
Attempt missed. Gabriel Jesus (Manchester City) header from the centre of the box is just a bit too high. Assisted by Fernandinho.
Substitution, FC Porto. Fábio Vieira replaces Otávio.
VAR Decision: No Goal FC Porto 0-0 Manchester City.
GOAL OVERTURNED BY VAR: Gabriel Jesus (Manchester City) scores but the goal is ruled out after a VAR review.
Offside, Manchester City. João Cancelo tries a through ball, but Rodrigo is caught offside.
Attempt saved. Eric García (Manchester City) right footed shot from very close range is saved in the centre of the goal. Assisted by Rúben Dias.
Attempt blocked. Rúben Dias (Manchester City) header from the centre of the box is blocked. Assisted by Phil Foden with a cross.
Corner, Manchester City. Conceded by Chancel Mbemba.
Foul by Raheem Sterling (Manchester City).
- Anton Ferdinand: Football, Racism and Me: How the John Terry incident drove him to tackle the problem in the game
- Rugby League's Great British Lions: Follow a behind the scenes look at their return tour down under