[{"data":1,"prerenderedAt":866},["Reactive",2],{"navigation":3,"/posts/cleaning-git-branches":204,"/posts/cleaning-git-branches-surround":836},[4,192,200],{"title":5,"_path":6,"children":7,"icon":191},"Blog","/posts",[8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59,62,65,68,71,74,77,80,83,86,89,92,95,98,101,104,107,110,113,116,119,122,125,128,131,134,137,140,143,146,149,152,155,158,161,164,167,170,173,176,179,182,185,188],{"title":9,"_path":10},"Testing your API with REST Client","/posts/testing-your-api-with-rest-client",{"title":12,"_path":13},"HTML templating in Xamarin","/posts/html-templating-in-xamarin",{"title":15,"_path":16},"Goodbye Azure Portal, Welcome Azure CLI","/posts/welcome-azure-cli",{"title":18,"_path":19},"Coming across Gitpod","/posts/gitpod",{"title":21,"_path":22},"Handle token retrieval while querying an API","/posts/delegating-handler",{"title":24,"_path":25},"Clean up your local git branches.","/posts/cleaning-git-branches",{"title":27,"_path":28},"Automate configuration of Teams Tab SSO with PowerShell.","/posts/teams-sso-powershell",{"title":30,"_path":31},"How to do a technology watch? - Part 1","/posts/technology-watch-part1",{"title":33,"_path":34},"How to do a technology watch? - Part 2","/posts/technology-watch-part2",{"title":36,"_path":37},"You almost no longer need Key Vault references for Azure Functions.","/posts/azure-functions-custom-configuration",{"title":39,"_path":40},"How to do a technology watch? - Part 3","/posts/technology-watch-part3",{"title":42,"_path":43},"Forget DevOps, the future is already here!","/posts/devops-future",{"title":45,"_path":46},"Week 9, 2021 - Tips I learned this week","/posts/w09-2021-tips-learned-this-week",{"title":48,"_path":49},"Week 12, 2021 - Tips I learned this week","/posts/w12-2021-tips-learned-this-week",{"title":51,"_path":52},"Week 14, 2021 - Tips I learned this week","/posts/w14-2021-tips-learned-this-week",{"title":54,"_path":55},"Once upon a time in .NET","/posts/once-upon-a-time-in-dotnet",{"title":57,"_path":58},"Install your applications with winget","/posts/winget-import",{"title":60,"_path":61},"Customize your applications when installing them with winget","/posts/winget-override",{"title":63,"_path":64},"Week 22, 2021 - Tips I learned this week","/posts/w22-2021-tips-learned-this-week",{"title":66,"_path":67},"How to connect to an Azure SQL Database from C# using Azure AD","/posts/sqlclient-active-directory-authent",{"title":69,"_path":70},"Producing packages for Windows Package Manager","/posts/wingetcreate",{"title":72,"_path":73},"4 tips about GitHub Actions environment variables and contexts","/posts/github-actions-var-and-context",{"title":75,"_path":76},"AzureWebJobsStorage, the secret you don't need in your Function App.","/posts/azure-functions-without-azurewebjobsstorage",{"title":78,"_path":79},"ASP.NET Core - Lost in configuration","/posts/lost-in-configuration",{"title":81,"_path":82},"Week 39, 2021 - Tips I learned this week","/posts/w39-2021-tips-learned-this-week",{"title":84,"_path":85},"Week 41, 2021 - Tips I learned this week","/posts/w41-2021-tips-learned-this-week",{"title":87,"_path":88},"Migrating and open-sourcing my blog","/posts/migrating-blog",{"title":90,"_path":91},"Week 45, 2021 - Tips I learned this week","/posts/w45-2021-tips-learned-this-week",{"title":93,"_path":94},"Organize your GitHub stars with Astral","/posts/astral",{"title":96,"_path":97},"Pulumi with an Azure Blob Storage backend","/posts/pulumi-azure-backend",{"title":99,"_path":100},"IaC Hot Reload with Pulumi Watch","/posts/pulumi-watch",{"title":102,"_path":103},"Week 2, 2022 - Tips I learned this week","/posts/w02-2022-tips-learned-this-week",{"title":105,"_path":106},"Week 3, 2022 - Tips I learned this week","/posts/w03-2022-tips-learned-this-week",{"title":108,"_path":109},"Week 5, 2022 - Tips I learned this week","/posts/w05-2022-tips-learned-this-week",{"title":111,"_path":112},"How to provision an Azure SQL Database with Active Directory authentication","/posts/sqldatabase-active-directory-authent",{"title":114,"_path":115},"Why will I choose Pulumi over Terraform for my next project?","/posts/pulumi-vs-terraform",{"title":117,"_path":118},"Week 19, 2022 - Tips I learned this week","/posts/w19-2022-tips-learned-this-week",{"title":120,"_path":121},"Week 20, 2022 - Tips I learned this week","/posts/w20-2022-tips-learned-this-week",{"title":123,"_path":124},"Keeping secrets secure when using API Clients","/posts/http-clients-secrets",{"title":126,"_path":127},"What made me want to be a developer?","/posts/be-a-developer",{"title":129,"_path":130},"What can we do when stuck with a programming problem?","/posts/get-unstuck",{"title":132,"_path":133},"How did I automate the setup of my developer Windows laptop?","/posts/automate-developer-machine",{"title":135,"_path":136},"Discussion about API clients","/posts/http-clients",{"title":138,"_path":139},"Week 46, 2022 - Tips I learned this week","/posts/w46-2022-tips-learned-this-week",{"title":141,"_path":142},"When Pulumi met Nuke: a .NET love story","/posts/when-pulumi-met-nuke",{"title":144,"_path":145},"A year of learning and sharing - Dev Retro 2022","/posts/2022-retro",{"title":147,"_path":148},"Perform Dynamic Execution of an npm Package","/posts/pnpm-dlx",{"title":150,"_path":151},"Manage multiple Node.js versions","/posts/pnpm-env",{"title":153,"_path":154},"Introducing the Vue.js CI/CD series","/posts/vuecicd-introduction",{"title":156,"_path":157},"Execute commands using your project dependencies","/posts/pnpm-exec",{"title":159,"_path":160},"Vue.js CI/CD: Continuous Integration","/posts/vuecicd-ci",{"title":162,"_path":163},"Who is using pnpm?","/posts/pnpm-who-is-using",{"title":165,"_path":166},"Create an Azure-Ready GitHub Repository using Pulumi","/posts/azure-ready-github-repository",{"title":168,"_path":169},"Deploying to Azure from Azure DevOps without secrets","/posts/ado-workload-identity-federation",{"title":171,"_path":172},"Effortlessly Configure GitHub Repositories for Azure Deployment via OIDC","/posts/scripting-azure-ready-github-repository",{"title":174,"_path":175},"Playing with the .NET 8 Web API template","/posts/playing-with-dotnet8",{"title":177,"_path":178},"Another year of sharing and learning - Dev Retro 2023","/posts/2023-retro",{"title":180,"_path":181},"Week 4, 2024 - Tips I learned this week","/posts/w04-2024-tips-learned-this-week",{"title":183,"_path":184},"Using dependency injection with Azure .NET SDK","/posts/azure-sdk-di",{"title":186,"_path":187},"Having Fun With IT Event Calendars","/posts/it-event-calendars",{"title":189,"_path":190},"Call your Azure AD B2C protected API with authenticated HTTP requests from your JetBrains IDE","/posts/http-clients-oauth2","i-heroicons-newspaper",{"title":193,"_path":194,"children":195,"icon":199},"Goodies","/goodies",[196],{"title":197,"_path":198},"My Git Cheat Sheet","/goodies/gitcheatsheet","i-heroicons-gift-solid",{"title":201,"_path":202,"icon":203},"About","/about","i-heroicons-user-circle-solid",{"_path":25,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":24,"description":208,"lead":209,"date":210,"image":211,"badge":213,"tags":215,"body":220,"_type":831,"_id":832,"_source":833,"_file":834,"_extension":835},"posts",false,"","When working on a git repository, I often have to manually delete old local branches that I don't use anymore. That's not a huge waste of time but still, that's something I have to do quite often so I decided to automate that.","Playing with Nushell to create a useful git alias to delete unused local git branches.","2020-04-06T00:00:00.000Z",{"src":212},"/images/branches_1.jpg",{"label":214},"Tips",[216,217,218,219],"tooling","git","shell","nushell",{"type":221,"children":222,"toc":825},"root",[223,230,237,242,258,291,296,310,316,336,341,354,375,385,398,429,435,455,464,485,494,506,515,520,708,714,735,771,792,805,814,819],{"type":224,"tag":225,"props":226,"children":227},"element","p",{},[228],{"type":229,"value":208},"text",{"type":224,"tag":231,"props":232,"children":234},"h2",{"id":233},"why-do-i-end-up-having-outdated-local-branches-on-my-git-repositories",[235],{"type":229,"value":236},"Why do I end up having outdated local branches on my git repositories?",{"type":224,"tag":225,"props":238,"children":239},{},[240],{"type":229,"value":241},"First, let's talk about how I end up having many useless local git branches. That's something quite usual and directly linked with the way I work with git but chances are that you are having the same issue.",{"type":224,"tag":225,"props":243,"children":244},{},[245,247,256],{"type":229,"value":246},"At work I am working in a small team of developers, we host our git repositories in ",{"type":224,"tag":248,"props":249,"children":253},"a",{"href":250,"rel":251},"https://azure.microsoft.com/en-us/services/devops/repos/",[252],"nofollow",[254],{"type":229,"value":255},"Azure DevOps",{"type":229,"value":257}," and we try to respect the following practices in our daily development:",{"type":224,"tag":259,"props":260,"children":261},"ul",{},[262,268,273],{"type":224,"tag":263,"props":264,"children":265},"li",{},[266],{"type":229,"value":267},"having a main branch (master) on which nobody can commit directly",{"type":224,"tag":263,"props":269,"children":270},{},[271],{"type":229,"value":272},"always create a short-lived branch (also called feature branch) when developing a new feature of the application",{"type":224,"tag":263,"props":274,"children":275},{},[276,278],{"type":229,"value":277},"only merge a feature branch on the main branch through an Azure DevOps pull request\n",{"type":224,"tag":259,"props":279,"children":280},{},[281,286],{"type":224,"tag":263,"props":282,"children":283},{},[284],{"type":229,"value":285},"the PR triggers a pipeline that ensures the code build correctly, follow some conventions (with a Sonar analysis for instance) and that unit tests pass",{"type":224,"tag":263,"props":287,"children":288},{},[289],{"type":229,"value":290},"the PR can only be completed after a code review of at least one member of the team",{"type":224,"tag":225,"props":292,"children":293},{},[294],{"type":229,"value":295},"These practices allow us to keep good quality in our code base, not to mess with our git repositories, and ensure the main branch always builds.",{"type":224,"tag":225,"props":297,"children":298},{},[299,301,308],{"type":229,"value":300},"However, each week we are creating a lot of branches that need to be deleted as once merged we no longer need to have them. When a pull request is approved and we decide to complete it, Azure DevOps takes care of automatically merging the associated feature branch into master and deleting it from the repository. Once that's done, I can do a ",{"type":224,"tag":302,"props":303,"children":305},"code",{"className":304},[],[306],{"type":229,"value":307},"git fetch --prune",{"type":229,"value":309}," on my laptop to have the feature branch removed from the remote of my local repository (by the way, I recommend you to directly set the fetch command to prune by default in your git config 👌). Nevertheless, this does not delete the local version of the feature branch thus our problem: over time if we do not think of deleting all these outdated branches, they become too many and we don't even know which branch should be kept or not.",{"type":224,"tag":231,"props":311,"children":313},{"id":312},"git-commands-to-identify-and-delete-outdated-branches",[314],{"type":229,"value":315},"Git commands to identify and delete outdated branches.",{"type":224,"tag":225,"props":317,"children":318},{},[319,321,326,328,334],{"type":229,"value":320},"As my outdated branches are already removed from my remote (thanks to ",{"type":224,"tag":302,"props":322,"children":324},{"className":323},[],[325],{"type":229,"value":307},{"type":229,"value":327},") it should not be too complicated to use some git commands to guess which branches are not useful anymore. But as it's Azure DevOps that took care of merging them (sometimes with a squash) I cannot use the ",{"type":224,"tag":302,"props":329,"children":331},{"className":330},[],[332],{"type":229,"value":333},"git branch --merged",{"type":229,"value":335}," command.",{"type":224,"tag":225,"props":337,"children":338},{},[339],{"type":229,"value":340},"If I take my blog repository as an example I have a bunch of branches: some that could be useful (articles I have started to write but did not finish yet and I don't know if I will one day 😋) and some that are already merged into my master branch through a PR.",{"type":224,"tag":225,"props":342,"children":343},{},[344],{"type":224,"tag":345,"props":346,"children":353},"img",{"alt":347,"className":348,"src":351,"width":352},"List all git branches in the terminal.",[349,350],"rounded-lg","mx-auto","/posts/images/cleaningbranches_shell_1.png",800,[],{"type":224,"tag":225,"props":355,"children":356},{},[357,359,365,367,373],{"type":229,"value":358},"The command ",{"type":224,"tag":302,"props":360,"children":362},{"className":361},[],[363],{"type":229,"value":364},"git branch -vl",{"type":229,"value":366}," (which lists in a verbose way the local git branches) gives us an interesting view as it shows the branches for which the remote has been deleted specifying a ",{"type":224,"tag":302,"props":368,"children":370},{"className":369},[],[371],{"type":229,"value":372},"[gone]",{"type":229,"value":374}," for them. These branches correspond to the outdated branches we want to delete.",{"type":224,"tag":225,"props":376,"children":377},{},[378],{"type":224,"tag":345,"props":379,"children":384},{"alt":380,"className":381,"src":382,"width":383},"List all git branches with verbose tag in terminal.",[349,350],"/posts/images/cleaningbranches_shell_2.png",1000,[],{"type":224,"tag":225,"props":386,"children":387},{},[388,390,396],{"type":229,"value":389},"We know how to identify the outdated branches but we need a command to delete them which is the ",{"type":224,"tag":302,"props":391,"children":393},{"className":392},[],[394],{"type":229,"value":395},"git branch -D",{"type":229,"value":397}," command. Now we only need a script to associate the output and input of these two commands to automate the deletion.",{"type":224,"tag":225,"props":399,"children":400},{},[401,403,410,412,418,420,427],{"type":229,"value":402},"You can find on Stackoverflow some posts like ",{"type":224,"tag":248,"props":404,"children":407},{"href":405,"rel":406},"https://stackoverflow.com/questions/7726949/remove-tracking-branches-no-longer-on-remote",[252],[408],{"type":229,"value":409},"this one",{"type":229,"value":411}," that show different solutions using bash that work perfectly but I thought it would be interesting to try to script that using another shell. Indeed I recently started to use a shell called ",{"type":224,"tag":248,"props":413,"children":416},{"href":414,"rel":415},"https://github.com/nushell/nushell",[252],[417],{"type":229,"value":219},{"type":229,"value":419}," which is a pretty powerful yet simple cross-platform shell. It is still in preview at the time of writing but if you have not heard of it I suggest you read the ",{"type":224,"tag":248,"props":421,"children":424},{"href":422,"rel":423},"https://www.jonathanturner.org/2019/08/introducing-nushell.html",[252],[425],{"type":229,"value":426},"introduction post",{"type":229,"value":428}," of Jonathan Turner.",{"type":224,"tag":231,"props":430,"children":432},{"id":431},"lets-script-that-with-nushell",[433],{"type":229,"value":434},"Let's script that with nushell!",{"type":224,"tag":225,"props":436,"children":437},{},[438,440,445,447,453],{"type":229,"value":439},"Enough of talking, let's script.\nTo start with, we can use the nu lines command to create a table from the lines of the ",{"type":224,"tag":302,"props":441,"children":443},{"className":442},[],[444],{"type":229,"value":364},{"type":229,"value":446}," output (we added an extra ",{"type":224,"tag":302,"props":448,"children":450},{"className":449},[],[451],{"type":229,"value":452},"*/*",{"type":229,"value":454}," argument as we are only interested in posts branches).",{"type":224,"tag":225,"props":456,"children":457},{},[458],{"type":224,"tag":345,"props":459,"children":463},{"alt":460,"className":461,"src":462,"width":383},"List git branches in table in the terminal.",[349,350],"/posts/images/cleaningbranches_shell_3.png",[],{"type":224,"tag":225,"props":465,"children":466},{},[467,469,475,477,483],{"type":229,"value":468},"Then we can split the different lines into columns that we can name with the ",{"type":224,"tag":302,"props":470,"children":472},{"className":471},[],[473],{"type":229,"value":474},"split column",{"type":229,"value":476}," command. We use spaces to correctly split a line and the option ",{"type":224,"tag":302,"props":478,"children":480},{"className":479},[],[481],{"type":229,"value":482},"--collapse-empty",{"type":229,"value":484}," to remove the empty columns.",{"type":224,"tag":225,"props":486,"children":487},{},[488],{"type":224,"tag":345,"props":489,"children":493},{"alt":490,"className":491,"src":492,"width":383},"List git branches in table with columns by property in the terminal.",[349,350],"/posts/images/cleaningbranches_shell_4.png",[],{"type":224,"tag":225,"props":495,"children":496},{},[497,499,504],{"type":229,"value":498},"We then just have to filter the table to get only the lines with the Status ",{"type":224,"tag":302,"props":500,"children":502},{"className":501},[],[503],{"type":229,"value":372},{"type":229,"value":505},".",{"type":224,"tag":225,"props":507,"children":508},{},[509],{"type":224,"tag":345,"props":510,"children":514},{"alt":511,"className":512,"src":513,"width":383},"Filter on git branches gone in the terminal.",[349,350],"/posts/images/cleaningbranches_shell_5.png",[],{"type":224,"tag":225,"props":516,"children":517},{},[518],{"type":229,"value":519},"And the final script:",{"type":224,"tag":521,"props":522,"children":526},"pre",{"className":523,"code":524,"language":525,"meta":207,"style":207},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","git branch -vl '*/*' | lines | split column \" \" BranchName Hash Status --collapse-empty | where Status == '[gone]' | each { |it| git branch -D $it.BranchName }\n","bash",[527],{"type":224,"tag":302,"props":528,"children":529},{"__ignoreMap":207},[530],{"type":224,"tag":531,"props":532,"children":535},"span",{"class":533,"line":534},"line",1,[536,541,547,552,558,562,567,572,577,581,586,591,596,600,605,610,615,620,624,629,633,638,642,646,650,654,659,664,668,673,678,683,687,692,698,703],{"type":224,"tag":531,"props":537,"children":539},{"style":538},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[540],{"type":229,"value":217},{"type":224,"tag":531,"props":542,"children":544},{"style":543},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[545],{"type":229,"value":546}," branch",{"type":224,"tag":531,"props":548,"children":549},{"style":543},[550],{"type":229,"value":551}," -vl",{"type":224,"tag":531,"props":553,"children":555},{"style":554},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[556],{"type":229,"value":557}," '",{"type":224,"tag":531,"props":559,"children":560},{"style":543},[561],{"type":229,"value":452},{"type":224,"tag":531,"props":563,"children":564},{"style":554},[565],{"type":229,"value":566},"'",{"type":224,"tag":531,"props":568,"children":569},{"style":554},[570],{"type":229,"value":571}," |",{"type":224,"tag":531,"props":573,"children":574},{"style":538},[575],{"type":229,"value":576}," lines",{"type":224,"tag":531,"props":578,"children":579},{"style":554},[580],{"type":229,"value":571},{"type":224,"tag":531,"props":582,"children":583},{"style":538},[584],{"type":229,"value":585}," split",{"type":224,"tag":531,"props":587,"children":588},{"style":543},[589],{"type":229,"value":590}," column",{"type":224,"tag":531,"props":592,"children":593},{"style":554},[594],{"type":229,"value":595}," \"",{"type":224,"tag":531,"props":597,"children":598},{"style":554},[599],{"type":229,"value":595},{"type":224,"tag":531,"props":601,"children":602},{"style":543},[603],{"type":229,"value":604}," BranchName",{"type":224,"tag":531,"props":606,"children":607},{"style":543},[608],{"type":229,"value":609}," Hash",{"type":224,"tag":531,"props":611,"children":612},{"style":543},[613],{"type":229,"value":614}," Status",{"type":224,"tag":531,"props":616,"children":617},{"style":543},[618],{"type":229,"value":619}," --collapse-empty",{"type":224,"tag":531,"props":621,"children":622},{"style":554},[623],{"type":229,"value":571},{"type":224,"tag":531,"props":625,"children":626},{"style":538},[627],{"type":229,"value":628}," where",{"type":224,"tag":531,"props":630,"children":631},{"style":543},[632],{"type":229,"value":614},{"type":224,"tag":531,"props":634,"children":635},{"style":543},[636],{"type":229,"value":637}," ==",{"type":224,"tag":531,"props":639,"children":640},{"style":554},[641],{"type":229,"value":557},{"type":224,"tag":531,"props":643,"children":644},{"style":543},[645],{"type":229,"value":372},{"type":224,"tag":531,"props":647,"children":648},{"style":554},[649],{"type":229,"value":566},{"type":224,"tag":531,"props":651,"children":652},{"style":554},[653],{"type":229,"value":571},{"type":224,"tag":531,"props":655,"children":656},{"style":538},[657],{"type":229,"value":658}," each",{"type":224,"tag":531,"props":660,"children":661},{"style":543},[662],{"type":229,"value":663}," {",{"type":224,"tag":531,"props":665,"children":666},{"style":554},[667],{"type":229,"value":571},{"type":224,"tag":531,"props":669,"children":670},{"style":538},[671],{"type":229,"value":672},"it",{"type":224,"tag":531,"props":674,"children":675},{"style":554},[676],{"type":229,"value":677},"|",{"type":224,"tag":531,"props":679,"children":680},{"style":538},[681],{"type":229,"value":682}," git",{"type":224,"tag":531,"props":684,"children":685},{"style":543},[686],{"type":229,"value":546},{"type":224,"tag":531,"props":688,"children":689},{"style":543},[690],{"type":229,"value":691}," -D",{"type":224,"tag":531,"props":693,"children":695},{"style":694},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[696],{"type":229,"value":697}," $it",{"type":224,"tag":531,"props":699,"children":700},{"style":543},[701],{"type":229,"value":702},".BranchName",{"type":224,"tag":531,"props":704,"children":705},{"style":543},[706],{"type":229,"value":707}," }\n",{"type":224,"tag":231,"props":709,"children":711},{"id":710},"make-it-a-git-alias",[712],{"type":229,"value":713},"Make it a git alias.",{"type":224,"tag":225,"props":715,"children":716},{},[717,719,725,727,733],{"type":229,"value":718},"We can integrate this script into our git commands by creating a git alias. Let's say I want to create the alias ",{"type":224,"tag":302,"props":720,"children":722},{"className":721},[],[723],{"type":229,"value":724},"bcl",{"type":229,"value":726}," for branch clean up, we only need to add the following to our ",{"type":224,"tag":302,"props":728,"children":730},{"className":729},[],[731],{"type":229,"value":732},".gitconfig",{"type":229,"value":734},":",{"type":224,"tag":521,"props":736,"children":740},{"className":737,"code":738,"language":739,"meta":207,"style":207},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","[alias]\n    bcl = !nu \\\"D:\\\\gitalias_bcl.nu\\\"\n","yaml",[741],{"type":224,"tag":302,"props":742,"children":743},{"__ignoreMap":207},[744,762],{"type":224,"tag":531,"props":745,"children":746},{"class":533,"line":534},[747,752,757],{"type":224,"tag":531,"props":748,"children":749},{"style":554},[750],{"type":229,"value":751},"[",{"type":224,"tag":531,"props":753,"children":754},{"style":543},[755],{"type":229,"value":756},"alias",{"type":224,"tag":531,"props":758,"children":759},{"style":554},[760],{"type":229,"value":761},"]\n",{"type":224,"tag":531,"props":763,"children":765},{"class":533,"line":764},2,[766],{"type":224,"tag":531,"props":767,"children":768},{"style":543},[769],{"type":229,"value":770},"    bcl = !nu \\\"D:\\\\gitalias_bcl.nu\\\"\n",{"type":224,"tag":225,"props":772,"children":773},{},[774,776,782,784,790],{"type":229,"value":775},"where ",{"type":224,"tag":302,"props":777,"children":779},{"className":778},[],[780],{"type":229,"value":781},"gitalias_bcl.nu",{"type":229,"value":783}," is the nu script file we created earlier (it's located here in the ",{"type":224,"tag":302,"props":785,"children":787},{"className":786},[],[788],{"type":229,"value":789},"D://",{"type":229,"value":791}," drive but can be created anywhere).",{"type":224,"tag":225,"props":793,"children":794},{},[795,797,803],{"type":229,"value":796},"Now we can simply do a ",{"type":224,"tag":302,"props":798,"children":800},{"className":799},[],[801],{"type":229,"value":802},"git bcl",{"type":229,"value":804}," to clean our outdated local git branches.",{"type":224,"tag":225,"props":806,"children":807},{},[808],{"type":224,"tag":345,"props":809,"children":813},{"alt":810,"className":811,"src":812,"width":352},"List oudated git branches  in the terminal.",[349,350],"/posts/images/cleaningbranches_shell_6.png",[],{"type":224,"tag":225,"props":815,"children":816},{},[817],{"type":229,"value":818},"That's it, nothing revolutionary but that was the opportunity to automate the boring task of deleting outdated local branches while playing with nushell.",{"type":224,"tag":820,"props":821,"children":822},"style",{},[823],{"type":229,"value":824},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":207,"searchDepth":764,"depth":764,"links":826},[827,828,829,830],{"id":233,"depth":764,"text":236},{"id":312,"depth":764,"text":315},{"id":431,"depth":764,"text":434},{"id":710,"depth":764,"text":713},"markdown","content:1.posts:6.cleaning-git-branches.md","content","1.posts/6.cleaning-git-branches.md","md",[837,851],{"_path":28,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":27,"description":838,"lead":839,"date":840,"image":841,"badge":843,"tags":845,"_type":831,"_id":849,"_source":833,"_file":850,"_extension":835},"If you have no interest in reading the blog post and just want the final script, you can find it on this GitHub repository.","Creating a PowerShell script to configure SSO for the tab of a Teams application.","2020-06-15T00:00:00.000Z",{"src":842},"/images/shell_1.jpg",{"label":844},"DevOps",[846,847,848],"Microsoft Teams","PowerShell","Azure Active Directory","content:1.posts:7.teams-sso-powershell.md","1.posts/7.teams-sso-powershell.md",{"_path":22,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":21,"description":852,"lead":853,"date":854,"image":855,"badge":857,"tags":859,"_type":831,"_id":864,"_source":833,"_file":865,"_extension":835},"In our daily job, we often have to query secure REST APIs that require our HTTP requests to have a valid access token in their Authorization header.\nOf course, many APIs come with an SDK that makes the job easier for us as it directly takes care of retrieving a token and sending the authenticated HTTP requests.\nHowever, it is not always the case and knowing how to implement that using HttpClient, IMemoryCache, and DelegatingHandler can become pretty useful.","Using a DelegatingHandler","2020-01-29T00:00:00.000Z",{"src":856},"/images/keyboard_1.jpg",{"label":858},"Development",[860,861,862,863],"HTTP","rest","ASP.NET Core",".NET","content:1.posts:5.delegating-handler.md","1.posts/5.delegating-handler.md",1716749602476]