public override void Merge(string sourceBranch, string destinationBranch) { _repo.Checkout(_repo.Branches[destinationBranch]); var oldHeadCommit = _repo.Head.Tip; var signature = GetSignature(); var result = _repo.Merge(_repo.Branches[sourceBranch], signature); switch (result.Status) { case MergeStatus.Conflicts: _repo.Reset(ResetMode.Hard, oldHeadCommit); break; case MergeStatus.NonFastForward: //https://help.github.com/articles/dealing-with-non-fast-forward-errors/ Pull(); Merge(sourceBranch, destinationBranch); //a little leary about this. Could stack overflow if I'm wrong. break; default: break; } base.Merge(sourceBranch, destinationBranch); }
public override void Checkout(string branch) { try { _repo.Checkout(_repo.Branches[branch]); base.Checkout(branch); RequeryUnsyncedCommits(); } catch (LibGit2SharpException ex) { throw new SourceControlException(SourceControlText.GitCheckoutFailed, ex); } }
public void GenerateSpecificVersion(RepositoryUrl repositoryUrl, string commit) { var pathResolver = new PathResolver(repositoryUrl.Url, commit); var repositoryFolder = pathResolver.GetRepositoryPath(); var repository = new Repository(repositoryFolder + "/.git"); repository.Checkout(commit); var commitFolder = pathResolver.GetVersionPath(); Directory.CreateDirectory(commitFolder); DirectoryCopy(repositoryFolder, commitFolder, true); repository.Checkout(repository.Branches["master"]); }
public Branch Checkout(string branch) { using (var repo = new Repository(_settings.Workspace)) { return repo.Checkout(branch); } }
public void GivenARemoteGitRepositoryWithCommitsAndBranches_ThenClonedLocalShouldMatchRemoteVersion() { using (var fixture = new RemoteRepositoryFixture( path => { Repository.Init(path); Console.WriteLine("Created git repository at '{0}'", path); var repo = new Repository(path); repo.MakeCommits(5); repo.CreateBranch("develop"); repo.CreateBranch("release-1.0"); repo.Checkout("release-1.0"); repo.MakeCommits(5); return repo; }, new Config())) { fixture.AssertFullSemver("1.0.0-beta.1+5"); fixture.AssertFullSemver("1.0.0-beta.1+5", fixture.LocalRepository); } }
public void GivenARemoteGitRepositoryWithCommitsAndBranches_ThenClonedLocalShouldMatchRemoteVersion() { using (var fixture = new RemoteRepositoryFixture( path => { Repository.Init(path); Console.WriteLine("Created git repository at '{0}'", path); var repo = new Repository(path); repo.MakeCommits(5); repo.CreateBranch("develop"); repo.CreateBranch("release-1.0"); repo.Checkout("release-1.0"); repo.MakeCommits(5); return repo; })) { GitRepositoryHelper.NormalizeGitDirectory(fixture.LocalRepositoryFixture.RepositoryPath, new AuthenticationInfo(), noFetch: false, currentBranch: string.Empty); fixture.AssertFullSemver("1.0.0-beta.1+5"); fixture.AssertFullSemver("1.0.0-beta.1+5", fixture.LocalRepositoryFixture.Repository); } }
public static void NormalizeGitDirectory(string gitDirectory, Arguments arguments, string branch = null) { using (var repo = new Repository(gitDirectory)) { var remote = EnsureOnlyOneRemoteIsDefined(repo); AddMissingRefSpecs(repo, remote); Logger.WriteInfo(string.Format("Fetching from remote '{0}' using the following refspecs: {1}.", remote.Name, string.Join(", ", remote.FetchRefSpecs.Select(r => r.Specification)))); var fetchOptions = BuildFetchOptions(arguments.Username, arguments.Password); repo.Network.Fetch(remote, fetchOptions); CreateMissingLocalBranchesFromRemoteTrackingOnes(repo, remote.Name); if (!repo.Info.IsHeadDetached) { Logger.WriteInfo(string.Format("HEAD points at branch '{0}'.", repo.Refs.Head.TargetIdentifier)); return; } Logger.WriteInfo(string.Format("HEAD is detached and points at commit '{0}'.", repo.Refs.Head.TargetIdentifier)); if (branch != null) { Logger.WriteInfo(string.Format("Checking out local branch 'refs/heads/{0}'.", branch)); repo.Checkout("refs/heads/" + branch); } else { CreateFakeBranchPointingAtThePullRequestTip(repo); } } }
public void CheckOut( string branchName ) { using( var r = new Repository( Path ) ) { Branch b = r.Branches[branchName]; r.Checkout( b, new CheckoutOptions() { CheckoutModifiers = CheckoutModifiers.Force } ); } }
public static void Main(string[] args) { try { log("started..."); var repoUrl = args[0]; var branchName = "master"; var username = args[1]; var password = ""; if (args.Length == 3) { password = args[2]; } var pathSplit = repoUrl.Split('/'); var repoName = pathSplit.Last(); var author = new Signature("scarletapi", "@gmail", DateTime.Now); var repoDir = new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), repoName)); var repoPath = repoDir.FullName; if (String.IsNullOrEmpty(username)) { throw new Exception("Must have username"); } if (String.IsNullOrEmpty(password)) { repoUrl = repoUrl.Replace(pathSplit[2], String.Format("{0}@{2}", username, password, pathSplit[2])); } else { repoUrl = repoUrl.Replace(pathSplit[2], String.Format("{0}:{1}@{2}", username, password, pathSplit[2])); } log("checking if repo exists"); if (!repoDir.Exists || !Repository.IsValid(repoPath)) { if (repoDir.Exists) { repoDir.Delete(true); } var cloneOptions = new CloneOptions(); cloneOptions.BranchName = branchName; log("cloning {0} repository at url {1}", repoName, repoUrl); repoUrl = Repository.Clone(repoUrl, repoPath, cloneOptions); using (var repo = new LibGit2Sharp.Repository(repoPath)) { repo.Checkout(repo.Branches[branchName], new CheckoutOptions()); } } } catch (Exception e) { log("ERROR: {0}", e.Message); } }
public void Update(string id) { using (var repo = new LibGit2Sharp.Repository(RepositoryPath)) { repo.Checkout(id, new CheckoutOptions { CheckoutModifiers = CheckoutModifiers.Force }); } }
public void CreateOrResetBranch(string branchName, string startPoint) { using (var repo = new LibGit2Sharp.Repository(RepositoryPath)) { if (string.IsNullOrWhiteSpace(startPoint)) { var branch = repo.GetOrCreateBranch(branchName); repo.Checkout(branch); } else { var commit = repo.Lookup <Commit>(startPoint); if (commit == null) { throw new LibGit2Sharp.NotFoundException(string.Format("Start point \"{0}\" for reset was not found.", startPoint)); } var branch = repo.GetOrCreateBranch(branchName); repo.Checkout(branch); repo.Reset(ResetMode.Hard, commit); } } }
public void GivenARemoteWithATagOnMaster_AndAPullRequestWithTwoCommits_AndBuildIsRunningInTeamCity_VersionIsCalculatedProperly(string pullRequestRef) { using (var fixture = new EmptyRepositoryFixture()) { var remoteRepositoryPath = PathHelper.GetTempPath(); Repository.Init(remoteRepositoryPath); using (var remoteRepository = new Repository(remoteRepositoryPath)) { remoteRepository.Config.Set("user.name", "Test"); remoteRepository.Config.Set("user.email", "*****@*****.**"); fixture.Repository.Network.Remotes.Add("origin", remoteRepositoryPath); Console.WriteLine("Created git repository at {0}", remoteRepositoryPath); remoteRepository.MakeATaggedCommit("1.0.3"); var branch = remoteRepository.CreateBranch("FeatureBranch"); remoteRepository.Checkout(branch); remoteRepository.MakeCommits(2); remoteRepository.Checkout(remoteRepository.Head.Tip.Sha); //Emulate merge commit var mergeCommitSha = remoteRepository.MakeACommit().Sha; remoteRepository.Checkout("master"); // HEAD cannot be pointing at the merge commit remoteRepository.Refs.Add(pullRequestRef, new ObjectId(mergeCommitSha)); // Checkout PR commit Commands.Fetch((Repository)fixture.Repository, "origin", new string[0], new FetchOptions(), null); fixture.Repository.Checkout(mergeCommitSha); } var result = GitVersionHelper.ExecuteIn(fixture.RepositoryPath, isTeamCity: true); result.ExitCode.ShouldBe(0); result.OutputVariables.FullSemVer.ShouldBe("1.0.4-PullRequest0005.3"); // Cleanup repository files DirectoryHelper.DeleteDirectory(remoteRepositoryPath); } }
public void NServiceBusDevelopOlderCommit() { using (var repository = new Repository(@"C:\Code\NServiceBus")) { var branch = repository.Branches.First(x => x.Name == "develop"); repository.Checkout("c0e0a5e13775552cd3e08e039f453e4cf1fd4235"); var finder = new GitVersionFinder(); var version = finder.FindVersion(new GitVersionContext(repository, branch, new Config())); Debug.WriteLine(version.Major); Debug.WriteLine(version.Minor); Debug.WriteLine(version.Patch); Debug.WriteLine(version.PreReleaseTag); Debug.WriteLine(version.BuildMetaData); } }
public RepositoryWrapper(Repository repo) { this.repo = repo; Head = async (i) => { return new BranchWrapper(repo, repo.Head); }; Config = async (i) => { return repo.Config; }; Index = async (i) => { return repo.Index; }; Ignore = async (i) => { return repo.Ignore; }; Network = async (i) => { return new NetworkWrapper(repo.Network); }; ObjectDatabase = async (i) => { return repo.ObjectDatabase; }; Refs = async (i) => { return repo.Refs; }; Commits = async (i) => { return repo.Commits.Select(c => new CommitWrapper(c)); }; Tags = async (i) => { return repo.Tags; }; Stashes = async (i) => { return repo.Stashes; }; Info = async (i) => { return repo.Info; }; Diff = async (i) => { return repo.Diff; }; Notes = async (i) => { return repo.Notes; }; Submodules = async (i) => { return repo.Submodules; }; Dispose = async (i) => { repo.Dispose(); return null; }; Lookup = async (id) => { var found = repo.Lookup(id.ToString()); if (found.GetType() == typeof(Commit)) { return new CommitWrapper((Commit)found); } else { return found; } }; Branches = async (i) => repo.Branches.Select(b => new BranchWrapper(repo, b)).ToDictionary(b => b.Name); Reset = async (dynamic i) => { var modeName = ((string)i.mode).ToLower(); ResetMode mode; if (modeName == "soft") { mode = ResetMode.Soft; } else if (modeName == "mixed") { mode = ResetMode.Mixed; } else { mode = ResetMode.Hard; } var committish = (string)i.committish; repo.Reset(mode, committish, null, null); return null; }; Checkout = async (i) => { var branch = repo.Branches.First(b => b.Name == i.ToString()); repo.Checkout(branch); return branch; }; }
private static void CreateFakeBranchPointingAtThePullRequestTip(Repository repo) { var remote = repo.Network.Remotes.Single(); var remoteTips = repo.Network.ListReferences(remote); var headTipSha = repo.Head.Tip.Sha; var refs = remoteTips.Where(r => r.TargetIdentifier == headTipSha).ToList(); if (refs.Count == 0) { Log.ErrorAndThrowException<GitLinkException>("Couldn't find any remote tips from remote '{0}' pointing at the commit '{1}'.", remote.Url, headTipSha); } if (refs.Count > 1) { var names = string.Join(", ", refs.Select(r => r.CanonicalName)); Log.ErrorAndThrowException<GitLinkException>("Found more than one remote tip from remote '{0}' pointing at the commit '{1}'. Unable to determine which one to use ({2}).", remote.Url, headTipSha, names); } var canonicalName = refs[0].CanonicalName; Log.Info("Found remote tip '{0}' pointing at the commit '{1}'.", canonicalName, headTipSha); if (!canonicalName.StartsWith("refs/pull/")) { Log.ErrorAndThrowException<Exception>("Remote tip '{0}' from remote '{1}' doesn't look like a valid pull request.", canonicalName, remote.Url); } var fakeBranchName = canonicalName.Replace("refs/pull/", "refs/heads/pull/"); Log.Info("Creating fake local branch '{0}'.", fakeBranchName); repo.Refs.Add(fakeBranchName, new ObjectId(headTipSha)); Log.Info("Checking local branch '{0}' out.", fakeBranchName); repo.Checkout(fakeBranchName); }
static void Main(string[] args) { string repopath = @"C:\users\rasquill\documents\github\azure-docs-pr\"; List<TOC> TOCs = new List<TOC>(); using (Repository repo = new Repository(repopath)) { repo.Checkout("master"); //Console.WriteLine(repo.Index.Count()); var tocfiles = (from f in repo.Index where f.Path.Contains("TOC.md") && f.Path.Contains(@"articles\") select f.Path); foreach (var tocfile in tocfiles) { //Console.WriteLine(File.ReadAllText(repo.Info.WorkingDirectory + tocfile)); TOCs.Add(new TOC(repo.Info.WorkingDirectory + tocfile)); } } Console.ReadLine(); }
public void NServiceBusReleaseSpecificCommit() { using (var repository = new Repository(@"C:\Code\NServiceBus")) { var branch = repository.Branches.First(x => x.Name == "release-4.1.0"); repository.Checkout("c0e0a5e13775552cd3e08e039f453e4cf1fd4235"); var finder = new GitVersionFinder(); var version = finder.FindVersion(new GitVersionContext { Repository = repository, CurrentBranch = branch }); Debug.WriteLine(version.Major); Debug.WriteLine(version.Minor); Debug.WriteLine(version.Patch); Debug.WriteLine(version.PreReleaseTag); Debug.WriteLine(version.BuildMetaData); } }
private static bool Pull(string directory) { try { using (var repo = new Repository(directory)) { Utility.Log(LogStatus.Info, "Pull", directory, Logs.MainLog); repo.Reset(ResetMode.Hard); repo.RemoveUntrackedFiles(); repo.Network.Pull( new Signature(Config.Instance.Username, $"{Config.Instance.Username}@joduska.me", DateTimeOffset.Now), new PullOptions { MergeOptions = new MergeOptions { FastForwardStrategy = FastForwardStrategy.Default, FileConflictStrategy = CheckoutFileConflictStrategy.Theirs, MergeFileFavor = MergeFileFavor.Theirs, CommitOnSuccess = true } }); repo.Checkout(repo.Head, new CheckoutOptions { CheckoutModifiers = CheckoutModifiers.Force }); if (repo.Info.IsHeadDetached) { Utility.Log(LogStatus.Error, "Pull", "Update+Detached", Logs.MainLog); } } return true; } catch (Exception e) { Utility.Log(LogStatus.Error, "Pull", e.Message, Logs.MainLog); return false; } }
public static void Main(string[] args) { try { log("started..."); var repoUrl = args[0]; var branchName = "master"; var username = args[1]; var password = ""; if (args.Length == 3) { password = args[2]; } var fileSpec = args[3]; if (fileSpec.Contains('/')) { fileSpec = fileSpec.Replace("/", "\\"); } var pathSplit = repoUrl.Split('/'); var repoName = pathSplit.Last(); var fileInfo = new FileInfo(Path.Combine(Directory.GetCurrentDirectory(), repoName, fileSpec)); var author = new Signature("scarletapi", "@gmail", DateTime.Now); var repoDir = new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), repoName)); var repoPath = repoDir.FullName; if (String.IsNullOrEmpty(username)) { throw new Exception("Must have username"); } if (String.IsNullOrEmpty(password)) { repoUrl = repoUrl.Replace(pathSplit[2], String.Format("{0}@{2}", username, password, pathSplit[2])); } else { repoUrl = repoUrl.Replace(pathSplit[2], String.Format("{0}:{1}@{2}", username, password, pathSplit[2])); } log("checking if repo is valid"); if (Repository.IsValid(repoPath)) { log("repo is valid"); using (var repo = new LibGit2Sharp.Repository(repoPath)) { var remoteBranch = repo.Branches[branchName]; repo.Stage(fileInfo.FullName); repo.Checkout(remoteBranch, new CheckoutOptions()); repo.Network.Pull( author, new PullOptions()); repo.Unstage(fileInfo.FullName); if (!fileInfo.Exists) { log("WARNING: file does not exist {0}", fileInfo.FullName); } log("attempting to get latest, add, commit and pushing to {0}", repoName); var uri = new Uri(repo.Info.WorkingDirectory); log("working directory uri: {0}", uri.OriginalString); log("adding file: {0}", fileInfo.FullName); uri = uri.MakeRelativeUri(new Uri(fileInfo.FullName)); repo.Index.Add(uri.OriginalString); var commit = repo.Commit("API Auto Commit", author, author); repo.Refs.UpdateTarget(repo.Refs.Head, commit.Id); var options = new LibGit2Sharp.PushOptions(); repo.Network.Push(remoteBranch, options); log("file {0} was pushed to {1}", fileSpec, repoName); } } else { log("repo is NOT valid"); } } catch (Exception e) { log("ERROR: {0}", e.Message); } }
protected void FetchGitSourceLocally(TemplateSource source, string destFolder) { if (source == null) { throw new ArgumentNullException("source"); } if (string.IsNullOrEmpty(destFolder)) { throw new ArgumentNullException("destFolder"); } // TODO: these methods should be renamed since fetch means something in git try { var destDirInfo = new DirectoryInfo(destFolder); if (destDirInfo.Exists) { ResetDirectoryAttributes(destDirInfo); // TODO: if the folder exists and there is a .git folder then we should do a fetch/merge or pull destDirInfo.Delete(true); } // clone it var repoPath = Repository.Clone(source.Location.AbsoluteUri, destFolder); var repo = new Repository(repoPath); Branch branch = repo.Checkout(source.Branch); branch.Checkout(); } catch (Exception ex) { UpdateStatusBar("There was an error check the activity log"); // TODO: we should log this error string msg = ex.ToString(); System.Windows.Forms.MessageBox.Show(msg); } }
static void CreateOrUpdateLocalBranchesFromRemoteTrackingOnes(Repository repo, string remoteName) { var prefix = string.Format("refs/remotes/{0}/", remoteName); var remoteHeadCanonicalName = string.Format("{0}{1}", prefix, "HEAD"); foreach (var remoteTrackingReference in repo.Refs.FromGlob(prefix + "*").Where(r => r.CanonicalName != remoteHeadCanonicalName)) { var remoteTrackingReferenceName = remoteTrackingReference.CanonicalName; var branchName = remoteTrackingReferenceName.Substring(prefix.Length); var localCanonicalName = "refs/heads/" + branchName; if (repo.Refs.Any(x => x.CanonicalName == localCanonicalName)) { var localRef = repo.Refs[localCanonicalName]; var remotedirectReference = remoteTrackingReference.ResolveToDirectReference(); if (localRef.ResolveToDirectReference().TargetIdentifier == remotedirectReference.TargetIdentifier) { Logger.WriteInfo(string.Format("Skipping update of '{0}' as it already matches the remote ref.", remoteTrackingReference.CanonicalName)); continue; } var remoteRefTipId = remotedirectReference.Target.Id; Logger.WriteInfo(string.Format("Updating local ref '{0}' to point at {1}.", localRef.CanonicalName, remoteRefTipId)); repo.Refs.UpdateTarget(localRef, remoteRefTipId); repo.Checkout(branchName); continue; } Logger.WriteInfo(string.Format("Creating local branch from remote tracking '{0}'.", remoteTrackingReference.CanonicalName)); repo.Refs.Add(localCanonicalName, new ObjectId(remoteTrackingReference.ResolveToDirectReference().TargetIdentifier), true); var branch = repo.Branches[branchName]; repo.Branches.Update(branch, b => b.TrackedBranch = remoteTrackingReferenceName); } }
public void When_The_Main_Branch_Has_More_Commits_Than_A_Ref_Branch_It_Should_Not_Be_Deletable() { /* Setup */ // First commit File.WriteAllText(Path.Combine(_repoPath, "file1.txt"), "File1's content..."); _repo.Stage("file1.txt"); _repo.Commit("First commit..."); // Checkout new branch _repo.CreateBranch("newBranch"); _repo.Checkout("newBranch"); // Second commit File.WriteAllText(Path.Combine(_repoPath, "file2.txt"), "File2's content..."); _repo.Stage("file2.txt"); _repo.Commit("Second commit..."); // Prepare for comparison var mainBranch = _repo.Branches["newBranch"]; var refBranch = _repo.Branches["master"]; /* Test */ var result = _selector.CompareBranches(new Gitcomparer.Core.Model.Branch(mainBranch), new Gitcomparer.Core.Model.Branch(refBranch)); /* Assert */ Assert.That(result.MainBranch.Name, Is.EqualTo(mainBranch.Name)); Assert.That(result.RefBranch.Name, Is.EqualTo(refBranch.Name)); Assert.That(result.Status, Is.EqualTo(ResultStatus.No)); }
public static void NormalizeGitDirectory(string gitDirectory, Authentication authentication, bool noFetch, string currentBranch) { using (var repo = new Repository(gitDirectory)) { var remote = EnsureOnlyOneRemoteIsDefined(repo); AddMissingRefSpecs(repo, remote); //If noFetch is enabled, then GitVersion will assume that the git repository is normalized before execution, so that fetching from remotes is not required. if (noFetch) { Logger.WriteInfo("Skipping fetching, if GitVersion does not calculate your version as expected you might need to allow fetching or use dynamic repositories"); } else { Logger.WriteInfo(string.Format("Fetching from remote '{0}' using the following refspecs: {1}.", remote.Name, string.Join(", ", remote.FetchRefSpecs.Select(r => r.Specification)))); var fetchOptions = BuildFetchOptions(authentication.Username, authentication.Password); repo.Network.Fetch(remote, fetchOptions); } EnsureLocalBranchExistsForCurrentBranch(repo, currentBranch); CreateOrUpdateLocalBranchesFromRemoteTrackingOnes(repo, remote.Name); var headSha = repo.Refs.Head.TargetIdentifier; if (!repo.Info.IsHeadDetached) { Logger.WriteInfo(string.Format("HEAD points at branch '{0}'.", headSha)); return; } Logger.WriteInfo(string.Format("HEAD is detached and points at commit '{0}'.", headSha)); Logger.WriteInfo(string.Format("Local Refs:\r\n" + string.Join(Environment.NewLine, repo.Refs.FromGlob("*").Select(r => string.Format("{0} ({1})", r.CanonicalName, r.TargetIdentifier))))); // In order to decide whether a fake branch is required or not, first check to see if any local branches have the same commit SHA of the head SHA. // If they do, go ahead and checkout that branch // If no, go ahead and check out a new branch, using the known commit SHA as the pointer var localBranchesWhereCommitShaIsHead = repo.Branches.Where(b => !b.IsRemote && b.Tip.Sha == headSha).ToList(); var matchingCurrentBranch = !string.IsNullOrEmpty(currentBranch) ? localBranchesWhereCommitShaIsHead.SingleOrDefault(b => b.CanonicalName.Replace("/heads/", "/") == currentBranch.Replace("/heads/", "/")) : null; if (matchingCurrentBranch != null) { Logger.WriteInfo(string.Format("Checking out local branch '{0}'.", currentBranch)); repo.Checkout(matchingCurrentBranch); } else if (localBranchesWhereCommitShaIsHead.Count > 1) { var branchNames = localBranchesWhereCommitShaIsHead.Select(r => r.CanonicalName); var csvNames = string.Join(", ", branchNames); const string moveBranchMsg = "Move one of the branches along a commit to remove warning"; Logger.WriteWarning(string.Format("Found more than one local branch pointing at the commit '{0}' ({1}).", headSha, csvNames)); var master = localBranchesWhereCommitShaIsHead.SingleOrDefault(n => n.Name == "master"); if (master != null) { Logger.WriteWarning("Because one of the branches is 'master', will build master." + moveBranchMsg); repo.Checkout(master); } else { var branchesWithoutSeparators = localBranchesWhereCommitShaIsHead.Where(b => !b.Name.Contains('/') && !b.Name.Contains('-')).ToList(); if (branchesWithoutSeparators.Count == 1) { var branchWithoutSeparator = branchesWithoutSeparators[0]; Logger.WriteWarning(string.Format("Choosing {0} as it is the only branch without / or - in it. " + moveBranchMsg, branchWithoutSeparator.CanonicalName)); repo.Checkout(branchWithoutSeparator); } else { throw new WarningException("Failed to try and guess branch to use. " + moveBranchMsg); } } } else if (localBranchesWhereCommitShaIsHead.Count == 0) { Logger.WriteInfo(string.Format("No local branch pointing at the commit '{0}'. Fake branch needs to be created.", headSha)); CreateFakeBranchPointingAtThePullRequestTip(repo, authentication); } else { Logger.WriteInfo(string.Format("Checking out local branch 'refs/heads/{0}'.", localBranchesWhereCommitShaIsHead[0].Name)); repo.Checkout(repo.Branches[localBranchesWhereCommitShaIsHead[0].Name]); } } }
string FakeTeamCityFetchAndCheckout(string upstreamRepository, string monitoredReference) { var repoPath = InitNewRepository(); using (var repo = new Repository(repoPath)) { var remote = repo.Network.Remotes.Add("origin", upstreamRepository); Debug.Assert(remote.FetchRefSpecs.Single().Specification == "+refs/heads/*:refs/remotes/origin/*"); repo.Network.Fetch(remote); if (monitoredReference.StartsWith("refs/pull/")) { repo.Network.Fetch(remote, new[]{ string.Format("+{0}:{0}", monitoredReference) }); } var src = monitoredReference; var dst = monitoredReference.Replace("refs/heads/", "refs/remotes/origin/"); var fetched = (DirectReference)repo.Refs[dst]; if (fetched.IsRemoteTrackingBranch()) { Assert.IsNull(repo.Refs[src]); repo.Refs.Add(src, fetched.Target.Id); var branch = repo.Branches[src]; repo.Branches.Update(branch, b => b.Remote = remote.Name, b => b.UpstreamBranch = src); } repo.Checkout(src); if (monitoredReference.StartsWith("refs/pull/")) { repo.Refs.Remove(monitoredReference); } } return repoPath; }
static void CreateFakePullRequest(string repoPath, string issueNumber) { // Fake an upstream repository as it would appear on GitHub // will pull requests stored under the refs/pull/ namespace using (var repo = new Repository(repoPath)) { var branch = repo.CreateBranch("temp", repo.Branches["develop"].Tip); branch.Checkout(); AddOneCommitToHead(repo, "code"); AddOneCommitToHead(repo, "code"); var c = repo.Head.Tip; repo.Refs.Add(string.Format("refs/pull/{0}/head", issueNumber), c.Id); var sign = Constants.SignatureNow(); var m = repo.ObjectDatabase.CreateCommit( string.Format("Merge pull request #{0} from nulltoken/ntk/fix/{0}", issueNumber) , sign, sign, c.Tree, new[] {repo.Branches["develop"].Tip, c}); repo.Refs.Add(string.Format("refs/pull/{0}/merge", issueNumber), m.Id); repo.Checkout("develop"); repo.Branches.Remove("temp"); } }
/// <summary> /// Normalisation of a git directory turns all remote branches into local branches, turns pull request refs into a real branch and a few other things. This is designed to be run *only on the build server* which checks out repositories in different ways. /// It is not recommended to run normalisation against a local repository /// </summary> public static void NormalizeGitDirectory(string gitDirectory, AuthenticationInfo authentication, bool noFetch, string currentBranch) { using (var repo = new Repository(gitDirectory)) { // Need to unsure the HEAD does not move, this is essentially a BugCheck var expectedSha = repo.Head.Tip.Sha; try { var remote = EnsureOnlyOneRemoteIsDefined(repo); AddMissingRefSpecs(repo, remote); //If noFetch is enabled, then GitVersion will assume that the git repository is normalized before execution, so that fetching from remotes is not required. if (noFetch) { Log.Info("Skipping fetching, if GitVersion does not calculate your version as expected you might need to allow fetching or use dynamic repositories"); } else { Fetch(authentication, remote, repo); } EnsureLocalBranchExistsForCurrentBranch(repo, currentBranch); CreateOrUpdateLocalBranchesFromRemoteTrackingOnes(repo, remote.Name); var headSha = repo.Refs.Head.TargetIdentifier; if (!repo.Info.IsHeadDetached) { Log.Info(string.Format("HEAD points at branch '{0}'.", headSha)); return; } Log.Info(string.Format("HEAD is detached and points at commit '{0}'.", headSha)); Log.Info(string.Format("Local Refs:\r\n" + string.Join(Environment.NewLine, repo.Refs.FromGlob("*").Select(r => string.Format("{0} ({1})", r.CanonicalName, r.TargetIdentifier))))); // In order to decide whether a fake branch is required or not, first check to see if any local branches have the same commit SHA of the head SHA. // If they do, go ahead and checkout that branch // If no, go ahead and check out a new branch, using the known commit SHA as the pointer var localBranchesWhereCommitShaIsHead = repo.Branches.Where(b => !b.IsRemote && b.Tip.Sha == headSha).ToList(); var matchingCurrentBranch = !string.IsNullOrEmpty(currentBranch) ? localBranchesWhereCommitShaIsHead.SingleOrDefault(b => b.CanonicalName.Replace("/heads/", "/") == currentBranch.Replace("/heads/", "/")) : null; if (matchingCurrentBranch != null) { Log.Info(string.Format("Checking out local branch '{0}'.", currentBranch)); repo.Checkout(matchingCurrentBranch); } else if (localBranchesWhereCommitShaIsHead.Count > 1) { var branchNames = localBranchesWhereCommitShaIsHead.Select(r => r.CanonicalName); var csvNames = string.Join(", ", branchNames); const string moveBranchMsg = "Move one of the branches along a commit to remove warning"; Log.Warn(string.Format("Found more than one local branch pointing at the commit '{0}' ({1}).", headSha, csvNames)); var master = localBranchesWhereCommitShaIsHead.SingleOrDefault(n => n.FriendlyName == "master"); if (master != null) { Log.Warn("Because one of the branches is 'master', will build master." + moveBranchMsg); repo.Checkout(master); } else { var branchesWithoutSeparators = localBranchesWhereCommitShaIsHead.Where(b => !b.FriendlyName.Contains('/') && !b.FriendlyName.Contains('-')).ToList(); if (branchesWithoutSeparators.Count == 1) { var branchWithoutSeparator = branchesWithoutSeparators[0]; Log.Warn(string.Format("Choosing {0} as it is the only branch without / or - in it. " + moveBranchMsg, branchWithoutSeparator.CanonicalName)); repo.Checkout(branchWithoutSeparator); } else { throw new WarningException("Failed to try and guess branch to use. " + moveBranchMsg); } } } else if (localBranchesWhereCommitShaIsHead.Count == 0) { Log.Info(string.Format("No local branch pointing at the commit '{0}'. Fake branch needs to be created.", headSha)); CreateFakeBranchPointingAtThePullRequestTip(repo, authentication); } else { Log.Info(string.Format("Checking out local branch 'refs/heads/{0}'.", localBranchesWhereCommitShaIsHead[0].FriendlyName)); repo.Checkout(repo.Branches[localBranchesWhereCommitShaIsHead[0].FriendlyName]); } } finally { if (repo.Head.Tip.Sha != expectedSha) { if (Environment.GetEnvironmentVariable("IGNORE_NORMALISATION_GIT_HEAD_MOVE") != "1") { // Whoa, HEAD has moved, it shouldn't have. We need to blow up because there is a bug in normalisation throw new BugException(string.Format(@"GitTools.Core has a bug, your HEAD has moved after repo normalisation. To disable this error set an environmental variable called IGNORE_NORMALISATION_GIT_HEAD_MOVE to 1 Please run `git {0}` and submit it along with your build log (with personal info removed) in a new issue at https://github.com/GitTools/GitTools.Core", LibGitExtensions.CreateGitLogArgs(100))); } } } } }
static void CreateFakeBranchPointingAtThePullRequestTip(Repository repo, AuthenticationInfo authentication) { var remote = repo.Network.Remotes.Single(); Log.Info("Fetching remote refs to see if there is a pull request ref"); var remoteTips = (string.IsNullOrEmpty(authentication.Username) ? GetRemoteTipsForAnonymousUser(repo, remote) : GetRemoteTipsUsingUsernamePasswordCredentials(repo, remote, authentication.Username, authentication.Password)) .ToList(); Log.Info("Remote Refs:\r\n" + string.Join(Environment.NewLine, remoteTips.Select(r => r.CanonicalName))); var headTipSha = repo.Head.Tip.Sha; var refs = remoteTips.Where(r => r.TargetIdentifier == headTipSha).ToList(); if (refs.Count == 0) { var message = string.Format("Couldn't find any remote tips from remote '{0}' pointing at the commit '{1}'.", remote.Url, headTipSha); throw new WarningException(message); } if (refs.Count > 1) { var names = string.Join(", ", refs.Select(r => r.CanonicalName)); var message = string.Format("Found more than one remote tip from remote '{0}' pointing at the commit '{1}'. Unable to determine which one to use ({2}).", remote.Url, headTipSha, names); throw new WarningException(message); } var reference = refs[0]; var canonicalName = reference.CanonicalName; Log.Info(string.Format("Found remote tip '{0}' pointing at the commit '{1}'.", canonicalName, headTipSha)); if (canonicalName.StartsWith("refs/tags")) { Log.Info(string.Format("Checking out tag '{0}'", canonicalName)); repo.Checkout(reference.Target.Sha); return; } if (!canonicalName.StartsWith("refs/pull/") && !canonicalName.StartsWith("refs/pull-requests/")) { var message = string.Format("Remote tip '{0}' from remote '{1}' doesn't look like a valid pull request.", canonicalName, remote.Url); throw new WarningException(message); } var fakeBranchName = canonicalName.Replace("refs/pull/", "refs/heads/pull/").Replace("refs/pull-requests/", "refs/heads/pull-requests/"); Log.Info(string.Format("Creating fake local branch '{0}'.", fakeBranchName)); repo.Refs.Add(fakeBranchName, new ObjectId(headTipSha)); Log.Info(string.Format("Checking local branch '{0}' out.", fakeBranchName)); repo.Checkout(fakeBranchName); }
private string PullLatest(string repository, string branch, string localGitPath) { using (var repo = new Repository(localGitPath)) { var targetBranch = repo.Branches[branch]; if (targetBranch != null) { if (!targetBranch.IsCurrentRepositoryHead) { repo.Checkout(branch); } try { var pullOptions = new PullOptions(); pullOptions.FetchOptions = new FetchOptions(); pullOptions.FetchOptions.CredentialsProvider = (_url, _user, _cred) => new DefaultCredentials(); repo.Network.Pull(GetSignature(), pullOptions); } catch (Exception) { var pullOptions = new PullOptions(); pullOptions.FetchOptions = new FetchOptions(); pullOptions.FetchOptions.CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials() { Username = SourceUserName, Password = SourcePassword }; repo.Network.Pull(GetSignature(), pullOptions); } } } return localGitPath; }
public void StandardExecutionMode_CannotDetermineTheVersionFromADetachedHead() { var repoPath = Clone(ASBMTestRepoWorkingDirPath); using (var repo = new Repository(repoPath)) { repo.Checkout("469f851"); Assert.IsTrue(repo.Info.IsHeadDetached); } var task = new UpdateAssemblyInfo { BuildEngine = new MockBuildEngine(), SolutionDirectory = repoPath, }; var exception = Assert.Throws<ErrorException>(task.InnerExecute); Assert.AreEqual("It looks like the branch being examined is a detached Head pointing to commit '469f851'. Without a proper branch name GitVersion cannot determine the build version.", exception.Message); }
private Branch CheckoutRemoteBranch(Repository rep) { // set to remote branch return rep.Checkout(GetRemoteBranch(rep));// TODO: if lock error raised: version take methods(assemblys part) not thread-save }
public void CreateOrResetBranch(string branchName, string startPoint) { using (var repo = new LibGit2Sharp.Repository(RepositoryPath)) { if (string.IsNullOrWhiteSpace(startPoint)) { var branch = repo.GetOrCreateBranch(branchName); repo.Checkout(branch); } else { var commit = repo.Lookup<Commit>(startPoint); if (commit == null) { throw new LibGit2Sharp.NotFoundException(string.Format("Start point \"{0}\" for reset was not found.", startPoint)); } var branch = repo.GetOrCreateBranch(branchName); repo.Checkout(branch); repo.Reset(ResetMode.Hard, commit); } } }
static void EnsureLocalBranchExistsForCurrentBranch(Repository repo, string currentBranch) { if (string.IsNullOrEmpty(currentBranch)) return; var isRef = currentBranch.Contains("refs"); var isBranch = currentBranch.Contains("refs/heads"); var localCanonicalName = !isRef ? "refs/heads/" + currentBranch : isBranch ? currentBranch : currentBranch.Replace("refs/", "refs/heads/"); var repoTip = repo.Head.Tip; var repoTipId = repoTip.Id; if (repo.Branches.All(b => b.CanonicalName != localCanonicalName)) { Log.Info(isBranch ? string.Format("Creating local branch {0}", localCanonicalName) : string.Format("Creating local branch {0} pointing at {1}", localCanonicalName, repoTipId)); repo.Refs.Add(localCanonicalName, repoTipId); } else { Log.Info(isBranch ? string.Format("Updating local branch {0} to point at {1}", localCanonicalName, repoTip.Sha) : string.Format("Updating local branch {0} to match ref {1}", localCanonicalName, currentBranch)); repo.Refs.UpdateTarget(repo.Refs[localCanonicalName], repoTipId); } repo.Checkout(localCanonicalName); }
public void Update(string id) { using (var repo = new LibGit2Sharp.Repository(RepositoryPath)) { repo.Checkout(id, new CheckoutOptions { CheckoutModifiers = CheckoutModifiers.Force }); } }
public void ChangeBranch(RepositoryItem repository, string BranchName) { var repo = new LibGit2Sharp.Repository(repository.Path); var branches = repo.Branches.Where(b => b.Name == BranchName).ToList(); if (branches.Any()) { var localBranch = branches.FirstOrDefault(x => !x.IsRemote); if (localBranch != null) { repo.Checkout(localBranch, new CheckoutOptions(), new Signature(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), DateTime.Now)); } else { throw new Exception("You must checkout manually the first time"); //COMMENTED THIS OUT AS IT CREATES DUPLICATE REMOTE BRANCHES, For instance R15_Release will duplicate as origin/R15_Release. //Current work around is to get them to check out the branch manually the first time around. //var remoteBranch = branches.FirstOrDefault(x => x.IsRemote); //if (remoteBranch != null) //{ // var newLocalBranch = repo.CreateBranch(BranchName, remoteBranch.Tip); // newLocalBranch = repo.Branches.Update(newLocalBranch, // b => // { // b.TrackedBranch = remoteBranch.CanonicalName; // }); // repo.Checkout(newLocalBranch, new CheckoutOptions(), new Signature(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), DateTime.Now)); //} } } }
public static string Update(string url, Log log, string directory, string repoDirectory = null) { if (string.IsNullOrWhiteSpace(url)) { Utility.Log(LogStatus.Skipped, "Updater", string.Format("No Url specified - {0}", url), log); } else { try { var dir = Path.Combine(directory, url.GetHashCode().ToString("X"), "trunk"); if (Repository.IsValid(dir)) { using (var repo = new Repository(dir)) { repo.Config.Set("user.name", Config.Instance.Username); repo.Config.Set("user.email", Config.Instance.Username + "@joduska.me"); repo.Fetch("origin"); if (repoDirectory != null) { repo.CheckoutPaths("origin/master", new List<String>() { repoDirectory }, new CheckoutOptions { CheckoutModifiers = CheckoutModifiers.Force }); } else { repo.Checkout("origin/master", new CheckoutOptions { CheckoutModifiers = CheckoutModifiers.Force }); } } } else { var oldPath = Path.Combine(directory, url.GetHashCode().ToString("X")); if (Directory.Exists(oldPath)) { Directory.Delete(oldPath, true); } Repository.Clone(url, dir, new CloneOptions { Checkout = true }); using (var repo = new Repository(dir)) { repo.Config.Set("user.name", Config.Instance.Username); repo.Config.Set("user.email", Config.Instance.Username + "@joduska.me"); } } return dir; } catch (Exception ex) { Utility.Log(LogStatus.Error, "Updater", string.Format("{0} - {1}", ex.Message, url), log); } } return string.Empty; }