0

I have a commit id, I want to check whether is it present in a branch or in which branches this commit id is present.

GitBranchStats doesn't have any properties related to commit info in

Microsoft.TeamFoundation.SourceControl.WebApi library.
Uri orgUrl = new Uri("https://example.com");         // Organization URL            
String personalAccessToken = "XXXXXXXXX"; 
VssConnection connection = new VssConnection(orgUrl, new VssBasicCredential(string.Empty, personalAccessToken));
GitHttpClient gitClient = connection.GetClient<GitHttpClient>();
GitBranchStats branch = gitClient.GetBranchAsync("repo", "name").Result;

FYI, I am not looking for a git command, I already know this.

Edit:

It's giving exceptions in method check_whether_present_in_branches in a few cases when a branch is in any folder like below.

Exception message:

TF401175:The version descriptor <Branch: Release > could not be resolved to a version in the repository

enter image description here

riQQ
  • 9,878
  • 7
  • 49
  • 66
Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
  • Does this answer your question? [Azure DevOps REST Api: Does git commit exists in branch?](https://stackoverflow.com/questions/64877697/azure-devops-rest-api-does-git-commit-exists-in-branch) – TTT Sep 22 '22 at 18:55
  • @TTT already visited this page, it’s not helping – Vivek Nuna Sep 22 '22 at 19:05
  • Is it because you can't get it working or because it doesn't get you what you want? (Side Note: now that I look closely at how that link works, it appears to be inefficient for large histories. It looks like it returns every commit for a branch and then checks if the desired commit is in the list... So even if you did get it working you may not want to use it for many branches and/or many commits in the history.) – TTT Sep 22 '22 at 19:12

1 Answers1

1

Update:

using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
using System;
using System.Collections.Generic;
using System.Linq;

namespace CheckWhetherCommitExistInCurrentBranch
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Uri orgUrl = new Uri("https://dev.azure.com/xxx/");         // Organization URL
            string project = "xxx";
            string repository = "xxx";
            String personalAccessToken = "xxx";
            string commit_id = "xxx";
            string branch_name = "xxx";

            //var commitref = GetLastestCommit(orgUrl, personalAccessToken, project, repository, branch_name);

            //Console.WriteLine(commitref.CommitId);

            //check whether the commit id exists in specific branch.
            bool exists = check_whether_present_in_branch(orgUrl, personalAccessToken, project, repository, commit_id, branch_name);
            Console.WriteLine("Whether commit id "+commit_id+" exists in "+branch_name+"? "+exists+"\n");

            //check what branches the commit id exists.
            List<string> branches = check_whether_present_in_branches(orgUrl, personalAccessToken, project, repository, commit_id);
            foreach (var branch in branches)
            {
                Console.WriteLine("exists in "+branch);
            }
        }
        public static bool check_whether_present_in_branch(Uri orgUrl, string personalAccessToken, string project, string repository, string commit_id, string branch)
        {
            bool exists = false;
            VssConnection connection = new VssConnection(orgUrl, new VssBasicCredential(string.Empty, personalAccessToken));
            GitHttpClient gitClient = connection.GetClient<GitHttpClient>();
            //check whether specific commit id present which branch
            var commits = gitClient.GetCommitsAsync(project: project, repositoryId: repository, new GitQueryCommitsCriteria
            {
                ItemVersion = new GitVersionDescriptor
                {
                    Version = branch,
                    VersionType = GitVersionType.Branch
                }
            }).Result;
            foreach (var commit in commits)
            {
                Console.WriteLine(commit.CommitId);
                if (commit.CommitId == commit_id)
                {
                    //Console.WriteLine("Commit id present in branch");
                    exists = true;
                    return exists;
                }
            }
            return exists;
        }


        public static List<string> check_whether_present_in_branches(Uri orgUrl, string personalAccessToken, string project, string repository, string commit_id)
        {
            List<string> branches = new List<string>();
            VssConnection connection = new VssConnection(orgUrl, new VssBasicCredential(string.Empty, personalAccessToken));
            GitHttpClient gitClient = connection.GetClient<GitHttpClient>();
            var refs = gitClient.GetRefsAsync(project: project, repositoryId: repository).Result;
            foreach (var ref_ in refs)
            {
                //Console.WriteLine(ref_.Name);
                if (ref_.Name.StartsWith("refs/heads/"))
                {
                    var commits = gitClient.GetCommitsAsync(project: project, repositoryId: repository, new GitQueryCommitsCriteria
                    {
                        ItemVersion = new GitVersionDescriptor
                        {
                            //Version = ref_.Name,
                            //Version = (ref_.Name.Split('/'))[(ref_.Name.Split('/')).Length - 1],
                            Version = ref_.Name.Substring(11),
                           
                            VersionType = GitVersionType.Branch
                        }
                    }).Result;
                    foreach (var commit in commits)
                    {
                        //Console.WriteLine(commit.CommitId);
                        if (commit.CommitId == commit_id)
                        {
                            //Console.WriteLine("Commit id present in branch");
                            branches.Add(ref_.Name);
                        }
                    }
                }
                else
                {
                    continue;
                }
            }
            return branches;
        }

        //get lastest commit
        public static GitCommitRef GetLastestCommit(Uri orgUrl, string personalAccessToken, string project, string repoId, string branchName)
        {
            List<string> branches = new List<string>();
            VssConnection connection = new VssConnection(orgUrl, new VssBasicCredential(string.Empty, personalAccessToken));
            GitHttpClient gitClient = connection.GetClient<GitHttpClient>();
            var commit = gitClient.GetCommitsAsync(project: project, repositoryId: repoId, new GitQueryCommitsCriteria()
            {
                ItemVersion = new GitVersionDescriptor()
                {
                    Version = branchName,
                    VersionType = GitVersionType.Branch
                },
                Top = 1
            }).Result.FirstOrDefault();
            return commit;
        }
    }
}

enter image description here

Original Answer:

Provide a C# demo for you(I think I should have already considered all the situations):

using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
using System;
using System.Collections.Generic;

namespace CheckWhetherCommitExistInCurrentBranch
{
    class Program
    {
        static void Main(string[] args)
        {
            Uri orgUrl = new Uri("https://dev.azure.com/xxx/");         // Organization URL
            string project = "xxx";
            string repository = "xxx";
            String personalAccessToken = "xxx";
            string commit_id = "xxx";
            string branch_name = "xxx";

            //check whether the commit id exists in specific branch.
            bool exists = check_whether_present_in_branch(orgUrl,personalAccessToken,project,repository,commit_id,branch_name);
            Console.WriteLine("Whether commit id "+commit_id+" exists in "+branch_name+"? "+exists+"\n");

            //check what branches the commit id exists.
            List<string>  branches = check_whether_present_in_branches(orgUrl, personalAccessToken, project, repository, commit_id);
            foreach (var branch in branches)
            {
                Console.WriteLine("exists in "+branch);
            }
        }
        public static bool check_whether_present_in_branch(Uri orgUrl, string personalAccessToken, string project, string repository, string commit_id, string branch) {
            bool exists = false;
            VssConnection connection = new VssConnection(orgUrl, new VssBasicCredential(string.Empty, personalAccessToken));
            GitHttpClient gitClient = connection.GetClient<GitHttpClient>();
            //check whether specific commit id present which branch
            var commits = gitClient.GetCommitsAsync(project: project, repositoryId: repository, new GitQueryCommitsCriteria
            {
                ItemVersion = new GitVersionDescriptor
                {
                    Version = branch,
                    VersionType = GitVersionType.Branch
                }
            }).Result;
            foreach (var commit in commits)
            {
                Console.WriteLine(commit.CommitId);
                if (commit.CommitId == commit_id)
                {
                    //Console.WriteLine("Commit id present in branch");
                    exists = true;
                    return exists;
                }
            }
            return exists;
        }


        public static List<string> check_whether_present_in_branches(Uri orgUrl, string personalAccessToken, string project, string repository, string commit_id)
        {
            List<string> branches = new List<string>();
            VssConnection connection = new VssConnection(orgUrl, new VssBasicCredential(string.Empty, personalAccessToken));
            GitHttpClient gitClient = connection.GetClient<GitHttpClient>();
            var refs = gitClient.GetRefsAsync(project: project, repositoryId: repository).Result;
            foreach (var ref_ in refs)
            {
                //Console.WriteLine(ref_.Name);
                if (ref_.Name.StartsWith("refs/heads/"))
                {
                    var commits = gitClient.GetCommitsAsync(project: project, repositoryId: repository, new GitQueryCommitsCriteria
                    {
                        ItemVersion = new GitVersionDescriptor
                        {
                            //Version = ref_.Name,
                            Version = (ref_.Name.Split('/'))[(ref_.Name.Split('/')).Length - 1],
                            VersionType = GitVersionType.Branch
                        }
                    }).Result;
                    foreach (var commit in commits)
                    {
                        //Console.WriteLine(commit.CommitId);
                        if (commit.CommitId == commit_id)
                        {
                            //Console.WriteLine("Commit id present in branch");
                            branches.Add(ref_.Name);
                        }
                    }
                }
                else
                {
                    continue;
                }
            }
            return branches;
        }
    }
}

Results:

enter image description here

Bowman Zhu-MSFT
  • 4,776
  • 1
  • 9
  • 10
  • Is there any efficient way to get the latest commit of a particular branch using this package? – Vivek Nuna Sep 23 '22 at 18:22
  • @viveknuna Hi vivek, I think this is a new question, may be you can post a new question and let me know? And does my answer works for your current question? – Bowman Zhu-MSFT Sep 26 '22 at 03:28
  • I have raised a new question, Please have a look. https://stackoverflow.com/questions/73849788/is-there-any-efficient-way-to-get-the-latest-commit-of-a-particular-branch-using – Vivek Nuna Sep 26 '22 at 05:05
  • 1
    Its gives exception in a few cases, I have updated the question, please have a look. I have unaccepted the answer, I will accept it again once it handles this case – Vivek Nuna Oct 02 '22 at 04:41
  • @viveknuna Thanks for your feedback! I fixed the issue just now.:) And by the way, just want to confirm with you about [this case](https://stackoverflow.com/questions/73849788/is-there-any-efficient-way-to-get-the-latest-commit-of-a-particular-branch-using), does my answer of this case answered that question? – Bowman Zhu-MSFT Oct 03 '22 at 00:35
  • why are you using `continue`, I don’t think it’s required. And your solution is very very slow. Just imagine I have 500 branches and more than 5000 commits. So I can’t go with your solution @BowmanZhu-MSFT – Vivek Nuna Oct 03 '22 at 02:18
  • @viveknuna That is required because PR will also be captured via this SDK. – Bowman Zhu-MSFT Oct 03 '22 at 02:35
  • 1
    yes so no need to writing continue. It will also work even if you remove that `continue`. Try it once – Vivek Nuna Oct 03 '22 at 03:23
  • 1
    what about performance? Your solution is very slow. – Vivek Nuna Oct 03 '22 at 03:24
  • @viveknuna I don't think this sdk provides a ready-made method to detect the existence of a commit. I just share with you what you can do if you have to use this sdk to "detect the existence of a commit". Your original question did not mention the number of branches for your repo and the number of commits per branch. I've just tried 500+ branches with 5000+ commits in each branch, and indeed as you said it doesn't perform well with large amounts of data. How quickly do you expect results to be returned, and do you currently have other ways to get results quickly? If yes, how long will it take? – Bowman Zhu-MSFT Oct 03 '22 at 03:44
  • @viveknuna I'm really sorry that my answer did not meet your requirements in terms of performance. For continue, I know that it is ok not to write it. I thought you meant that the judgment statement where the continue is located is unnecessary, so I explain why this step is added. I agree with you, there is no need to add continue here. The reason for adding continue is that I don't use C# frequently, and I use python more, so I didn't leave blanks inside the conditional statement here. If you don't like it, you can delete the continue here. If you find a great solution, please share it here:) – Bowman Zhu-MSFT Oct 03 '22 at 03:46