public void CallsCloneOnVsProvidedCloneService(bool recurseSubmodules, CloneOptions expectedCloneOptions) { var provider = Substitute.For<IUIProvider>(); var gitRepositoriesExt = Substitute.For<IGitRepositoriesExt>(); provider.GetService(typeof(IGitRepositoriesExt)).Returns(gitRepositoriesExt); var vsServices = new VSServices(provider); vsServices.Clone("https://github.com/github/visualstudio", @"c:\fake\ghfvs", recurseSubmodules); gitRepositoriesExt.Received() .Clone("https://github.com/github/visualstudio", @"c:\fake\ghfvs", expectedCloneOptions); }
public void Checkout(string refspec = "master", CancellationToken token = default(CancellationToken)) { var checkoutOptions = new CheckoutOptions { CheckoutModifiers = CheckoutModifiers.Force, }; // Clone repository if it does not exist if (!Repository.IsValid(Source.RepositoryPath)) { Output.WriteLine("Cloning Repository...", ConsoleColor.DarkCyan); var cloneOptions = new CloneOptions(); cloneOptions.CredentialsProvider += CredentialsProvider; Repository.Clone(Source.RepositoryUrl, Source.RepositoryPath, cloneOptions); } using (var repo = new Repository(Source.RepositoryPath)) { // Fetch all updated refspecs and tags Output.WriteLine("Fetching updated refs...", ConsoleColor.DarkCyan); var fetchSpec = new[] { "+refs/heads/*:refs/remotes/origin/*" }; var fetchOptions = new FetchOptions { TagFetchMode = TagFetchMode.All, }; fetchOptions.CredentialsProvider += CredentialsProvider; LibGit2Sharp.Commands.Fetch(repo, "origin", fetchSpec, fetchOptions, null); // Find local and remote branches var remoteBranchName = $"refs/remotes/origin/{refspec}"; var remoteBranch = repo.Branches[remoteBranchName]; var localBranchName = $"refs/heads/origin/{refspec}"; var localBranch = repo.Branches[localBranchName]; if (remoteBranch == null) { Output.Write("Git Refspec ", ConsoleColor.DarkYellow) .Write(refspec, ConsoleColor.Yellow) .WriteLine(" was not found!", ConsoleColor.DarkYellow); throw new ApplicationException($"Git Refspec '{refspec}' was not found!"); } if (localBranch != null) { Output.WriteLine($"Found local branch '{localBranch.FriendlyName}'...", ConsoleColor.DarkCyan); // Update tracking branch if not remote branch if (!localBranch.IsTracking || localBranch.TrackedBranch != remoteBranch) { Output.WriteLine("Updating local branch tracking reference...", ConsoleColor.DarkCyan); repo.Branches.Update(localBranch, b => b.TrackedBranch = remoteBranch.CanonicalName); } // Checkout local branch if not current if (!localBranch.IsCurrentRepositoryHead) { Output.WriteLine($"Checkout local branch '{localBranch.FriendlyName}'...", ConsoleColor.DarkCyan); LibGit2Sharp.Commands.Checkout(repo, localBranch, checkoutOptions); } // Revert to common ancestor commit if diverged var status = localBranch.TrackingDetails; var aheadCount = status.AheadBy ?? 0; if (aheadCount > 0) { Output.WriteLine($"Local branch '{localBranch.FriendlyName}' has diverged from the remote tracking branch!", ConsoleColor.DarkYellow); var common = status.CommonAncestor; if (common != null) { Output.WriteLine($"Reverting local branch to commit '{common.Sha}'!", ConsoleColor.DarkCyan); repo.Reset(ResetMode.Hard, common, checkoutOptions); } } // Pull latest changes from remote Output.WriteLine("Pull changes from remote...", ConsoleColor.DarkCyan); var sign = new Signature("photon", "*****@*****.**", DateTimeOffset.Now); var pullOptions = new PullOptions { FetchOptions = fetchOptions, }; LibGit2Sharp.Commands.Pull(repo, sign, pullOptions); } else { // Create local branch tracking remote Output.WriteLine($"No local branch found. Creating local tracking branch '{remoteBranch.FriendlyName}'...", ConsoleColor.DarkCyan); localBranch = repo.CreateBranch(remoteBranch.FriendlyName, remoteBranch.Tip); repo.Branches.Update(localBranch, b => b.TrackedBranch = remoteBranch.CanonicalName); Output.WriteLine($"Checkout local tracking branch '{localBranch.FriendlyName}'...", ConsoleColor.DarkCyan); LibGit2Sharp.Commands.Checkout(repo, localBranch, checkoutOptions); } var commit = repo.Head?.Tip; CommitHash = commit?.Sha; CommitAuthor = commit?.Author?.Name; CommitMessage = commit?.Message; Output.WriteLine("Current Commit:", ConsoleColor.DarkBlue) .WriteLine($" {CommitHash}", ConsoleColor.Blue) .WriteLine($" {CommitAuthor}", ConsoleColor.Blue) .WriteLine(CommitMessage, ConsoleColor.Cyan); } }
/// <summary> /// Clone any object /// </summary> /// <typeparam name="T"></typeparam> /// <param name="sourceObject">The object to clone</param> /// <param name="options">Specify the Clone options</param> /// <returns></returns> public static T Clone <T>(this T sourceObject, CloneOptions options) { var cloneProvider = new CloneProvider <T>(); return(cloneProvider.Clone(sourceObject, CloneConfiguration.CreateFromOptions(options))); }
public static async Task ProcessMergeMessageAsync([QueueTrigger("merges")] Shared.Merge merge, TextWriter log) { var sessionId = Guid.NewGuid(); var reposPath = new DirectoryInfo(ConfigurationManager.AppSettings["RepositoryPath"]).FullName; var repoPath = Path.Combine(reposPath, merge.RepositoryName); await LogAsync($"Merge message received for commit '{merge.CommitId}'.", sessionId, log); var mergeSet = new MergeSet() { RepoName = merge.RepositoryName, RepoPath = repoPath, Changes = new List <Node>() }; var cloneOptions = new CloneOptions() { CredentialsProvider = (_url, _user, _cred) => GetRepoCredentials(merge.PersonalAccessToken) }; if (!Directory.Exists(repoPath)) { await LogAsync($"Repo path not found, creating directory '{repoPath}'.", sessionId, log); await LogAsync($"Cloning repository '{merge.RemoteUrl}'.", sessionId, log); Directory.CreateDirectory(repoPath); var cloneResult = Repository.Clone(merge.RemoteUrl, repoPath, cloneOptions); var files = Directory.GetFiles(repoPath, "*", SearchOption.AllDirectories); foreach (var file in files) { var currentFileInfo = new FileInfo(file); if (currentFileInfo.Directory.FullName.Replace(repoPath, "").ToLower().StartsWith("\\.git")) { continue; } mergeSet.Changes.Add(new Node() { Path = file, Status = ChangeKind.Added }); } } else { await LogAsync($"Pulling from repository '{merge.RemoteUrl}'.", sessionId, log); Directory.CreateDirectory(repoPath); using (var repo = new Repository(repoPath)) { PullOptions options = new PullOptions() { FetchOptions = new FetchOptions() { CredentialsProvider = new CredentialsHandler( (url, usernameFromUrl, types) => GetRepoCredentials(merge.PersonalAccessToken)) } }; var lastCommit = repo.Head.Tip; var mergeResult = Commands.Pull(repo, GetRepoSignature(), options); var headCommit = repo.Branches["origin/master"].Commits.First(); var treeChanges = repo.Diff.Compare <TreeChanges>(lastCommit.Tree, headCommit.Tree); foreach (var treeChange in treeChanges) { if (treeChange.Status.Equals(ChangeKind.Renamed)) { mergeSet.Changes.Add(new Node() { Path = Path.Combine(repoPath, treeChange.OldPath), Status = ChangeKind.Deleted }); } ; mergeSet.Changes.Add(new Node() { Path = Path.Combine(repoPath, treeChange.Path), Status = treeChange.Status }); } } } using (var repo = new Repository(repoPath)) { mergeSet.Sha = repo.Head.Tip.Sha; mergeSet.Author = repo.Head.Tip.Author.Name; mergeSet.LastRevisionDate = repo.Head.Tip.Author.When; foreach (var change in mergeSet.Changes) { change.RepoName = mergeSet.RepoName; change.RepoPath = mergeSet.RepoPath; change.Revisions.Add(new Revision() { Sha = mergeSet.Sha, Author = mergeSet.Author, LastRevisionDate = mergeSet.LastRevisionDate }); if (change.Path.Replace(repoPath, "").ToLower().StartsWith("\\.git")) { continue; } await Helpers.QueueHelper.SendQueueMessage("renders", change); } } await Helpers.QueueHelper.SendQueueMessage("cleanups", mergeSet); }
/// <summary> /// 重新设置整个表的所有 TreeIndex。 /// 注意,此方法只保证生成的 TreeIndex 有正确的父子关系,同时顺序有可能被打乱。 /// </summary> /// <param name="repository"></param> public static void ResetTreeIndex(EntityRepository repository) { using (var tran = RF.TransactionScope(repository)) { //先清空 var dp = repository.DataProvider as RdbDataProvider; if (dp == null) { throw new InvalidProgramException("TreeIndexHelper.ResetTreeIndex 方法只支持在关系数据库上使用。"); } var table = dp.DbTable; var column = table.Columns.First(c => c.Info.Property == Entity.TreeIndexProperty); using (var dba = dp.CreateDbAccesser()) { dba.ExecuteText(string.Format("UPDATE {0} SET {1} = NULL", table.Name, column.Name)); } var all = repository.GetAll(); if (all.Count > 0) { //如果加载的过程中,第一个节点刚好是根节点, //则加载完成后是一棵完整的树,Index 也生成完毕,不需要再次处理。 if (all.IsTreeRootList) { all.ResetTreeIndex(); repository.Save(all); } else { var cloneOptions = CloneOptions.ReadSingleEntity(); var oldList = new List <Entity>(); all.EachNode(e => { var cloned = repository.New(); cloned.Clone(e, cloneOptions); cloned.PersistenceStatus = PersistenceStatus.Unchanged; oldList.Add(cloned); return(false); }); var newList = repository.NewList(); while (oldList.Count > 0) { foreach (var item in oldList) { var treePId = item.TreePId; if (treePId == null) { newList.Add(item); oldList.Remove(item); break; } else { var parent = newList.EachNode(e => e.Id.Equals(treePId)); if (parent != null) { parent.TreeChildren.LoadAdd(item); oldList.Remove(item); break; } } } } TreeHelper.MarkTreeFullLoaded(newList); newList.ResetTreeIndex(); repository.Save(newList); } } tran.Complete(); } }
public static bool Run(CompressimagesParameters parameters) { CredentialsHandler credentialsProvider = (url, user, cred) => new UsernamePasswordCredentials { Username = KnownGitHubs.Username, Password = parameters.Password }; // clone var cloneOptions = new CloneOptions { CredentialsProvider = credentialsProvider, }; Repository.Clone(parameters.CloneUrl, parameters.LocalPath, cloneOptions); var repo = new Repository(parameters.LocalPath); var remote = repo.Network.Remotes["origin"]; // check if we have the branch already or this is empty repo try { if (repo.Network.ListReferences(remote, credentialsProvider).Any() == false) { return(false); } if (repo.Network.ListReferences(remote, credentialsProvider).Any(x => x.CanonicalName == $"refs/heads/{KnownGitHubs.BranchName}")) { return(false); } } catch { // ignore } var repoConfiguration = new RepoConfiguration(); try { // see if .imgbotconfig exists in repo root var repoConfigJson = File.ReadAllText(parameters.LocalPath + Path.DirectorySeparatorChar + ".imgbotconfig"); if (!string.IsNullOrEmpty(repoConfigJson)) { repoConfiguration = JsonConvert.DeserializeObject <RepoConfiguration>(repoConfigJson); } } catch { // ignore } if (Schedule.ShouldOptimizeImages(repoConfiguration, repo) == false) { return(false); } // check out the branch repo.CreateBranch(KnownGitHubs.BranchName); var branch = Commands.Checkout(repo, KnownGitHubs.BranchName); // reset any mean files repo.Reset(ResetMode.Mixed, repo.Head.Tip); // optimize images var imagePaths = ImageQuery.FindImages(parameters.LocalPath, repoConfiguration); var optimizedImages = OptimizeImages(repo, parameters.LocalPath, imagePaths); if (optimizedImages.Length == 0) { return(false); } // create commit message based on optimizations var commitMessage = CommitMessage.Create(optimizedImages); // commit var signature = new Signature(KnownGitHubs.ImgBotLogin, KnownGitHubs.ImgBotEmail, DateTimeOffset.Now); repo.Commit(commitMessage, signature, signature); // We just made a normal commit, now we are going to capture all the values generated from that commit // then rewind and make a signed commit var commitBuffer = Commit.CreateBuffer( repo.Head.Tip.Author, repo.Head.Tip.Committer, repo.Head.Tip.Message, repo.Head.Tip.Tree, repo.Head.Tip.Parents, true, null); var signedCommitData = CommitSignature.Sign(commitBuffer + "\n", parameters.PgpPrivateKeyStream, parameters.PgPPassword); repo.Reset(ResetMode.Soft, repo.Head.Commits.Skip(1).First().Sha); var commitToKeep = repo.ObjectDatabase.CreateCommitWithSignature(commitBuffer, signedCommitData); repo.Refs.UpdateTarget(repo.Refs.Head, commitToKeep); var branchAgain = Commands.Checkout(repo, KnownGitHubs.BranchName); repo.Reset(ResetMode.Hard, commitToKeep.Sha); // push to GitHub repo.Network.Push(remote, $"refs/heads/{KnownGitHubs.BranchName}", new PushOptions { CredentialsProvider = credentialsProvider, }); return(true); }
/// <summary> /// Get repository. /// </summary> /// <param name="latest">If true, ensure the repository is up to date.</param> /// <param name="reset">If true, the repository is cloned from scratch.</param> public Repository Init(bool latest, bool reset) { Validate(); // special local path logic string workPath = ParseLocalUrl(RemoteUrl); if (workPath != null) { Repository local = null; if (FileUtility.IsFolderEmpty(workPath)) { local = new Repository(Repository.Init(workPath)); } else { local = new Repository(workPath); } // get latest from remote if (latest && local.Network.Remotes["origin"] != null) { FetchOptions localFetchOptions = new FetchOptions(); localFetchOptions.CredentialsProvider += ProvideCredentials; PullOptions pullOptions = new PullOptions(); pullOptions.FetchOptions = localFetchOptions; local.Network.Pull(new Signature(AuthorName, AuthorEmail, DateTime.Now), pullOptions); } // get branch Branch branch = local.Branches[BranchName]; if (branch == null) { Branch remoteBranch = local.Branches[String.Format("origin/{0}", BranchName)]; if (remoteBranch != null) { branch = local.CreateBranch(BranchName, remoteBranch.Tip); branch = local.Branches.Update( branch, b => b.TrackedBranch = remoteBranch.CanonicalName); } } if (branch != null) { local.Checkout(branch); } return(local); } // don't get latest or clone from remote if (!latest) { if (FileUtility.IsFolderEmpty(WorkingPath)) { throw new Exception("Repository doesn't exist."); } return(new Repository(WorkingPath)); } Repository repo = null; // delete existing repository so we will start from scratch if (reset) { FileUtility.DeleteFolderContents(WorkingPath); } // clean out existing repository if it doesn't match current settings if (!FileUtility.IsFolderEmpty(WorkingPath)) { repo = new Repository(WorkingPath); Remote remote = repo.Network.Remotes["origin"]; if (remote == null || remote.Url != RemoteUrl) { if (repo != null) { repo.Dispose(); } repo = null; FileUtility.DeleteFolderContents(WorkingPath); } } // clone repository if needed if (repo == null) { CloneOptions options = new CloneOptions(); options.CredentialsProvider += ProvideCredentials; try { repo = new Repository(Repository.Clone(RemoteUrl, WorkingPath, options)); } finally { options.CredentialsProvider -= ProvideCredentials; } } FetchOptions fetchOptions = null; try { // get latest changes fetchOptions = new FetchOptions(); fetchOptions.CredentialsProvider += ProvideCredentials; PullOptions pullOptions = new PullOptions(); pullOptions.FetchOptions = fetchOptions; repo.Network.Pull(new Signature(AuthorName, AuthorEmail, DateTime.Now), pullOptions); // get branch or create new one if needed Branch localBranch = repo.Branches[BranchName]; if (localBranch == null) { Branch remoteBranch = repo.Branches[String.Format("origin/{0}", BranchName)]; if (remoteBranch == null) { throw new Exception(String.Format("There is no branch named: {0} in the repository.", BranchName)); } localBranch = repo.CreateBranch(BranchName, remoteBranch.Tip); localBranch = repo.Branches.Update( localBranch, b => b.TrackedBranch = remoteBranch.CanonicalName); } // if the local branch is ahead of the remote branch then we need to start from scratch if (localBranch.TrackingDetails.AheadBy.HasValue && localBranch.TrackingDetails.AheadBy.Value > 0) { if (!reset) { repo.Dispose(); return(Init(latest, true)); } throw new Exception("It appears the local repository is out of sync with the remote repository."); } Branch = localBranch; // checkout branch and wipe out any uncommitted changes repo.Reset(ResetMode.Hard); CheckoutOptions checkoutOptions = new CheckoutOptions(); checkoutOptions.CheckoutModifiers = CheckoutModifiers.Force; repo.Checkout(localBranch, checkoutOptions); } finally { if (fetchOptions != null) { fetchOptions.CredentialsProvider -= ProvideCredentials; } } return(repo); }
public static bool Run(CompressimagesParameters parameters, ICollector <CompressImagesMessage> compressImagesMessages, ILogger logger) { CredentialsHandler credentialsProvider = (url, user, cred) => new UsernamePasswordCredentials { Username = KnownGitHubs.Username, Password = parameters.Password }; // clone var cloneOptions = new CloneOptions { CredentialsProvider = credentialsProvider, }; Repository.Clone(parameters.CloneUrl, parameters.LocalPath, cloneOptions); var repo = new Repository(parameters.LocalPath); var remote = repo.Network.Remotes["origin"]; var isWikiCompress = parameters.CloneUrl.EndsWith(".wiki.git"); // check if we have the branch already or this is empty repo try { if (repo.Network.ListReferences(remote, credentialsProvider).Any() == false) { logger.LogInformation("CompressImagesFunction: no references found for {Owner}/{RepoName}", parameters.RepoOwner, parameters.RepoName); return(false); } if (!parameters.IsRebase && repo.Network.ListReferences(remote, credentialsProvider).Any(x => x.CanonicalName == $"refs/heads/{KnownGitHubs.BranchName}")) { logger.LogInformation("CompressImagesFunction: branch already exists for {Owner}/{RepoName}", parameters.RepoOwner, parameters.RepoName); return(false); } } catch (Exception e) { // log + ignore logger.LogWarning(e, "CompressImagesFunction: issue checking for existing branch or empty repo for {Owner}/{RepoName}", parameters.RepoOwner, parameters.RepoName); } // check if we should switch away from the default branch if (!isWikiCompress && parameters.Settings != null && !string.IsNullOrEmpty(parameters.Settings.DefaultBranchOverride)) { logger.LogInformation( "CompressImagesFunction: default branch override for {Owner}/{RepoName} is {DefaultBranchOverride}", parameters.RepoOwner, parameters.RepoName, parameters.Settings.DefaultBranchOverride); var baseBranch = repo.Branches[$"refs/remotes/origin/{parameters.Settings.DefaultBranchOverride}"]; if (baseBranch == null) { logger.LogWarning( "CompressImagesFunction: default branch ({DefaultBranchOverride}) not found for {Owner}/{RepoName}", parameters.Settings.DefaultBranchOverride, parameters.RepoOwner, parameters.RepoName); return(false); } Commands.Checkout(repo, baseBranch); } var repoConfiguration = new RepoConfiguration(); try { // see if .imgbotconfig exists in repo root var repoConfigJson = File.ReadAllText(parameters.LocalPath + Path.DirectorySeparatorChar + ".imgbotconfig"); if (!string.IsNullOrEmpty(repoConfigJson)) { repoConfiguration = JsonConvert.DeserializeObject <RepoConfiguration>(repoConfigJson); } } catch { // ignore } // Add new compressMessage if we should compress Wiki if (repoConfiguration.CompressWiki && isWikiCompress == false) { logger.LogInformation("CompressImagesFunction: Adding Wiki image compression to queue for {Owner}/{RepoName}", parameters.RepoOwner, parameters.RepoName); compressImagesMessages.Add(new CompressImagesMessage() { InstallationId = parameters.CompressImagesMessage.InstallationId, RepoName = parameters.CompressImagesMessage.RepoName, Owner = parameters.RepoOwner, CloneUrl = $"https://github.com/{parameters.RepoOwner}/{parameters.RepoName}.wiki.git" }); } if (Schedule.ShouldOptimizeImages(repoConfiguration, repo) == false) { logger.LogInformation("CompressImagesFunction: skipping optimization due to schedule for {Owner}/{RepoName}", parameters.RepoOwner, parameters.RepoName); return(false); } // Should not create branch if we are compressing Wiki or performing rebase if (isWikiCompress == false && !parameters.IsRebase) { // check out the branch repo.CreateBranch(KnownGitHubs.BranchName); var branch = Commands.Checkout(repo, KnownGitHubs.BranchName); } // reset any mean files repo.Reset(ResetMode.Mixed, repo.Head.Tip); // optimize images string[] imagePaths; List <string> addedOrModifiedImagePaths = new List <string>(); List <string> deletedImagePaths = new List <string>(); if (parameters.IsRebase) { var refspec = string.Format("{0}:{0}", KnownGitHubs.BranchName); Commands.Fetch(repo, "origin", new List <string> { refspec }, null, "fetch"); var diff = repo.Diff.Compare <TreeChanges>(repo.Branches[KnownGitHubs.BranchName].Commits.ElementAt(1).Tree, repo.Head.Tip.Tree); if (diff == null) { logger.LogInformation("Something went wrong while doing rebase"); return(false); } foreach (TreeEntryChanges c in diff) { if (KnownImgPatterns.ImgExtensions.Contains(Path.GetExtension(c.Path))) { var path = parameters.LocalPath + "/" + c.Path; var oldpath = parameters.LocalPath + "/" + c.OldPath; switch (c.Status) { case ChangeKind.Added: case ChangeKind.Modified: addedOrModifiedImagePaths.Add(path.Replace("\\", "/")); break; case ChangeKind.Renamed: addedOrModifiedImagePaths.Add(path.Replace("\\", "/")); deletedImagePaths.Add(oldpath.Replace("\\", "/")); break; case ChangeKind.Deleted: deletedImagePaths.Add(path.Replace("\\", "/")); break; } } } imagePaths = ImageQuery.FilterOutIgnoredFiles(addedOrModifiedImagePaths, repoConfiguration); } else { imagePaths = ImageQuery.FindImages(parameters.LocalPath, repoConfiguration); } var optimizedImages = OptimizeImages(repo, parameters.LocalPath, imagePaths, logger, repoConfiguration.AggressiveCompression); if (optimizedImages.Length == 0) { return(false); } // create commit message based on optimizations foreach (var image in optimizedImages) { Commands.Stage(repo, image.OriginalPath); } var commitMessage = CommitMessage.Create(optimizedImages); var signature = new Signature(KnownGitHubs.ImgBotLogin, KnownGitHubs.ImgBotEmail, DateTimeOffset.Now); repo.Commit(commitMessage, signature, signature); if (parameters.IsRebase) { var baseBranch = repo.Head; var newCommit = baseBranch.Tip; var oldCommit = repo.Branches[KnownGitHubs.BranchName].Tip; // we need to reset the default branch so that we can // rebase to it later. repo.Reset(ResetMode.Hard, repo.Head.Commits.ElementAt(1)); // checkout to imgbot branch. TODO: remove because this is needed earlier on diff Commands.Checkout(repo, KnownGitHubs.BranchName); // cherry-pick var cherryPickOptions = new CherryPickOptions() { MergeFileFavor = MergeFileFavor.Theirs, }; var cherryPickResult = repo.CherryPick(newCommit, signature, cherryPickOptions); if (cherryPickResult.Status == CherryPickStatus.Conflicts) { var status = repo.RetrieveStatus(new LibGit2Sharp.StatusOptions() { }); foreach (var item in status) { if (item.State == FileStatus.Conflicted) { Commands.Stage(repo, item.FilePath); } } repo.Commit(commitMessage, signature, signature); } // New commit message creation var previousCommitResults = CompressionResult.ParseCommitMessage(oldCommit.Message); var mergedResults = CompressionResult.Merge(optimizedImages, previousCommitResults); var filteredResults = CompressionResult.Filter(mergedResults, deletedImagePaths.ToArray()); var squashCommitMessage = CommitMessage.Create(filteredResults); // squash var baseCommit = repo.Head.Commits.ElementAt(2); repo.Reset(ResetMode.Soft, baseCommit); repo.Commit(squashCommitMessage, signature, signature); // rebase var rebaseOptions = new RebaseOptions() { FileConflictStrategy = CheckoutFileConflictStrategy.Theirs, }; var rebaseResult = repo.Rebase.Start(repo.Head, baseBranch, null, new Identity(KnownGitHubs.ImgBotLogin, KnownGitHubs.ImgBotEmail), rebaseOptions); while (rebaseResult.Status == RebaseStatus.Conflicts) { var status = repo.RetrieveStatus(new LibGit2Sharp.StatusOptions() { }); foreach (var item in status) { if (item.State == FileStatus.Conflicted) { if (imagePaths.Contains(parameters.LocalPath + "/" + item.FilePath)) { Commands.Stage(repo, item.FilePath); } else { Commands.Remove(repo, item.FilePath); } } } rebaseResult = repo.Rebase.Continue(new Identity(KnownGitHubs.ImgBotLogin, KnownGitHubs.ImgBotEmail), rebaseOptions); } } // We just made a normal commit, now we are going to capture all the values generated from that commit // then rewind and make a signed commit var commitBuffer = Commit.CreateBuffer( repo.Head.Tip.Author, repo.Head.Tip.Committer, repo.Head.Tip.Message, repo.Head.Tip.Tree, repo.Head.Tip.Parents, true, null); var signedCommitData = CommitSignature.Sign(commitBuffer + "\n", parameters.PgpPrivateKey, parameters.PgPPassword); repo.Reset(ResetMode.Soft, repo.Head.Commits.Skip(1).First().Sha); var commitToKeep = repo.ObjectDatabase.CreateCommitWithSignature(commitBuffer, signedCommitData); repo.Refs.UpdateTarget(repo.Refs.Head, commitToKeep); // Should use "master" if we are compressing Wiki if (isWikiCompress) { var branchAgain = Commands.Checkout(repo, "master"); } else { var branchAgain = Commands.Checkout(repo, KnownGitHubs.BranchName); } repo.Reset(ResetMode.Hard, commitToKeep.Sha); // verify images are not corrupted by reading from git // see https://github.com/dabutvin/ImgBot/issues/273 try { foreach (var image in optimizedImages) { if (image.OriginalPath.EndsWith(".svg")) { // do not use ImageMagick to verify SVGs continue; } new MagickImage(image.OriginalPath).Dispose(); } } catch (MagickErrorException) { logger.LogError("Corrupt images after reset!"); return(false); } // push to GitHub if (isWikiCompress) { repo.Network.Push(remote, "refs/heads/master", new PushOptions { CredentialsProvider = credentialsProvider, }); } else { var refs = $"refs/heads/{KnownGitHubs.BranchName}"; if (parameters.IsRebase) { refs = refs.Insert(0, "+"); } logger.LogInformation("refs: {refs}", refs); repo.Network.Push(remote, refs, new PushOptions { CredentialsProvider = credentialsProvider, }); } return(true); }
private void DownloadAddon() { bool updated = false; bool cloned = false; if (!Directory.Exists(info.packedPath)) { Directory.CreateDirectory(info.packedPath); } if (Directory.Exists(info.dlPath) && Repository.IsValid(info.dlPath)) { using (Repository repo = new Repository(info.dlPath)) { RepositoryStatus status = repo.RetrieveStatus(); string commit = repo.Head.Tip.Id.Sha; // reset local changes if (status.IsDirty) { repo.Reset(ResetMode.Hard); } // fetch & merge from origin repo.Network.Fetch(repo.Network.Remotes["origin"]); repo.MergeFetchedRefs(new Signature("meldii", "*****@*****.**", new DateTimeOffset()), new MergeOptions()); // updated if (!repo.Head.Tip.Id.Sha.Equals(commit)) { updated = true; } } } else { if (Directory.Exists(info.dlPath)) { ForceDeleteDirectory(info.dlPath); } CloneOptions co = new CloneOptions(); co.BranchName = info.branch; Repository.Clone(info.url, info.dlPath, co); updated = true; cloned = true; } //Pack & ship it if (updated) { if (File.Exists(info.packedFile)) { File.Delete(info.packedFile); } ZipFile zip = new ZipFile(info.packedFile); foreach (string file in Directory.EnumerateFiles(info.dlPath, "*.*", SearchOption.AllDirectories)) { string rPath = file.Replace(info.dlPath, "").TrimStart(new char[] { '\\', '/' }); if (!rPath.StartsWith(".git", StringComparison.CurrentCultureIgnoreCase) && !rPath.Equals("README.md", StringComparison.CurrentCultureIgnoreCase)) { string[] split = rPath.Split(new char[] { '\\', '/' }); string zipPath = split.Length == 1 ? "" : string.Join("\\", split, 0, split.Length - 1); zip.AddFile(file, zipPath); } } zip.Save(); } if (cloned) { _Copy(Path.Combine(MeldiiSettings.Self.AddonLibaryPath, info.repoName) + ".zip", info.packedFile); } }
public static bool GitDownload(ServerMod sm) { if (pulledGits.Contains(sm.GitUrl.ToLower())) { return(true); } pulledGits.Add(sm.GitUrl.ToLower()); Console.WriteLine(""); Console.WriteLine("Pulling from git..."); try { string token = sm.GitToken.Replace("token ", ""); string gitName = Path.GetFileNameWithoutExtension(sm.GitUrl); string gitPath = Path.Combine(Program.Settings.GitDirectory, gitName); if (!Directory.Exists(Program.Settings.GitDirectory)) { Directory.CreateDirectory(Program.Settings.GitDirectory); } // This options allows you to use the SSH option. (Allows for Repo specific auth) if (sm.GitType == 3) { if (Directory.Exists(gitPath)) { return(true); } string branch = ""; if (sm.GitPath != "") { branch = $" -b {sm.GitPath}"; } Process.Start(new ProcessStartInfo { WorkingDirectory = Program.Settings.GitDirectory, FileName = "git", Arguments = $"clone --depth=1{branch} {sm.GitUrl}", UseShellExecute = false, CreateNoWindow = true }).WaitForExit(); Program.DeleteDirectory(Path.Combine(Program.Settings.GitDirectory, gitName, ".git")); return(true); } if (Directory.Exists(Path.Combine(Program.Settings.GitDirectory, sm.GitPath))) { Directory.Delete(Program.Settings.GitDirectory, true); } Directory.CreateDirectory(Program.Settings.GitDirectory); if (sm.GitType == 2) { CloneOptions co = new CloneOptions { CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials { Username = "******", Password = sm.GitToken } }; if (sm.GitPath != "") { co.BranchName = sm.GitPath; } Repository.Clone(sm.GitUrl, gitPath, co); } else { CloneOptions co = new CloneOptions { CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials { Username = sm.GitToken, Password = string.Empty } }; if (sm.GitPath != "") { co.BranchName = sm.GitPath; } Repository.Clone(sm.GitUrl, gitPath, co); } return(true); } catch (Exception ex) { Console.WriteLine("Error in download: " + ex); return(false); } }
public void Clone(string url, string branch, IFolder folder, CloneOptions cloneOptions, bool useCache, IErrorsAndInfos errorsAndInfos) { Clone(url, branch, folder, cloneOptions, useCache, () => true, () => { }, errorsAndInfos); }
static async Task Main(string[] args) { Uri org1Url = new Uri("https://dev.azure.com/" + Environment.GetEnvironmentVariable("ORG1")); String project1 = Environment.GetEnvironmentVariable("PROJ1"); String pat1 = Environment.GetEnvironmentVariable("PAT1"); // See https://docs.microsoft.com/azure/devops/integrate/get-started/authentication/pats Uri org2Url = new Uri("https://dev.azure.com/" + Environment.GetEnvironmentVariable("ORG2")); String project2 = Environment.GetEnvironmentVariable("PROJ2"); String pat2 = Environment.GetEnvironmentVariable("PAT2"); // Project name which this should look at Boolean dryRun = !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("DRYRUN")); // Create a connection var sourceConnection = new VssConnection(org1Url, new VssBasicCredential(string.Empty, pat1)); var destinationConnection = new VssConnection(org2Url, new VssBasicCredential(string.Empty, pat2)); var destProject = await destinationConnection.GetClient <ProjectHttpClient>().GetProject(project2); var sourceRepos = await GetAllRepos(sourceConnection, project1); var destReposDict = (await GetAllRepos(destinationConnection, project2)).ToDictionary(x => x.Name); var missingReposInDest = sourceRepos.Where(x => !destReposDict.ContainsKey(getDestNameFromSourceName(x.Name))); var tempPath = Path.GetTempPath(); var tempDir = Directory.CreateDirectory(Path.Join(tempPath, "repocloner", RandomString(5).ToLower())); Console.WriteLine($"Using path {tempDir.FullName}"); // Create any repos missing in proj2 var destSourceClient = destinationConnection.GetClient <GitHttpClient>(); foreach (var sourceRepo in missingReposInDest) { if (dryRun) { Console.WriteLine($"Would create repo {sourceRepo.Name} in {destSourceClient.BaseAddress}"); } else { var gitToCreate = new GitRepositoryCreateOptions() { Name = getDestNameFromSourceName(sourceRepo.Name), ProjectReference = destProject, }; var destRepo = await destSourceClient.CreateRepositoryAsync(gitToCreate); destReposDict[destRepo.Name] = destRepo; } } // Sync source from proj1 to proj2 for all branchs foreach (var sourceRepo in sourceRepos) { var destRepo = destReposDict[getDestNameFromSourceName(sourceRepo.Name)]; if (dryRun) { Console.WriteLine($"Would clone {sourceRepo.Name} @ {sourceRepo.WebUrl} and sync to {destRepo.Name} @ {destRepo.WebUrl}"); } else { // Create a temp dir to store the cloned repo var gitDir = Directory.CreateDirectory(Path.Join(tempDir.FullName, sourceRepo.Name)); var co = new CloneOptions(); CredentialsHandler sourceCredProvider = (_url, _user, _cred) => new UsernamePasswordCredentials { Username = pat1, Password = pat1 }; co.CredentialsProvider = sourceCredProvider; Console.WriteLine($"Cloning source {sourceRepo.Name}"); Repository.Clone(sourceRepo.RemoteUrl, gitDir.FullName, co); using (var repo = new Repository(gitDir.FullName)) { CredentialsHandler destCredProvider = (_url, _user, _cred) => new UsernamePasswordCredentials { Username = pat2, Password = pat2 }; LibGit2Sharp.PushOptions options = new LibGit2Sharp.PushOptions(); options.CredentialsProvider = destCredProvider; if (!repo.Network.Remotes.Where(x => x.Name == "dest").Any()) { repo.Network.Remotes.Add("dest", destRepo.RemoteUrl); } else { repo.Network.Remotes.Remove("dest"); repo.Network.Remotes.Add("dest", destRepo.RemoteUrl); } var destRemote = repo.Network.Remotes["dest"]; foreach (var branch in repo.Branches) { Console.WriteLine($"Pusing source {sourceRepo.Name}:{branch} to {destRepo.Name}:{branch} @ {destRepo.Url}"); repo.Network.Push(destRemote, branch.CanonicalName, new PushOptions() { CredentialsProvider = destCredProvider }); } } } } }
/// <summary> /// 复制一个指定的对象 /// 包括所有的孩子(如果是树节点的话),所有的实体属性和细表属性。 /// </summary> /// <param name="oldObject">需要复制的对象</param> /// <param name="parentNode">如果不为null,表示需要设置新的对象成为这个对象的孩子</param> /// <param name="modifyName">是否在这个对象的Name属性上添加“-新增”</param> /// <returns></returns> private Entity CopyObject(Entity oldObject, Entity parentNode, bool modifyName, CloneOptions options) { throw new NotImplementedException();//huqf ////添加一个新的空对象 //Entity newObject = null; //if (parentNode != null) //{ // newObject = this.NewObject(parentNode, true); //} //else //{ // newObject = this.NewObject(oldObject, false); //} //try //{ // newObject.BeforeCopy(); // if (this.IsDealingTree) // { // var newNode = newObject; // //暂存ParentNode // Entity cachedParent = null; // cachedParent = newNode.TreeParentEntity; // //暂存OrderNo // int oldOrderNo = newObject.OrderNo; // //拷贝所有属性值 // newObject.Clone(oldObject, options); // newNode.TreeParentEntity = cachedParent; // //还原OrderNo // newObject.OrderNo = oldOrderNo; // //拷贝所有的孩子 // var children = oldObject.ChildrenNodes; // for (int i = 0, c = children.Count; i < c; i++) // { // var oldChild = children[i] as Entity; // //复制一个新的节点作为newObject的孩子 // var newChild = this.CopyObject(oldChild, newNode, false, options); // } // } // else // { // //拷贝所有属性值 // newObject.Clone(oldObject, options); // } // this.TryModifyName(newObject, modifyName); //} //finally //{ // newObject.AfterCopy(); //} //return newObject; }
public async Task <string> Clone(string url, string workingDirectory, CloneOptions options = null) { return(await new Task <string>(() => Repository.Clone(url, workingDirectory, options))); }
protected virtual void HandleAutoVersioning(Repository myRepository, string myShortName, Dependency dependency, CloneOptions cloneOptions) { if (!string.IsNullOrEmpty(dependency.Commit)) { throw new InvalidOperationException($"Dependency {dependency}: autoversioning: definition is incoherent: Branch = '{dependency.Branch}' and a Commit = '{dependency.Commit}' => you can't have both set!"); } if (Directory.Exists(dependency.OutputFolder)) { Log($"Dependency {dependency}: autoversioning: output folder already exists: removing..."); new DirectoryInfo(dependency.OutputFolder).ForceDelete(); } Log($"Dependency {dependency}: autoversioning: cloning default branch of '{dependency.Remote}' into '{dependency.OutputFolder}'"); Repository.Clone(dependency.Remote, dependency.OutputFolder, cloneOptions); try { IndentLevel++; using (var otherRepository = new Repository(dependency.OutputFolder)) { otherRepository.CheckoutAllRemoteBranches(); VersionResolver.CheckoutBranchInDependencyRepository(otherRepository, myRepository, myShortName, this); } } finally { IndentLevel--; } }
private void MigrateRepository(Repository repository, Octokit.Repository githubRepo) { var clonePath = Path.Combine(_configuration.TempPath, repository.RepositoryName); if (Directory.Exists(clonePath) && (Directory.GetFiles(clonePath).Length > 0 || Directory.GetDirectories(clonePath).Length > 0)) { using var localRepo = new LibGit2Sharp.Repository(clonePath); Policy .Handle <LibGit2SharpException>(exception => exception.Message.Contains("Secure")) .WaitAndRetry(2, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)) ) .Execute(() => { Log.Information("Pushing to github"); localRepo.Network.Push(localRepo.Branches, new PushOptions { CredentialsProvider = (url, user, cred) => new UsernamePasswordCredentials { Username = _configuration.GithubUsername, Password = _configuration.GithubToken }, }); }); } else { var cloneOptions = new CloneOptions { CredentialsProvider = (url, user, cred) => new UsernamePasswordCredentials { Username = _configuration.BitbucketUsername, Password = _configuration.BitbucketPassword }, }; Policy .Handle <LibGit2SharpException>(exception => exception.Message.Contains("Secure")) .WaitAndRetry(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)) ).Execute(() => { Log.Information("Cloning from Bitbucket"); return(LibGit2Sharp.Repository.Clone(repository.CloneUrl.ToString(), clonePath, cloneOptions)); }); using var localRepo = new LibGit2Sharp.Repository(clonePath); localRepo.Network.Remotes.Remove("origin"); var newRemote = localRepo.Network.Remotes.Add("origin", githubRepo.CloneUrl); foreach (var localRepoBranch in localRepo.Branches) { localRepo.Branches.Update(localRepoBranch, b => b.Remote = newRemote.Name, b => b.UpstreamBranch = localRepoBranch.CanonicalName); } Policy .Handle <LibGit2SharpException>(exception => exception.Message.Contains("Secure")) .WaitAndRetry(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)) ) .Execute(() => { Log.Information("Pushing to github"); localRepo.Network.Push(localRepo.Branches, new PushOptions { CredentialsProvider = (url, user, cred) => new UsernamePasswordCredentials { Username = _configuration.GithubUsername, Password = _configuration.GithubToken }, }); }); } }
/// <inheritdoc /> public async Task <IRepository> CloneRepository( Uri url, string initialBranch, string username, string password, Action <int> progressReporter, bool recurseSubmodules, CancellationToken cancellationToken) { if (url == null) { throw new ArgumentNullException(nameof(url)); } if (progressReporter == null) { throw new ArgumentNullException(nameof(progressReporter)); } logger.LogInformation("Begin clone {0} (Branch: {1})", url, initialBranch); lock (semaphore) { if (CloneInProgress) { throw new JobException(ErrorCode.RepoCloning); } CloneInProgress = true; } try { using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false)) { logger.LogTrace("Semaphore acquired"); var repositoryPath = ioManager.ResolvePath(); if (!await ioManager.DirectoryExists(repositoryPath, cancellationToken).ConfigureAwait(false)) { try { var cloneOptions = new CloneOptions { OnProgress = (a) => !cancellationToken.IsCancellationRequested, OnTransferProgress = (a) => { var percentage = 100 * (((float)a.IndexedObjects + a.ReceivedObjects) / (a.TotalObjects * 2)); progressReporter((int)percentage); return(!cancellationToken.IsCancellationRequested); }, RecurseSubmodules = recurseSubmodules, OnUpdateTips = (a, b, c) => !cancellationToken.IsCancellationRequested, RepositoryOperationStarting = (a) => !cancellationToken.IsCancellationRequested, BranchName = initialBranch, CredentialsProvider = repositoryFactory.GenerateCredentialsHandler(username, password) }; await repositoryFactory.Clone( url, cloneOptions, repositoryPath, cancellationToken) .ConfigureAwait(false); } catch { try { logger.LogTrace("Deleting partially cloned repository..."); // DCT: Cancellation token is for job, operation must run regardless await ioManager.DeleteDirectory(repositoryPath, default).ConfigureAwait(false); } catch (Exception e) { logger.LogDebug(e, "Error deleting partially cloned repository!"); } throw; } } else { logger.LogDebug("Repository exists, clone aborted!"); return(null); } } logger.LogInformation("Clone complete!"); } finally { CloneInProgress = false; } return(await LoadRepository(cancellationToken).ConfigureAwait(false)); }
public void CanRecursivelyCloneSubmodules() { var uri = new Uri($"file://{Path.GetFullPath(SandboxSubmoduleSmallTestRepo())}"); var scd = BuildSelfCleaningDirectory(); string relativeSubmodulePath = "submodule_target_wd"; // Construct the expected URL the submodule will clone from. string expectedSubmoduleUrl = Path.Combine(Path.GetDirectoryName(uri.AbsolutePath), relativeSubmodulePath); expectedSubmoduleUrl = expectedSubmoduleUrl.Replace('\\', '/'); Dictionary <string, CloneCallbackInfo> callbacks = new Dictionary <string, CloneCallbackInfo>(); CloneCallbackInfo currentEntry = null; bool unexpectedOrderOfCallbacks = false; CheckoutProgressHandler checkoutProgressHandler = (x, y, z) => { if (currentEntry != null) { currentEntry.CheckoutProgressCalled = true; } else { // Should not be called if there is not a current // callbackInfo entry. unexpectedOrderOfCallbacks = true; } }; UpdateTipsHandler remoteRefUpdated = (x, y, z) => { if (currentEntry != null) { currentEntry.RemoteRefUpdateCalled = true; } else { // Should not be called if there is not a current // callbackInfo entry. unexpectedOrderOfCallbacks = true; } return(true); }; RepositoryOperationStarting repositoryOperationStarting = (x) => { if (currentEntry != null) { // Should not be called if there is a current // callbackInfo entry. unexpectedOrderOfCallbacks = true; } currentEntry = new CloneCallbackInfo(); currentEntry.StartingWorkInRepositoryCalled = true; currentEntry.RecursionDepth = x.RecursionDepth; currentEntry.RemoteUrl = x.RemoteUrl; callbacks.Add(x.RepositoryPath, currentEntry); return(true); }; RepositoryOperationCompleted repositoryOperationCompleted = (x) => { if (currentEntry != null) { currentEntry.FinishedWorkInRepositoryCalled = true; currentEntry = null; } else { // Should not be called if there is not a current // callbackInfo entry. unexpectedOrderOfCallbacks = true; } }; CloneOptions options = new CloneOptions() { RecurseSubmodules = true, OnCheckoutProgress = checkoutProgressHandler, OnUpdateTips = remoteRefUpdated, RepositoryOperationStarting = repositoryOperationStarting, RepositoryOperationCompleted = repositoryOperationCompleted, }; string clonedRepoPath = Repository.Clone(uri.AbsolutePath, scd.DirectoryPath, options); string workDirPath; using (Repository repo = new Repository(clonedRepoPath)) { workDirPath = repo.Info.WorkingDirectory.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); } // Verification: // Verify that no callbacks were called in an unexpected order. Assert.False(unexpectedOrderOfCallbacks); Dictionary <string, CloneCallbackInfo> expectedCallbackInfo = new Dictionary <string, CloneCallbackInfo>(); expectedCallbackInfo.Add(workDirPath, new CloneCallbackInfo() { RecursionDepth = 0, RemoteUrl = uri.AbsolutePath, StartingWorkInRepositoryCalled = true, FinishedWorkInRepositoryCalled = true, CheckoutProgressCalled = true, RemoteRefUpdateCalled = true, }); expectedCallbackInfo.Add(Path.Combine(workDirPath, relativeSubmodulePath), new CloneCallbackInfo() { RecursionDepth = 1, RemoteUrl = expectedSubmoduleUrl, StartingWorkInRepositoryCalled = true, FinishedWorkInRepositoryCalled = true, CheckoutProgressCalled = true, RemoteRefUpdateCalled = true, }); // Callbacks for each expected repository that is cloned foreach (KeyValuePair <string, CloneCallbackInfo> kvp in expectedCallbackInfo) { CloneCallbackInfo entry = null; Assert.True(callbacks.TryGetValue(kvp.Key, out entry), string.Format("{0} was not found in callbacks.", kvp.Key)); Assert.Equal(kvp.Value.RemoteUrl, entry.RemoteUrl); Assert.Equal(kvp.Value.RecursionDepth, entry.RecursionDepth); Assert.Equal(kvp.Value.StartingWorkInRepositoryCalled, entry.StartingWorkInRepositoryCalled); Assert.Equal(kvp.Value.FinishedWorkInRepositoryCalled, entry.FinishedWorkInRepositoryCalled); Assert.Equal(kvp.Value.CheckoutProgressCalled, entry.CheckoutProgressCalled); Assert.Equal(kvp.Value.RemoteRefUpdateCalled, entry.RemoteRefUpdateCalled); } // Verify the state of the submodule using (Repository repo = new Repository(clonedRepoPath)) { var sm = repo.Submodules[relativeSubmodulePath]; Assert.True(sm.RetrieveStatus().HasFlag(SubmoduleStatus.InWorkDir | SubmoduleStatus.InConfig | SubmoduleStatus.InIndex | SubmoduleStatus.InHead)); Assert.NotNull(sm.HeadCommitId); Assert.Equal("480095882d281ed676fe5b863569520e54a7d5c0", sm.HeadCommitId.Sha); Assert.False(repo.RetrieveStatus().IsDirty); } }
public void Process(ScheduledTaskContext context) { if (context.Task.TaskType == TaskType) { var settings = this.orchardServices.WorkContext.CurrentSite.As <GITSettingsPart>(); if (string.IsNullOrEmpty(settings.Server)) { return; } try { this.transactionManager.Demand(); var gitPath = this.appDataFolder.Combine("Sites", shellSettings.Name, "GIT"); if (!this.appDataFolder.DirectoryExists(gitPath)) { this.appDataFolder.CreateDirectory(gitPath); } var serverRecord = this.svnServerRepository.Table.FirstOrDefault(c => c.Server == settings.Server); var path = Path.Combine(gitPath, settings.LocalFolder); var mappedPath = this.appDataFolder.MapPath(path); Repository repo = null; if (serverRecord == null) { if (this.appDataFolder.DirectoryExists(path)) { Directory.Delete(mappedPath, true); } this.appDataFolder.CreateDirectory(path); // var destination = Repository.Init(mappedPath); CloneOptions options = new CloneOptions(); options.CredentialsProvider = new LibGit2Sharp.Handlers.CredentialsHandler( (url, usernameFromUrl, types) => new UsernamePasswordCredentials() { Username = settings.Username, Password = settings.Password }); Repository.Clone(settings.Server, mappedPath, options); repo = new Repository(mappedPath); serverRecord = new GITServerRecord { Server = settings.Server, LastRevision = settings.LastRevision, FromDate = DateTime.UtcNow }; this.svnServerRepository.Create(serverRecord); this.svnServerRepository.Flush(); } repo = repo ?? new Repository(mappedPath); var branches = !string.IsNullOrEmpty(settings.Branches) ? settings.Branches.Split(',') : new[] { "master" }; branches = branches.Select(c => c.Trim()).Where(c => !string.IsNullOrEmpty(c)).ToArray(); if (string.IsNullOrEmpty(settings.Password) || string.IsNullOrEmpty(settings.Username)) { repo.Network.Fetch("origin", branches.Select(c => c + ":" + c)); } else { FetchOptions options = new FetchOptions(); options.CredentialsProvider = new LibGit2Sharp.Handlers.CredentialsHandler( (url, usernameFromUrl, types) => new UsernamePasswordCredentials() { Username = settings.Username, Password = settings.Password }); repo.Network.Fetch("origin", branches.Select(c => c + ":" + c), options); } var branchRecords = this.gitServerBranchRepository.Table.Where(c => c.ServerRecord.Id == serverRecord.Id).ToList(); foreach (var branchName in branches) { var branch = repo.Branches.FirstOrDefault(c => c.FriendlyName == branchName); if (branch == null) { continue; } var branchRecord = branchRecords.FirstOrDefault(c => c.BranchName == branchName); if (branchRecord == null) { branchRecord = new GITServerBranchRecord { BranchName = branchName, ServerRecord = serverRecord, LastUpdate = DateTime.UtcNow }; this.gitServerBranchRepository.Create(branchRecord); this.gitServerBranchRepository.Flush(); } var commits = branch.Commits.ToList(); if (!string.IsNullOrEmpty(branchRecord.Sha)) { var commit = commits.FirstOrDefault(c => c.Sha == branchRecord.Sha); if (commit != null) { int index = commits.IndexOf(commit); commits = commits.Skip(index + 1).ToList(); } } foreach (var commit in commits) { RaiseWorkflow(branchRecord, commit); } } var settingContentItem = this.orchardServices.ContentManager.Get(settings.Id); var gitSettingPart = settingContentItem.As <GITSettingsPart>(); gitSettingPart.LastSuccessfullConnectionTime = DateTime.UtcNow; gitSettingPart.LatestError = null; gitSettingPart.LatestErrorTime = null; this.transactionManager.Demand(); } catch (Exception e) { this.transactionManager.Cancel(); this.Logger.Error(e, e.Message); // We need a new transaction for storing the data this.transactionManager.RequireNew(); settings.LatestError = e.Message; settings.LatestErrorTime = DateTime.UtcNow; var settingContentItem = this.orchardServices.ContentManager.Get(settings.Id); var gitSettingPart = settingContentItem.As <GITSettingsPart>(); gitSettingPart.LatestError = e.Message; gitSettingPart.LatestErrorTime = settings.LatestErrorTime; this.transactionManager.Demand(); } finally { DateTime nextTaskDate = DateTime.UtcNow.AddMinutes(PeriodInMinutes); this.ScheduleNextTask(nextTaskDate); } } }
public List <Commit> Get(String path, String username, String password, String branch) { DirectoryInfo di = new DirectoryInfo("tempRepo/"); if (di.Exists) { BranchController.setAttributesNormal(di); di.Delete(true); } string clone; if (username != null && password != null) { var cloneOptions = new CloneOptions() { CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials { Username = username, Password = password } }; clone = Repository.Clone(path, "tempRepo/", cloneOptions); } else { clone = Repository.Clone(path, "tempRepo/"); } var list = new List <Commit>(); using (var repo = new Repository(@clone)) { // Object lookup var obj = repo.Lookup("sha"); var commit = repo.Lookup <LibGit2Sharp.Commit>("sha"); var tree = repo.Lookup <Tree>("sha"); // var tag = repo.Lookup<Tag>("sha"); ICommitLog commits = null; if (branch == null) { commits = repo.Head.Commits; } else { commits = repo.Branches[branch].Commits; } foreach (var tempCommit in commits.Take(100)) { string message; string type = "None"; if (tempCommit.Message.Contains(":")) { string[] strings = tempCommit.Message.Split(":"); message = strings[1]; type = strings[0]; } else { message = tempCommit.Message; } var commitObj = new Commit { author = tempCommit.Author, commiter = tempCommit.Committer, message = message, type = type }; list.Add(commitObj); } return(list); // Branches // special kind of reference } }
public static bool Run(CompressimagesParameters parameters, ICollector <CompressImagesMessage> compressImagesMessages, ILogger logger) { CredentialsHandler credentialsProvider = (url, user, cred) => new UsernamePasswordCredentials { Username = KnownGitHubs.Username, Password = parameters.Password }; // clone var cloneOptions = new CloneOptions { CredentialsProvider = credentialsProvider, }; Repository.Clone(parameters.CloneUrl, parameters.LocalPath, cloneOptions); var repo = new Repository(parameters.LocalPath); var remote = repo.Network.Remotes["origin"]; var isWikiCompress = parameters.CloneUrl.EndsWith(".wiki.git"); // check if we have the branch already or this is empty repo try { if (repo.Network.ListReferences(remote, credentialsProvider).Any() == false) { logger.LogInformation("CompressImagesFunction: no references found for {Owner}/{RepoName}", parameters.RepoOwner, parameters.RepoName); return(false); } if (repo.Network.ListReferences(remote, credentialsProvider).Any(x => x.CanonicalName == $"refs/heads/{KnownGitHubs.BranchName}")) { logger.LogInformation("CompressImagesFunction: branch already exists for {Owner}/{RepoName}", parameters.RepoOwner, parameters.RepoName); return(false); } } catch (Exception e) { // log + ignore logger.LogWarning(e, "CompressImagesFunction: issue checking for existing branch or empty repo for {Owner}/{RepoName}", parameters.RepoOwner, parameters.RepoName); } // check if we should switch away from the default branch if (!isWikiCompress && parameters.Settings != null && !string.IsNullOrEmpty(parameters.Settings.DefaultBranchOverride)) { logger.LogInformation( "CompressImagesFunction: default branch override for {Owner}/{RepoName} is {DefaultBranchOverride}", parameters.RepoOwner, parameters.RepoName, parameters.Settings.DefaultBranchOverride); var baseBranch = repo.Branches[$"refs/remotes/origin/{parameters.Settings.DefaultBranchOverride}"]; if (baseBranch == null) { logger.LogWarning( "CompressImagesFunction: default branch ({DefaultBranchOverride}) not found for {Owner}/{RepoName}", parameters.Settings.DefaultBranchOverride, parameters.RepoOwner, parameters.RepoName); return(false); } Commands.Checkout(repo, baseBranch); } var repoConfiguration = new RepoConfiguration(); try { // see if .imgbotconfig exists in repo root var repoConfigJson = File.ReadAllText(parameters.LocalPath + Path.DirectorySeparatorChar + ".imgbotconfig"); if (!string.IsNullOrEmpty(repoConfigJson)) { repoConfiguration = JsonConvert.DeserializeObject <RepoConfiguration>(repoConfigJson); } } catch { // ignore } // Add new compressMessage if we should compress Wiki if (repoConfiguration.CompressWiki && isWikiCompress == false) { logger.LogInformation("CompressImagesFunction: Adding Wiki image compression to queue for {Owner}/{RepoName}", parameters.RepoOwner, parameters.RepoName); compressImagesMessages.Add(new CompressImagesMessage() { InstallationId = parameters.CompressImagesMessage.InstallationId, RepoName = parameters.CompressImagesMessage.RepoName, Owner = parameters.RepoOwner, CloneUrl = $"https://github.com/{parameters.RepoOwner}/{parameters.RepoName}.wiki.git" }); } if (Schedule.ShouldOptimizeImages(repoConfiguration, repo) == false) { logger.LogInformation("CompressImagesFunction: skipping optimization due to schedule for {Owner}/{RepoName}", parameters.RepoOwner, parameters.RepoName); return(false); } // Should not create branch if we are compressing Wiki if (isWikiCompress == false) { // check out the branch repo.CreateBranch(KnownGitHubs.BranchName); var branch = Commands.Checkout(repo, KnownGitHubs.BranchName); } // reset any mean files repo.Reset(ResetMode.Mixed, repo.Head.Tip); // optimize images var imagePaths = ImageQuery.FindImages(parameters.LocalPath, repoConfiguration); var optimizedImages = OptimizeImages(repo, parameters.LocalPath, imagePaths, logger, repoConfiguration.AggressiveCompression); if (optimizedImages.Length == 0) { return(false); } if (!Threshold.MeetsThreshold(repoConfiguration, optimizedImages)) { logger.LogInformation($"Did not meet threshold. {parameters.RepoOwner}/{parameters.RepoName}"); return(false); } // create commit message based on optimizations foreach (var image in optimizedImages) { Commands.Stage(repo, image.OriginalPath); } var commitMessage = CommitMessage.Create(optimizedImages); var signature = new Signature(KnownGitHubs.ImgBotLogin, KnownGitHubs.ImgBotEmail, DateTimeOffset.Now); repo.Commit(commitMessage, signature, signature); // We just made a normal commit, now we are going to capture all the values generated from that commit // then rewind and make a signed commit var commitBuffer = Commit.CreateBuffer( repo.Head.Tip.Author, repo.Head.Tip.Committer, repo.Head.Tip.Message, repo.Head.Tip.Tree, repo.Head.Tip.Parents, true, null); var signedCommitData = CommitSignature.Sign(commitBuffer + "\n", parameters.PgpPrivateKey, parameters.PgPPassword); repo.Reset(ResetMode.Soft, repo.Head.Commits.Skip(1).First().Sha); var commitToKeep = repo.ObjectDatabase.CreateCommitWithSignature(commitBuffer, signedCommitData); repo.Refs.UpdateTarget(repo.Refs.Head, commitToKeep); // Should use "master" if we are compressing Wiki if (isWikiCompress) { var branchAgain = Commands.Checkout(repo, "master"); } else { var branchAgain = Commands.Checkout(repo, KnownGitHubs.BranchName); } repo.Reset(ResetMode.Hard, commitToKeep.Sha); // verify images are not corrupted by reading from git // see https://github.com/dabutvin/ImgBot/issues/273 try { foreach (var image in optimizedImages) { if (image.OriginalPath.EndsWith(".svg")) { // do not use ImageMagick to verify SVGs continue; } new MagickImage(image.OriginalPath).Dispose(); } } catch (MagickErrorException) { logger.LogError("Corrupt images after reset!"); return(false); } // push to GitHub if (isWikiCompress) { repo.Network.Push(remote, "refs/heads/master", new PushOptions { CredentialsProvider = credentialsProvider, }); } else { repo.Network.Push(remote, $"refs/heads/{KnownGitHubs.BranchName}", new PushOptions { CredentialsProvider = credentialsProvider, }); } return(true); }
private static void Main(string[] args) { var result = CommandLine.Parser.Default.ParseArguments <Options>(args); if (!result.Errors.Any()) { string url = result.Value.Repository; var brancOption = result.Value.Branch; var branchSepIndex = brancOption.IndexOf('/'); if (branchSepIndex > 0) { var credentials = new UsernamePasswordCredentials { Username = result.Value.UserName, Password = result.Value.Password }; CredentialsHandler credHandler = (s, fromUrl, types) => credentials; var remote = brancOption.Substring(0, branchSepIndex); var branch = brancOption.Substring(branchSepIndex + 1, brancOption.Length - branchSepIndex - 1); var workingDirectory = result.Value.LocalRepoPath; var isLocalRepoExist = Repository.Discover(workingDirectory); if (isLocalRepoExist == null) { var cloneOptions = new CloneOptions { CredentialsProvider = credHandler }; Repository.Clone(url, workingDirectory, cloneOptions); } Repository repo = null; try { var tagName = result.Value.TagName; repo = new Repository(workingDirectory); //repo.Fetch(remote, new FetchOptions(){CredentialsProvider = credHandler}); repo.Network.Pull(new Signature(result.Value.UserName, result.Value.Email, new DateTimeOffset()), new PullOptions() { FetchOptions = new FetchOptions() { CredentialsProvider = credHandler } }); repo.ApplyTag(tagName); PushChanges(repo, credHandler, remote, branch, tagName); Console.WriteLine("Tagged :{0}", result.Value.TagName); } catch (Exception ex) { Console.WriteLine("Error happened {0}", ex.Message); } finally { if (repo != null) { repo.Dispose(); } } } } Console.ReadLine(); }
internal void InitRepository(string path, RepositoryConfig config) { this.config = config; Logger.Write("Initializing Repository."); _repoBase = path; if (Directory.Exists(path) == false) { Directory.CreateDirectory(path); } if (Directory.Exists(path + Path.DirectorySeparatorChar + ".git")) { Logger.Write("Repository found, opening."); /* already a git repo */ _repository = new Repository(_repoBase); } else { if (config.Url.Length > 0) { Logger.Write("Repository URL is set, cloning repo to disk."); /* repository is configured with a remote, try cloning from there */ try { var co = new CloneOptions(); co.CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials { Username = config.User, Password = config.Password }; var result = Repository.Clone(config.Url, _repoBase, co); } catch (Exception ex) { /* Cloning failed, maybe it doesn't exist at the remote yet. Gitlab lets you push to a non-existant repo to create it, so we should continue */ Logger.Write("Failed to clone repo, creating new repository."); Repository.Init(_repoBase); } } else { Repository.Init(_repoBase); } _repository = new Repository(_repoBase); } /* confirm this repository has an "origin" remote */ if (_repository.Network.Remotes["origin"] != null) { /* there is an origin, make sure it points to the URL in config */ if (_repository.Network.Remotes["origin"].Url.Equals(config.Url) == false) { Logger.Write("Repository origin doesn't match config. Updating..."); _repository.Network.Remotes.Update("origin", r => r.Url = config.Url); } } else { Logger.Write("Repository doesn't have an origin. Adding..."); /* no origin, lets set one if we have a URL */ if (config.Url.Length > 0) { _repository.Network.Remotes.Add("origin", config.Url); } } /* confirm .gitignore is present */ var gitAttrFile = Path.Join(_repoBase, ".gitattributes"); if (File.Exists(gitAttrFile) == false) { Logger.Write("Repository does not have a gitattributes present. Adding..."); File.WriteAllText(gitAttrFile, "* text eol=crlf"); Commands.Stage(_repository, gitAttrFile); Signature author = new Signature("PIVET", "PIVET", DateTime.Now); Signature committer = author; Commit commit = _repository.Commit("Added gitattributes for consistent line endings", author, committer); } }
public string Clone(string sourceUrl, string workdirPath, CloneOptions options) => Repository.Clone(sourceUrl, workdirPath, options);
public static Repository PrepareRepository( string repositoryDescriptor, string descriptorIsFor, bool allowEmpty, bool allowRemote, int maxDepth, string mustLocalTailingMessage = "", string mustExistsTailingMessage = "") { string repositoryPath; #if SUPPORT_REMOTE_REPOSITORY if (UrlSchemas.Any(repositoryDescriptor.StartsWith)) { if (!allowRemote) { throw new InvalidUsageException($"{descriptorIsFor} must be local repository" + mustLocalTailingMessage + "."); } var tempDir = Path.GetTempFileName(); File.Delete(tempDir); Directory.CreateDirectory(tempDir); var options = new CloneOptions { RecurseSubmodules = false }; repositoryPath = Repository.Init(repositoryDescriptor); Directory.CreateDirectory(repositoryPath); repositoryPath = CommandGit.ShallowClone(repositoryDescriptor, tempDir, maxDepth); using var repo = new Repository(repositoryPath); foreach (var branch in repo.Branches) { if (branch.IsRemote && branch.RemoteName == "origin") { var localName = branch.FriendlyName.RemovePrefix("origin/"); repo.Config.Set($"branch.{localName}.remote", "origin"); repo.Config.Set($"branch.{localName}.merge", $"refs/heads/{localName}"); repo.Branches.Add(localName, branch.Tip); } } } else #endif { repositoryPath = Path.Join(repositoryDescriptor, ".git"); if (!Directory.Exists(repositoryPath)) { if (!allowEmpty) { throw new InvalidUsageException($"{descriptorIsFor} is not exists." + mustExistsTailingMessage); } repositoryPath = Repository.Init(repositoryDescriptor); } } return(new Repository(repositoryPath)); }
/// <summary> /// Clone any object /// </summary> /// <typeparam name="T"></typeparam> /// <param name="sourceObject">The object to clone</param> /// <param name="options">Specify the Clone options</param> /// <param name="ignoreProperties">A list of property names to ignore</param> /// <returns></returns> public static T Clone <T>(this T sourceObject, CloneOptions options, params Expression <Func <T, object> >[] ignoreProperties) { var cloneProvider = new CloneProvider <T>(); return(cloneProvider.Clone(sourceObject, options, CloneConfiguration.DefaultMaxDepth, ignoreProperties)); }
public object Clone(CloneOptions options) { return(this); }
/// <summary> /// Clone any object /// </summary> /// <typeparam name="T"></typeparam> /// <param name="sourceObject">The object to clone</param> /// <param name="options">Specify the Clone options</param> /// <param name="ignorePropertiesOrPaths">A list of property names or fully qualified paths to ignore</param> /// <returns></returns> public static T Clone <T>(this T sourceObject, CloneOptions options, params string[] ignorePropertiesOrPaths) { var cloneProvider = new CloneProvider <T>(); return(cloneProvider.Clone(sourceObject, options, CloneConfiguration.DefaultMaxDepth, ignorePropertiesOrPaths)); }
private static void UpdateExistingPullRequest( GitHubAuth gitHubAuth, PullRequestOptions prOptions, string commitMessage, GitHubBranch upstreamBranch) { // PullRequestCreator ends up force-pushing updates to an existing PR which is not great when the logic // gets called on a schedule (see https://github.com/dotnet/dotnet-docker/issues/1114). To avoid this, // it needs the ability to only update files that have changed from the existing PR. Because the // PullRequestCreator class doesn't rely on there being a locally cloned repo, it doesn't have an // efficient way to determine whether files have changed or not. Update-dependencies would have to // implement logic which pulls down each file individually from the API and compare it to what exists // in the local repo. Since that's not an efficient process, this method works by cloning the PR's // branch to a temporary repo location, grabbing the whole repo where the original updates from // update-dependencies were made and copying it into the temp repo, and committing and pushing // those changes in the temp repo back to the PR's branch. string tempRepoPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); try { string branchName = prOptions.BranchNamingStrategy.Prefix(upstreamBranch.Name); CloneOptions cloneOptions = new CloneOptions { BranchName = branchName }; // Clone the PR's repo/branch to a temp location Repository.Clone($"https://github.com/{gitHubAuth.User}/{Options.GitHubProject}", tempRepoPath, cloneOptions); // Remove all existing directories and files from the temp repo ClearRepoContents(tempRepoPath); // Copy contents of local repo changes to temp repo DirectoryCopy(".", tempRepoPath); using Repository repo = new Repository(tempRepoPath); RepositoryStatus status = repo.RetrieveStatus(new StatusOptions()); // If there are any changes from what exists in the PR if (status.IsDirty) { Commands.Stage(repo, "*"); Signature signature = new Signature(Options.GitHubUser, Options.GitHubEmail, DateTimeOffset.Now); repo.Commit(commitMessage, signature, signature); Branch branch = repo.Branches[$"origin/{branchName}"]; PushOptions pushOptions = new PushOptions { CredentialsProvider = (url, user, credTypes) => new UsernamePasswordCredentials { Username = Options.GitHubPassword, Password = string.Empty } }; Remote remote = repo.Network.Remotes["origin"]; string pushRefSpec = $@"refs/heads/{branchName}"; repo.Network.Push(remote, pushRefSpec, pushOptions); } } finally { // Cleanup temp repo DeleteRepoDirectory(tempRepoPath); } }
private static async Task WriteContributorsToRepo(string username, string password) { var nameOfThankyouBranch = "thankyou"; var repoUrl = _parsedOptions.gitRepositoryUrl; var contributorsHeader = _parsedOptions.acknowledgementSection; var fileHoldingContributorsInfo = _parsedOptions.fileInRepoForAcknowledgement; string tempPathGitFolder = CreateTempFolderForTheRepo(); var gitCredentialsHandler = new CredentialsHandler( (url, usernameFromUrl, types) => new UsernamePasswordCredentials() { Username = username, Password = password }); var cloneOptions = new CloneOptions(); cloneOptions.CredentialsProvider = gitCredentialsHandler; LibGit2Sharp.Repository.Clone(repoUrl, tempPathGitFolder, cloneOptions); using (var repo = new LibGit2Sharp.Repository(tempPathGitFolder)) { var remote = repo.Network.Remotes["origin"]; var defaultBranch = repo.Branches.FirstOrDefault(b => b.IsCurrentRepositoryHead == true); var refSpecs = remote.FetchRefSpecs.Select(x => x.Specification); var remoteThankYouBranch = repo.Branches.FirstOrDefault(b => b.FriendlyName == repo.Network.Remotes.FirstOrDefault()?.Name + "/" + nameOfThankyouBranch); if (remoteThankYouBranch != null) { Commands.Checkout(repo, remoteThankYouBranch); } if (repo.Head.FriendlyName != nameOfThankyouBranch) { var newThankyouBranch = repo.CreateBranch(nameOfThankyouBranch); repo.Branches.Update(newThankyouBranch, b => b.UpstreamBranch = newThankyouBranch.CanonicalName, b => b.Remote = repo.Network.Remotes.First().Name); Commands.Checkout(repo, newThankyouBranch); } var pathToReadme = Path.Combine(tempPathGitFolder, fileHoldingContributorsInfo); // Change the file and save it var inputLines = await File.ReadAllLinesAsync(pathToReadme); var outputLines = MarkdownProcessor.AddContributorsToMarkdownFile(inputLines, _contributorsToday); await File.WriteAllLinesAsync(pathToReadme, outputLines); var status = repo.RetrieveStatus(fileHoldingContributorsInfo); if (status == FileStatus.ModifiedInWorkdir) { // Commit the file to the repo, on a non-master branch repo.Index.Add(fileHoldingContributorsInfo); repo.Index.Write(); var gitAuthorName = _parsedOptions.gitAuthorName; var gitAuthorEmail = _parsedOptions.gitAuthorEmail; // Create the committer's signature and commit var author = new LibGit2Sharp.Signature(gitAuthorName, gitAuthorEmail, DateTime.Now); var committer = author; // Commit to the repository var commit = repo.Commit("A new list of awesome contributors", author, committer); //Push the commit to origin LibGit2Sharp.PushOptions options = new LibGit2Sharp.PushOptions(); options.CredentialsProvider = gitCredentialsHandler; repo.Network.Push(repo.Head, options); // Login to GitHub with Octokit var githubClient = new GitHubClient(new ProductHeaderValue(username)); githubClient.Credentials = new Octokit.Credentials(password); try { // Create a PR on the repo for the branch "thank you" await githubClient.PullRequest.Create(username, "thankyou", new NewPullRequest("Give credit for people on Twitch chat", nameOfThankyouBranch, defaultBranch.FriendlyName)); } catch (Exception ex) { // It's alright, the PR is already there. No harm is done. } } } }
public IRepository CloneRepository(string sourceUrl, string workdirPath, CloneOptions options) { Repository.Clone(sourceUrl, workdirPath, options); return(new Repository(workdirPath)); }