Born in Praia, Cape Verde, Martins moved to Portugal in his teens and played youth football with C.F. Benfica and Sporting CP. In March 2014, he was promoted to the B-team of the latter and signed a contract extension until 2019, with a release clause of €45 million; during his youth spell, his goal against C.F. União de Coimbra earned the praise of many, even though his coach at Sporting B had previously said he was being "harmed" by not playing in his preferred position as winger. Gelson made his debut as a professional on 24 August 2014, coming on as a late substitute for Lewis Enoh in a 1–0 away win against S.C. Olhanense for the Segunda Liga championship. On 21 December he scored his first goal in the competition, contributing to a 3–1 success at Vitória S.C. B. Martins was promoted to Sporting's main squad in summer 2015 by new manager Jorge Jesus. He made his competitive debut on 9 August, playing injury time in a 1–0 win over S.L. Benfica for the Supertaça Cândido de Oliveira. Martins first appeared in the Primeira Liga on 14 August 2015, playing one minute in a 2–1 success against newly promoted C.D. Tondela. On 15 January of the following year, against the same opponent, he scored Sporting's 5000th goal in the competition, putting the hosts ahead in an eventual 2–2 draw. On 11 June 2018, Martins requested that his contract with Sporting be terminated, following an incident in the previous month where a group of around 50 supporters invaded the club's training centre and assaulted several players and staff members.
Atlético Madrid
On 18 July 2018, Martins accepted an offer from Atlético Madrid. One week later, he was announced as a new player of the Spanish club after agreeing to a five-year deal on a free transfer. Sporting made an official complaint to FIFA over the transfer and demanded compensation of €100 million, the release clause of his cancelled contract. Martins made his La Liga debut on 20 August 2018 in a 1–1 away draw to Valencia CF where he played 18 minutes in place of Antoine Griezmann, and scored his first goal two months later as the visitors won it 1–0 against amateurs UE Sant Andreu in the Copa del Rey. During his spell at the Metropolitano Stadium, he was sparingly played by coach Diego Simeone.
Monaco
On 27 January 2019, Martins joined AS Monaco FC on loan until the end of the season. He first appeared in Ligue 1 on 2 February, providing an assist for Aleksandr Golovin early in the first half and also being involved in Cesc Fàbregas' goal in the 2–1 home victory over Toulouse FC. In July 2019, Martins signed a permanent five-year contract at Monaco. The following 1 February, at the 30-minute mark of an away fixture against Nîmes Olympique, he repeatedly pushed referee Mikael Lesage in retaliation for his teammate Tiémoué Bakayoko's ejection seconds before, and was too sent off as his team eventually lost 3–1. For his actions, he was handed a six-month suspension on 5 March.