Skip to content

Added support for remote repositories (with and without authentication) #101

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

Merged
merged 12 commits into from
Mar 20, 2014
Merged
Show file tree
Hide file tree
Changes from 5 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
36 changes: 30 additions & 6 deletions GitVersion/ArgumentParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ public static Arguments ParseArguments(List<string> commandLineArguments)
if (commandLineArguments.Count == 0)
{
return new Arguments
{
TargetPath = Environment.CurrentDirectory
};
{
TargetPath = Environment.CurrentDirectory
};
}

var firstArgument = commandLineArguments.First();
Expand All @@ -33,9 +33,9 @@ public static Arguments ParseArguments(List<string> commandLineArguments)
if (commandLineArguments.Count == 1)
{
return new Arguments
{
TargetPath = firstArgument
};
{
TargetPath = firstArgument
};
}

List<string> namedArguments;
Expand Down Expand Up @@ -64,6 +64,30 @@ public static Arguments ParseArguments(List<string> commandLineArguments)
continue;
}

if (IsSwitch("url", name))
{
arguments.TargetUrl = value;
continue;
}

if (IsSwitch("b", name))
{
arguments.TargetBranch = value;
continue;
}

if (IsSwitch("u", name))
{
arguments.Username = value;
continue;
}

if (IsSwitch("p", name))
{
arguments.Password = value;
continue;
}

if ((IsSwitch("v", name)) && VersionParts.Contains(value.ToLower()))
{
arguments.VersionPart = value.ToLower();
Expand Down
7 changes: 7 additions & 0 deletions GitVersion/Arguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ namespace GitVersion
class Arguments
{
public string TargetPath;

public string TargetUrl;
public string TargetBranch;

public string Username;
public string Password;

public bool IsHelp;
public string LogFilePath;
public string VersionPart;
Expand Down
1 change: 1 addition & 0 deletions GitVersion/BuildServers/GitHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public static void NormalizeGitDirectory(string gitDirectory)

static FetchOptions BuildFetchOptions()
{
// TODO: Respect username/password of arguments?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

@andreasohlund What's your take about this? How should we behave when both arguments and environment variables are valued? Which one should we consider?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say commandline first, then fallback to env?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Commandline should override general settings.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say commandline first, then fallback to env?

I agree. Commandline should override general settings.

@GeertvanHorrik Makes sense. Could you please update the PR to cope with this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Working on it. I will pass the arguments around everywhere then. Normally I would use an IoC container to inject the arguments automatically, but since this app is so simple, I will just pass it into the ctors manually.

var username = Environment.GetEnvironmentVariable("GITVERSION_REMOTE_USERNAME");
var password = Environment.GetEnvironmentVariable("GITVERSION_REMOTE_PASSWORD");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,7 @@ int NumberOfCommitsInBranchNotKnownFromBaseBranch(
BranchType branchType,
string baseBranchName)
{
var baseTip = repo.Branches[baseBranchName].Tip;

var baseTip = repo.FindBranch(baseBranchName).Tip;
if (branch.Tip == baseTip)
{
// The branch bears no additional commit
Expand Down
106 changes: 106 additions & 0 deletions GitVersion/GitPreparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
namespace GitVersion
{
using System.IO;
using LibGit2Sharp;

public class GitPreparer
{
public GitPreparer(string targetPath, string url, string branchName, string username, string password)
{
TargetPath = targetPath;
Url = url;
BranchName = branchName;
Username = username;
Password = password;
}

public string TargetPath { get; private set; }

public string Url { get; private set; }

public string BranchName { get; private set; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this property leveraged by the code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, you are right. Let me check...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, good catch!


public string Username { get; private set; }

public string Password { get; private set; }

public bool IsDynamicGitRepository
{
get { return !string.IsNullOrWhiteSpace(DynamicGitRepositoryPath); }
}

public string DynamicGitRepositoryPath { get; private set; }

public string Prepare()
{
var gitPath = TargetPath;

if (!string.IsNullOrWhiteSpace(Url))
{
gitPath = GetGitInfoFromUrl();
}

return GitDirFinder.TreeWalkForGitDir(gitPath);
}

private string GetGitInfoFromUrl()
{
var gitDirectory = Path.Combine(TargetPath, "_dynamicrepository", ".git");
if (Directory.Exists(gitDirectory))
{
Logger.WriteInfo(string.Format("Deleting existing .git folder from '{0}' to force new checkout from url", gitDirectory));

DeleteHelper.DeleteGitRepository(gitDirectory);
}

Credentials credentials = null;
if (!string.IsNullOrWhiteSpace(Username) && !string.IsNullOrWhiteSpace(Password))
{
Logger.WriteInfo(string.Format("Setting up credentials using name '{0}'", Username));

credentials = new Credentials()
{
Username = Username,
Password = Password
};
}

Logger.WriteInfo(string.Format("Retrieving git info from url '{0}'", Url));

Repository.Clone(Url, gitDirectory, checkout: false, credentials: credentials);

if (!string.IsNullOrWhiteSpace(BranchName))
{
// Normalize (download branches) before using the branch
GitHelper.NormalizeGitDirectory(gitDirectory);

using (var repository = new Repository(gitDirectory))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we just check the branch out?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have an easier way, yes. But I couldn't find it (clone doesn't support default branch to check out). I don't want to download all the files though (since this might be a lot of data).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the repository is already fully downloaded, I think that something like this should work (Warning: untested code)

var branchName = "..."
var b = repo.FindBranch(branchName);
repo.Checkout(b, CheckoutModifiers.Force);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That code works, but is much slower. Just let me know what you prefer, I don't mind what is being used in the end.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That code works, but is much slower

Hmmm. You're right. We don't actually need to check the files out.

How about

var branchName = "..."
var b = repo.FindBranch(branchName);
Debug.Assert(b != null);
repo.Refs.UpdateTarget("HEAD", b.CanonicalName);
Logger.WriteInfo(string.Format("Moving HEAD to branch '{0}'", b.CanonicalName));

That should work 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pushed (with other options commented out). This works great and is slightly simpler than what we had before.

{
var targetBranchName = string.Format("refs/heads/{0}", BranchName);
if (!string.Equals(repository.Head.CanonicalName, targetBranchName))
{
Logger.WriteInfo(string.Format("Switching to branch '{0}'", BranchName));

var branch = repository.FindBranch(BranchName);
if ((branch != null) && !branch.IsCurrentRepositoryHead)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this line (and the one above) can be safely dropped

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

{
// Option 1: checkout (slow)
//repository.Checkout(branch, CheckoutModifiers.Force, null, null);

// Option 2: add head refs
//var finalName = string.Format("refs/heads/{0}", BranchName);
//repository.Refs.Add("HEAD", finalName, true);

// Option 3: replace head
repository.Refs.UpdateTarget("HEAD", branch.CanonicalName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and branch.CanonicalName replaced by targetBranchName

}
}
}
}

DynamicGitRepositoryPath = gitDirectory;

return gitDirectory;
}
}
}
2 changes: 2 additions & 0 deletions GitVersion/GitVersion.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
<Compile Include="GitHubFlow\LastTaggedReleaseFinder.cs" />
<Compile Include="GitHubFlow\NextSemverCalculator.cs" />
<Compile Include="GitHubFlow\NextVersionTxtFileFinder.cs" />
<Compile Include="GitPreparer.cs" />
<Compile Include="Helpers\DeleteHelper.cs" />
<Compile Include="OutputFormatters\BuildOutputFormatter.cs" />
<Compile Include="BuildServers\BuildServerList.cs" />
<Compile Include="BuildServers\ContinuaCi.cs" />
Expand Down
8 changes: 6 additions & 2 deletions GitVersion/HelpWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ public static void Write()

GitVersion [path] [/l logFilePath]

path The directory containing .git. If not defined current directory is used.
/l Path to logfile.
path The directory containing .git. If not defined current directory is used.
/url Url to remote git repository.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: tabs vs spaces identations

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

/b Name of the branch to use on the remote repository, must be used in combination with /url.
/u Username in case authentication is required.
/p Password in case authentication is required.
/l Path to logfile.
";
Console.Write(message);
}
Expand Down
27 changes: 27 additions & 0 deletions GitVersion/Helpers/DeleteHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace GitVersion
{
using System.IO;

public static class DeleteHelper
{
public static void DeleteGitRepository(string directory)
{
if (string.IsNullOrEmpty(directory))
{
return;
}

foreach (var fileName in Directory.GetFiles(directory, "*.*", SearchOption.AllDirectories))
{
var fileInfo = new FileInfo(fileName)
{
IsReadOnly = false
};

fileInfo.Delete();
}

Directory.Delete(directory, true);
}
}
}
7 changes: 4 additions & 3 deletions GitVersion/LibGitExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ public static Branch FindBranch(this IRepository repository, string branchName)
return exact;
}

return repository.Branches.FirstOrDefault(x => x.Name == "origin/"+branchName);
}
return repository.Branches.FirstOrDefault(x => x.Name == "origin/" + branchName);
}

public static SemanticVersion NewestSemVerTag(this IRepository repository, Commit commit)
{
Expand All @@ -43,6 +43,7 @@ public static SemanticVersion NewestSemVerTag(this IRepository repository, Commi
return version;
}
}

return null;
}

Expand All @@ -67,7 +68,7 @@ public static GitObject PeeledTarget(this Tag tag)

while (target is TagAnnotation)
{
target = ((TagAnnotation) (target)).Target;
target = ((TagAnnotation)(target)).Target;
}

return target;
Expand Down
Loading