Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cherry-pick support for commit #426

Merged
merged 5 commits into from
Apr 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions NGitLab.Mock.Tests/CommitsMockTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Linq;
using NGitLab.Mock.Config;
using NGitLab.Models;
using NUnit.Framework;

namespace NGitLab.Mock.Tests
Expand Down Expand Up @@ -77,5 +78,28 @@ public void Test_two_branches_can_be_created_from_same_commit()
Assert.IsNotEmpty(commitFromBranch2.Parents);
Assert.AreEqual(commitFromBranch1.Parents[0], commitFromBranch2.Parents[0]);
}

[Test]
public void Test_commits_can_be_cherry_pick()
{
using var server = new GitLabConfig()
.WithUser("user1", isDefault: true)
.WithProject("test-project", id: 1, addDefaultUserAsMaintainer: true, configure: project => project
.WithCommit("Initial commit")
.WithCommit("Changes with tag", sourceBranch: "branch_1"))
.BuildServer();

var client = server.CreateClient();
var repository = client.GetRepository(1);
var commitFromBranch1 = repository.GetCommits("branch_1").FirstOrDefault();
Assert.NotNull(commitFromBranch1);

var cherryPicked = client.GetCommits(1).CherryPick(new CommitCherryPick
{
Sha = commitFromBranch1.Id,
Branch = "main",
});
Assert.NotNull(cherryPicked);
}
}
}
13 changes: 12 additions & 1 deletion NGitLab.Mock/Clients/CommitClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using NGitLab.Mock.Internals;
using NGitLab.Models;
Expand Down Expand Up @@ -37,6 +37,17 @@ public Commit GetCommit(string @ref)
}
}

public Commit CherryPick(CommitCherryPick cherryPick)
{
using (Context.BeginOperationScope())
{
var project = GetProject(_projectId, ProjectPermission.Contribute);
var gitCommit = project.Repository.CherryPick(cherryPick);

return gitCommit.ToCommitClient(project);
}
}

public JobStatus GetJobStatus(string branchName)
{
throw new NotImplementedException();
Expand Down
1 change: 1 addition & 0 deletions NGitLab.Mock/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,7 @@ NGitLab.Mock.ReleaseTag.ReleaseNotes.set -> void
NGitLab.Mock.ReleaseTag.ReleaseTag(string name, string releaseNotes) -> void
NGitLab.Mock.Repository
NGitLab.Mock.Repository.Checkout(string committishOrBranchNameSpec) -> void
NGitLab.Mock.Repository.CherryPick(NGitLab.Models.CommitCherryPick commitCherryPick) -> LibGit2Sharp.Commit
NGitLab.Mock.Repository.Commit(NGitLab.Mock.User user, string message) -> LibGit2Sharp.Commit
NGitLab.Mock.Repository.Commit(NGitLab.Mock.User user, string message, string targetBranch, System.Collections.Generic.IEnumerable<NGitLab.Mock.File> files) -> LibGit2Sharp.Commit
NGitLab.Mock.Repository.Commit(NGitLab.Mock.User user, string message, System.Collections.Generic.IEnumerable<NGitLab.Mock.File> files) -> LibGit2Sharp.Commit
Expand Down
24 changes: 15 additions & 9 deletions NGitLab.Mock/Repository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,20 @@ public Commit Commit(CommitCreate commitCreate)
return commit;
}

public Commit CherryPick(CommitCherryPick commitCherryPick)
{
var repo = GetGitRepository();
Commands.Checkout(repo, commitCherryPick.Branch);

var commit = GetCommit(commitCherryPick.Sha.ToString());
var options = new CherryPickOptions
{
CommitOnSuccess = commitCherryPick.Message?.Length > 0,
};
var cherryPickResult = repo.CherryPick(commit, commit.Author, options);
return cherryPickResult.Commit ?? repo.Commit(commit.Message, commit.Author, commit.Committer);
}

public void Checkout(string committishOrBranchNameSpec)
{
Commands.Checkout(GetGitRepository(), committishOrBranchNameSpec);
Expand Down Expand Up @@ -396,15 +410,7 @@ public IEnumerable<Commit> GetCommits(string @ref)
public Commit GetCommit(string reference)
{
var repository = GetGitRepository();
var branchTip = GetBranchTipCommit(reference);
if (branchTip != null)
return branchTip;

var tag = repository.Tags[reference];
if (tag?.PeeledTarget is Commit commit)
return commit;

return repository.Commits.SingleOrDefault(c => string.Equals(c.Sha, reference, StringComparison.Ordinal));
return repository.Lookup<Commit>(reference);
}

public Patch GetBranchFullPatch(string branchName)
Expand Down
39 changes: 38 additions & 1 deletion NGitLab.Tests/CommitsTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NGitLab.Models;
using NGitLab.Tests.Docker;
Expand Down Expand Up @@ -76,5 +77,41 @@ public async Task Test_can_get_merge_request_associated_to_commit()
var mergeRequest = mergeRequests.Single();
Assert.AreEqual(mergeRequestTitle, mergeRequest.Title);
}

[Test]
[NGitLabRetry]
public async Task Test_can_cherry_pick_commit()
{
using var context = await GitLabTestContext.CreateAsync();
var project = context.CreateProject();
var repository = context.Client.GetRepository(project.Id);
var commitClient = context.Client.GetCommits(project.Id);

repository.Branches.Create(new BranchCreate { Name = "test-cherry-pick", Ref = project.DefaultBranch });

var commit = commitClient.Create(new CommitCreate
{
Branch = "test-cherry-pick",
CommitMessage = "Test to cherry-pick",
Actions = new List<CreateCommitAction>
{
new()
{
Action = "update",
Content = "Test to cherry-pick",
FilePath = "README.md",
},
},
});

var cherryPickedCommit = commitClient.CherryPick(new CommitCherryPick
{
Branch = project.DefaultBranch,
Sha = commit.Id,
});

var latestCommit = commitClient.GetCommit(project.DefaultBranch);
Assert.AreEqual(cherryPickedCommit.Id, latestCommit.Id);
}
}
}
5 changes: 5 additions & 0 deletions NGitLab/ICommitClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public interface ICommitClient
/// </summary>
Commit GetCommit(string @ref);

/// <summary>
/// Cherry-picks a commit to a given branch.
/// </summary>
Commit CherryPick(CommitCherryPick cherryPick);

/// <summary>
/// Get merge requests related to a commit
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions NGitLab/Impl/CommitClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public Commit GetCommit(string @ref)
return _api.Get().To<Commit>(_repoPath + $"/commits/{@ref}");
}

public Commit CherryPick(CommitCherryPick cherryPick)
{
return _api.Post().With(cherryPick).To<Commit>($"{_repoPath}/commits/{cherryPick.Sha}/cherry_pick");
}

public JobStatus GetJobStatus(string branchName)
{
var encodedBranch = WebUtility.UrlEncode(branchName);
Expand Down
19 changes: 19 additions & 0 deletions NGitLab/Models/CommitCherryPick.cs
PMExtra marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;

namespace NGitLab.Models
{
public class CommitCherryPick
{
[Required]
[JsonIgnore]
public Sha1 Sha { get; set; }

[Required]
[JsonPropertyName("branch")]
public string Branch { get; set; }

[JsonPropertyName("message")]
public string Message { get; set; }
}
}
10 changes: 10 additions & 0 deletions NGitLab/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ NGitLab.IBranchClient.Unprotect(string name) -> NGitLab.Models.Branch
NGitLab.IClusterClient
NGitLab.IClusterClient.All.get -> System.Collections.Generic.IEnumerable<NGitLab.Models.ClusterInfo>
NGitLab.ICommitClient
NGitLab.ICommitClient.CherryPick(NGitLab.Models.CommitCherryPick cherryPick) -> NGitLab.Models.Commit
NGitLab.ICommitClient.Create(NGitLab.Models.CommitCreate commit) -> NGitLab.Models.Commit
NGitLab.ICommitClient.GetCommit(string ref) -> NGitLab.Models.Commit
NGitLab.ICommitClient.GetJobStatus(string branchName) -> NGitLab.JobStatus
Expand Down Expand Up @@ -389,6 +390,7 @@ NGitLab.Impl.ClusterClient
NGitLab.Impl.ClusterClient.All.get -> System.Collections.Generic.IEnumerable<NGitLab.Models.ClusterInfo>
NGitLab.Impl.ClusterClient.ClusterClient(NGitLab.Impl.API api, int projectId) -> void
NGitLab.Impl.CommitClient
NGitLab.Impl.CommitClient.CherryPick(NGitLab.Models.CommitCherryPick cherryPick) -> NGitLab.Models.Commit
NGitLab.Impl.CommitClient.CommitClient(NGitLab.Impl.API api, int projectId) -> void
NGitLab.Impl.CommitClient.Create(NGitLab.Models.CommitCreate commit) -> NGitLab.Models.Commit
NGitLab.Impl.CommitClient.GetCommit(string ref) -> NGitLab.Models.Commit
Expand Down Expand Up @@ -1226,6 +1228,14 @@ NGitLab.Models.Commit.Stats -> NGitLab.Models.CommitStats
NGitLab.Models.Commit.Status -> string
NGitLab.Models.Commit.Title -> string
NGitLab.Models.Commit.WebUrl -> string
NGitLab.Models.CommitCherryPick
NGitLab.Models.CommitCherryPick.Branch.get -> string
NGitLab.Models.CommitCherryPick.Branch.set -> void
NGitLab.Models.CommitCherryPick.CommitCherryPick() -> void
NGitLab.Models.CommitCherryPick.Message.get -> string
NGitLab.Models.CommitCherryPick.Message.set -> void
NGitLab.Models.CommitCherryPick.Sha.get -> NGitLab.Sha1
NGitLab.Models.CommitCherryPick.Sha.set -> void
NGitLab.Models.CommitCreate
NGitLab.Models.CommitCreate.Actions -> System.Collections.Generic.IList<NGitLab.Models.CreateCommitAction>
NGitLab.Models.CommitCreate.AuthorEmail -> string
Expand Down