Created
January 24, 2020 10:52
-
-
Save pizycki/2f9605d343424aa7aada2404b4c24834 to your computer and use it in GitHub Desktop.
Delete old Git branches, filtered by name and date
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| let inline (--) (x:string) (y:string) = x.Replace(y, String.Empty) | |
| module Wildcards = | |
| let private wildcardToRegular wc = | |
| "^" + Regex.Escape(wc).Replace("\\*", ".*") + "$" | |
| let accepts wildcard branch = | |
| let regex = wildcardToRegular wildcard | |
| let rgx = new Regex(regex, RegexOptions.IgnoreCase) | |
| rgx.IsMatch(branch) | |
| module Repo = | |
| let fetch (repo:Repository) (remote:Remote) = | |
| let refSpecs = remote.FetchRefSpecs |> Seq.map (fun x -> x.Specification) |> List.ofSeq | |
| let log = "" | |
| Commands.Fetch(repo, remote.Name, refSpecs, null, log) | |
| log | |
| module Commit = | |
| let commitTime (c:Commit) = | |
| c.Committer.When | |
| module Branch = | |
| open Commit | |
| let bareName (branch:Branch) = | |
| if branch.IsRemote | |
| then branch.FriendlyName -- (branch.RemoteName + "/") | |
| else branch.FriendlyName | |
| let olderThan (timespan:TimeSpan) (branch:Branch) = | |
| DateTime.Now - (branch.Tip |> commitTime).DateTime > timespan | |
| let deleteRemote (repo: Repository) | |
| (remote: Remote) | |
| (branch: Branch) | |
| = | |
| let ref = String.Format(":refs/heads/{0}", (bareName branch)) | |
| let opt = new PushOptions() | |
| opt.OnPushStatusError <- new PushStatusErrorHandler(fun err -> err.Dump()) | |
| repo.Network.Push(remote, [ref], opt) | |
| module BranchDelete = | |
| open Branch | |
| type BranchLock = | |
| | Strict of string | |
| | Wildcard of string | |
| let private accepts (branch: Branch) (lock:BranchLock) = | |
| let bareName = bareName branch | |
| match lock with | |
| | Strict s -> s = bareName | |
| | Wildcard wc -> Wildcards.accepts wc bareName | |
| /// Is branch locked by any lock | |
| let locked locks branch = | |
| let locks = locks |> Seq.map (fun x-> accepts branch x) |> List.ofSeq | |
| locks |> Seq.exists id | |
| /////////////////////////////////////////////////////////////////////////////// | |
| open System | |
| open Branch | |
| open Commit | |
| open BranchDelete | |
| let dump x = x.Dump(); | |
| let locks = [ | |
| BranchLock.Strict "HEAD" | |
| BranchLock.Strict "master" | |
| BranchLock.Strict "develop" | |
| BranchLock.Wildcard "release/*" | |
| BranchLock.Wildcard "refactor/*" | |
| ] | |
| let repo = new Repository("""c:\bc\bc.hub""") | |
| let origin = repo.Network.Remotes |> Seq.exactlyOne | |
| let log = Repo.fetch repo origin | |
| printfn "%s" log | |
| let ageLimit = TimeSpan.FromDays(21.0) | |
| let toBeDeleted = | |
| repo.Branches | |
| |> Seq.where (fun x -> not (locked locks x)) | |
| |> Seq.where (olderThan ageLimit) | |
| toBeDeleted | |
| |> Seq.map (fun x -> | |
| {| Remote = x.RemoteName | |
| Name = bareName x | |
| LastCommit = x.Tip |> commitTime |}) | |
| |> Seq.sortBy (fun x -> x.LastCommit) | |
| |> dump | |
| toBeDeleted |> Seq.length |> dump | |
| toBeDeleted | |
| |> Seq.iter (deleteRemote repo origin) | |
| //let oneDay = TimeSpan.FromDays(1.0) | |
| //repo.Branches |> Seq.filter (fun x ->x.FriendlyName = "master")|> Seq.exactlyOne |> (olderThan oneDay) |> dump |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment