Skip to content

Instantly share code, notes, and snippets.

@pizycki
Created January 24, 2020 10:52
Show Gist options
  • Select an option

  • Save pizycki/2f9605d343424aa7aada2404b4c24834 to your computer and use it in GitHub Desktop.

Select an option

Save pizycki/2f9605d343424aa7aada2404b4c24834 to your computer and use it in GitHub Desktop.
Delete old Git branches, filtered by name and date
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