[ACCEPTED]-Make TeamCity pull down all git branches-teamcity

Accepted answer
Score: 18

Starting from TeamCity 10.0.4, you can do 2 that by adding a configuration parameter 1 teamcity.git.fetchAllHeads=true See here

Score: 0

It turns out that (so far) there is no way 15 to do this nicely in TeamCity so in the 14 mean time this problem has been solved by 13 running an additional MsBuild script at 12 the start of the build process that verifies 11 whether the master branch is present in 10 the current (local) repository and getting 9 it if it is not.

The script looks like:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0"
         DefaultTargets="Run"
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <DirWorkspace>$(MSBuildProjectDirectory)</DirWorkspace>
        <DirRepository Condition=" '$(DirRepository)' == '' ">$(DirWorkspace)</DirRepository>
        <DirGit Condition=" '$(DirGit)' == '' ">c:\Program Files (x86)\Git\bin</DirGit>      
    </PropertyGroup>

    <Import Project="$(DirWorkspace)\GitHasMasterBranch.msbuild"
            Condition="Exists('$(DirWorkspace)\GitHasMasterBranch.msbuild')"/>  
    <Import Project="$(DirWorkspace)\GitGetMasterBranch.msbuild"
            Condition="Exists('$(DirWorkspace)\GitGetMasterBranch.msbuild')"/>  

    <Target Name="Run" DependsOnTargets="_DisplayInfo;_FetchOriginMasterIfNotExists">
        <!-- Do nothing here -->
    </Target>

    <!-- Display info -->
    <Target Name="_DisplayInfo">
        <Message Text="Preparing workspace ..." />
    </Target>

    <PropertyGroup>
        <ExeGit>$(DirGit)\git.exe</ExeGit>
    </PropertyGroup>
    <Target Name="_FetchOriginMasterIfNotExists" DependsOnTargets="_DisplayInfo">
        <GitHasMasterBranch LocalPath="$(DirRepository)">
            <Output TaskParameter="HasMaster" PropertyName="HasMaster" />
        </GitHasMasterBranch>

        <Message Text="Not fetching master branch because it already exists" Condition="($(HasMaster))" />
        <Message Text="Fetching master branch because it does not exist" Condition="(!$(HasMaster))" />
        <GitGetMasterBranch LocalPath="$(DirRepository)" Condition="(!$(HasMaster))"/>
    </Target>
 </Project>

In 8 this script the GitHasMasterBranch MsBuild inline script looks 7 like:

<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' 
         ToolsVersion="4.0">
    <UsingTask TaskName="GitHasMasterBranch" 
               TaskFactory="CodeTaskFactory" 
               AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
        <ParameterGroup>
            <LocalPath ParameterType="System.String" Required="true" />
            <HasMaster ParameterType="System.Boolean" Output="true" />
        </ParameterGroup>
        <Task>
            <Code Type="Method" Language="cs">
                <![CDATA[
                    public override bool Execute()
                    {
                        var info = new System.Diagnostics.ProcessStartInfo
                                {
                                    FileName = "git",
                                    Arguments = "branch",
                                    WorkingDirectory = LocalPath,
                                    UseShellExecute = false,
                                    RedirectStandardOutput = true,
                                    RedirectStandardError = true,
                                };

                        var text = new System.Text.StringBuilder();
                        var process = new System.Diagnostics.Process();
                        process.StartInfo = info;
                        process.OutputDataReceived += 
                            (s, e) => 
                            { 
                                text.Append(e.Data);
                            };
                        process.ErrorDataReceived += 
                            (s, e) => 
                            { 
                                if (!string.IsNullOrWhiteSpace(e.Data))
                                {
                                    Log.LogError(e.Data); 
                                }
                            };
                        process.Start();

                        process.BeginOutputReadLine();
                        process.BeginErrorReadLine();
                        process.WaitForExit();

                        HasMaster = text.ToString().Contains("* master");

                        // Log.HasLoggedErrors is true if the task logged any errors -- even if they were logged 
                        // from a task's constructor or property setter. As long as this task is written to always log an error
                        // when it fails, we can reliably return HasLoggedErrors.
                        return !Log.HasLoggedErrors;
                    }
                ]]>  
            </Code>
        </Task>
    </UsingTask>
</Project>

And the GitGetMasterBranch MsBuild inline script looks 6 like:

<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' 
         ToolsVersion="4.0">
    <UsingTask TaskName="GitGetMasterBranch" 
               TaskFactory="CodeTaskFactory" 
               AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
        <ParameterGroup>
            <LocalPath ParameterType="System.String" Required="true" />
        </ParameterGroup>
        <Task>
            <Code Type="Method" Language="cs">
                <![CDATA[
                    public override bool Execute()
                    {
                        // Get the name of the current branch
                        var info = new System.Diagnostics.ProcessStartInfo
                                {
                                    FileName = "git",
                                    Arguments = "symbolic-ref --short -q HEAD",
                                    WorkingDirectory = LocalPath,
                                    UseShellExecute = false,
                                    RedirectStandardOutput = true,
                                    RedirectStandardError = true,
                                };

                        var text = new System.Text.StringBuilder();
                        var process = new System.Diagnostics.Process();
                        process.StartInfo = info;
                        process.OutputDataReceived += 
                            (s, e) => 
                            { 
                                text.Append(e.Data);
                            };
                        process.Start();

                        process.BeginOutputReadLine();
                        process.BeginErrorReadLine();
                        process.WaitForExit();

                        var currentBranch = text.ToString().Trim();

                        // git fetch
                        info = new System.Diagnostics.ProcessStartInfo
                                {
                                    FileName = "git",
                                    Arguments = "fetch origin",
                                    WorkingDirectory = LocalPath,
                                    UseShellExecute = false,
                                    RedirectStandardOutput = true,
                                    RedirectStandardError = true,
                                };

                        process = new System.Diagnostics.Process();
                        process.StartInfo = info;
                        process.OutputDataReceived += 
                            (s, e) => 
                            { 
                                if (!string.IsNullOrWhiteSpace(e.Data))
                                {
                                    Log.LogMessage(MessageImportance.High, e.Data);
                                }
                            };
                        process.Start();

                        process.BeginOutputReadLine();
                        process.BeginErrorReadLine();
                        process.WaitForExit();

                        // git checkout master
                        info = new System.Diagnostics.ProcessStartInfo
                                {
                                    FileName = "git",
                                    Arguments = "checkout master",
                                    WorkingDirectory = LocalPath,
                                    UseShellExecute = false,
                                    RedirectStandardOutput = true,
                                    RedirectStandardError = true,
                                };

                        process = new System.Diagnostics.Process();
                        process.StartInfo = info;
                        process.OutputDataReceived += 
                            (s, e) => 
                            { 
                                if (!string.IsNullOrWhiteSpace(e.Data))
                                {
                                    Log.LogMessage(MessageImportance.High, e.Data);
                                }
                            };
                        process.Start();

                        process.BeginOutputReadLine();
                        process.BeginErrorReadLine();
                        process.WaitForExit();

                        // git pull
                        info = new System.Diagnostics.ProcessStartInfo
                                {
                                    FileName = "git",
                                    Arguments = "pull",
                                    WorkingDirectory = LocalPath,
                                    UseShellExecute = false,
                                    RedirectStandardOutput = true,
                                    RedirectStandardError = true,
                                };

                        process = new System.Diagnostics.Process();
                        process.StartInfo = info;
                        process.OutputDataReceived += 
                            (s, e) => 
                            { 
                                if (!string.IsNullOrWhiteSpace(e.Data))
                                {
                                    Log.LogMessage(MessageImportance.High, e.Data);
                                }
                            };
                        process.Start();

                        process.BeginOutputReadLine();
                        process.BeginErrorReadLine();
                        process.WaitForExit();

                        // git checkout <CURRENT_BRANCH>
                        info = new System.Diagnostics.ProcessStartInfo
                                {
                                    FileName = "git",
                                    Arguments = string.Format("checkout {0}", currentBranch),
                                    WorkingDirectory = LocalPath,
                                    UseShellExecute = false,
                                    RedirectStandardOutput = true,
                                    RedirectStandardError = true,
                                };

                        process = new System.Diagnostics.Process();
                        process.StartInfo = info;
                        process.OutputDataReceived += 
                            (s, e) => 
                            { 
                                if (!string.IsNullOrWhiteSpace(e.Data))
                                {
                                    Log.LogMessage(MessageImportance.High, e.Data);
                                }
                            };
                        process.Start();

                        process.BeginOutputReadLine();
                        process.BeginErrorReadLine();
                        process.WaitForExit();

                        // Log.HasLoggedErrors is true if the task logged any errors -- even if they were logged 
                        // from a task's constructor or property setter. As long as this task is written to always log an error
                        // when it fails, we can reliably return HasLoggedErrors.
                        return !Log.HasLoggedErrors;
                    }
                ]]>  
            </Code>
        </Task>
    </UsingTask>
</Project>

Essentially all this last script does 5 is to store the current branch name, perform 4 a GIT fetch to get all the branches, perform a GIT checkout of 3 the master branch and then perform a GIT checkout of 2 the original branch.

It's not the fastest 1 approach but it works for now.

More Related questions