-
Notifications
You must be signed in to change notification settings - Fork 287
Implemented a rebase feature #635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,7 +37,6 @@ public static bool Run(CompressimagesParameters parameters, ICollector<CompressI | |
| { | ||
| CredentialsProvider = credentialsProvider, | ||
| }; | ||
|
|
||
| Repository.Clone(parameters.CloneUrl, parameters.LocalPath, cloneOptions); | ||
|
|
||
| var repo = new Repository(parameters.LocalPath); | ||
|
|
@@ -52,19 +51,20 @@ public static bool Run(CompressimagesParameters parameters, ICollector<CompressI | |
| 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 the branch exists and has been modified by the user | ||
| if (parameters.IsRebase && repo.Branches[$"refs/remotes/origin/{KnownGitHubs.BranchName}"].Tip.Author.Name != KnownGitHubs.ImgBotLogin) | ||
| { | ||
| logger.LogInformation("CompressImagesFunction: imgbot branch has been modified by the user."); | ||
| return false; | ||
| } | ||
|
|
||
| // check if we should switch away from the default branch | ||
| if (!isWikiCompress && parameters.Settings != null && !string.IsNullOrEmpty(parameters.Settings.DefaultBranchOverride)) | ||
| { | ||
|
|
@@ -123,19 +123,26 @@ public static bool Run(CompressimagesParameters parameters, ICollector<CompressI | |
| return false; | ||
| } | ||
|
|
||
| // Should not create branch if we are compressing Wiki | ||
| if (isWikiCompress == 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); | ||
| } | ||
| else if (parameters.IsRebase) | ||
| { | ||
| // if rebasing, fetch the branch | ||
| var refspec = string.Format("{0}:{0}", KnownGitHubs.BranchName); | ||
| Commands.Fetch(repo, "origin", new List<string> { refspec }, null, "fetch"); | ||
| } | ||
|
|
||
| // 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; | ||
|
|
@@ -156,6 +163,71 @@ public static bool Run(CompressimagesParameters parameters, ICollector<CompressI | |
| 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; | ||
|
|
||
| // we need to reset the default branch so that we can | ||
| // rebase to it later. | ||
| repo.Reset(ResetMode.Hard, repo.Head.Commits.ElementAt(1)); | ||
|
|
||
| Commands.Checkout(repo, KnownGitHubs.BranchName); | ||
|
|
||
| // reset imgbot branch removing old commit | ||
| repo.Reset(ResetMode.Hard, repo.Head.Commits.ElementAt(1)); | ||
|
|
||
| // 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); | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Really interesting thought about optimizing the process to only compress the new or modified images 👍 Having this as part of the rebase is one small part of the overall optimization, because as it stands, every time a new image is added, when we are not rebasing, we run the optimizer over every single image anyway. Because of the complexity here, I'd like to pull this functionality into a separate PR. Let's get the rebase feature all finished up and shipped and then come back to focus on optimizing the compute resources looking at the whole system. For the first iteration, when we rebase, we can trigger a full optimization run.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, removing this for now 👍 For optimizing the whole thing, what do you think about a checksum-based solution? We could store all (filename,checksum) entries on a table, and compare every time the compression function is called, therefore compressing only the images in which the checksum does not match. In terms of operation cost, this solution would mean a storage/processing trade-off. I believe in the long run, and specially in repositories with hundreds/thousands of images the trade-off would be justified.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's a cool idea 👍 and i think you're right, could be a huge win in the long run. |
||
|
|
||
| // 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(Path.Combine(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( | ||
|
|
@@ -217,7 +289,12 @@ public static bool Run(CompressimagesParameters parameters, ICollector<CompressI | |
| } | ||
| else | ||
| { | ||
| repo.Network.Push(remote, $"refs/heads/{KnownGitHubs.BranchName}", new PushOptions | ||
| var refs = $"refs/heads/{KnownGitHubs.BranchName}"; | ||
| if (parameters.IsRebase) | ||
| refs = refs.Insert(0, "+"); | ||
javierron marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| logger.LogInformation("refs: {refs}", refs); | ||
|
|
||
| repo.Network.Push(remote, refs, new PushOptions | ||
| { | ||
| CredentialsProvider = credentialsProvider, | ||
| }); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.IO; | ||
| using System.Linq; | ||
|
|
||
| namespace CompressImagesFunction | ||
| { | ||
| public partial class CompressionResult | ||
| { | ||
| // If items with the same "Title" are found, the merge will ignore the entry from array2 | ||
| public static CompressionResult[] Merge(CompressionResult[] array1, CompressionResult[] array2) | ||
| { | ||
| List<CompressionResult> list = new List<CompressionResult>(); | ||
| list.AddRange(array1); | ||
| list.AddRange(array2); | ||
|
|
||
| var nonRepeat = list.GroupBy(x => x.Title).Select(y => y.First()); | ||
|
|
||
| return nonRepeat.ToArray(); | ||
| } | ||
|
|
||
| public static CompressionResult[] Filter(CompressionResult[] optimizedImages, string[] toRemove) | ||
| { | ||
| var relativePaths = toRemove.Select(path => Path.GetFileName(path)); | ||
| var filtered = optimizedImages.Where(r => !relativePaths.Contains(r.Title)); | ||
| return filtered.ToArray(); | ||
| } | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.