Thursday 22 November 2018

Displaying branch history in Git

I desired to have an easy branch log today. The following alias commands makes this easier. These go under the [alias] section in the .gitconfig file you are using in your repository.

latest = "!f() { echo "Latest \"${1:-11}\" commits accross all branches:"; git log  --abbrev-commit --date=relative --branches --all --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset%n' -n ${1:-11};  } ; f"
logbranch = "!f() { echo "Latest \"${1:-11}\" commits in current branch against master:"; git log master..${1:git branch}  --abbrev-commit --date=relative  --pretty=format:'%C(yellow)%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(white blue bold)<%an>%Creset%n' -n ${1:-11};  } ; f"

git logbranch will display only the latest commit for the specified branch or defaulting to the current branch, defaulting to last 11 commits using a shell function. Note that we compare against the master branch. And we get the following sample output:

Sunday 4 November 2018

Closing branches in Git

Git unlike Mercurial has no builtin support for closing branches. This leads to a proliferation of branches and running git branch -a to view remote branches or git branch will show ever more branches. Actually, closing a branch in Git can be supported through the use of tags. We decide to keep the tag for future use, so that we can use it to check out a new branch from this tag. Another way would of course be to just delete a brach local and/or remote, but that is not the same as closing a branch. Closing a branch in Mercurial still makes it possible to reopen it again for later work. Anyways, in this article, I will show two aliases which can be used to close a branch, either both local and remote or just remote. Put the following into the [alias] section of your .gitConfig file:

closebranch = "!w() { echo Attempting to close local and remote branch: $1 Processing...; echo Checking the branch $1 out..; git checkout $1; echo Trying to create a new tag archive/$1; git tag archive/\"$1\"; git push origin archive/\"$1\"; echo Deleting the local branch $1; git branch -d $1;  echo Deleting the remote branch $1; git push origin --delete $1; echo Done. To restore the closed branch later, enter: git checkout -b MyNewBranch archive/\"$1\"; }; w"

closebranchpassive = "!w() { echo Attempting to close local and remote branch: $1 Processing...; echo Checking the branch $1 out..; git checkout $1; echo Trying to create a new tag archive/$1; git tag archive/\"$1\"; git push origin archive/$1; echo Deleting the local branch $1;   echo Deleting the remote branch $1;  echo Done. To restore the closed branch later, enter: git checkout -b MyNewBranch archive/\"$1\"; }; w"

closeremotebranch =  "!w() { echo Attempting to close remote branch: $1 Processing...; echo Checking the branch $1 out..; git checkout $1;  echo Trying to create a new tag archive/$1; git tag archive/\"$1\"; git push origin archive/\"$1\"; echo Deleting the remote branch $1; git push origin --delete $1; echo Done. To restore the closed branch later, enter: git checkout -b MyNewBranch archive/\"$1\"; }; w"

What we do here is the following:
  • Check out the branch to close
  • Tag this branch as archive/branchname
  • Important - push the tag the remote e.g. origin in the provided aliased commands above
  • (Delete the local branch)
  • Delete the remote branch
  • Display a friendly output message how to restore the branch later through a tag
What we use here is a shell function in each alias. This allows us to do multiple commands in Git through a simple aliased command. Say you want to close a local and remote branch called MyBranchToBeClosed. Just enter: git closebranch MyBranchToBeClosed If you just want to close the remote branch and keep the local one, enter: git closeremotebranch MyBranchToBeClosed To restore the branch MyBranchToBeClosed (which now is actually closed!) later, just enter: git checkout -b MyRestoredBranch archive/MyBranchToBeClosed This lets you keep old branch around as tags and not proliferate the branch listings. We however have moved the branch(es) over to tags prefixed with archive/ I wish Git was simpler to use sometimes so we did not have to use such hacks, closing branches should be easy.

Wednesday 17 October 2018

Working with Netsh http sslcert setup and SSL bindings through Powershell

I am working with a solution at work where I need to enable IIS Client certificates. I am not able to get past the "Provide client certificate" dialog, but it is possible to alter the setup of SSL cert bindings on your computer through the Netsh command. This command is not in Powershell, but at the command line. I decided to write some Powershell functions to be able to alter this setup atleast in an easier way. One annoyance with the netsh command is that you have to keep track of the Application Id and Certificate hash values. Here, we can easier keep track of this through Powershell code. The Powershell code to display and alter, modify, delete and and SSL cert bindings is as follows:

function Get-NetshSetup($sslBinding='0.0.0.0:443') {

$sslsetup = netsh http show ssl 0.0.0.0:443
#Get-Member -InputObject $sslsetup

$sslsetupKeys = @{}

foreach ($line in $sslsetup){
 if ($line -ne $null -and $line.Contains(': ')){
    
    $key = $line.Split(':')[0]
    $value = $line.Split(':')[1]
     if (!$sslsetupKeys.ContainsKey($key)){
       $sslsetupKeys.Add($key.Trim(), $value.Trim()) 
      }
    } 
}


return $sslsetup

}

function Display-NetshSetup($sslBinding='0.0.0.0:443'){
 
 Write-Host SSL-Setup is: 

 $sslsetup = Get-NetshSetup($sslBinding)

foreach ($key in $sslsetup){
 Write-Host $key $sslsetup[$key]
}
}

function Modify-NetshSetup($sslBinding='0.0.0.0:443', $certstorename='My',
  $verifyclientcertrevocation='disable', $verifyrevocationwithcachedcleintcertonly='disable',
  $clientCertNegotiation='enable', $dsmapperUsage='enable'){
  $sslsetup = Get-NetshSetup($sslBinding)
 
  echo Deleting sslcert netsh http binding for $sslBinding ...
  netsh http delete sslcert ipport=$sslBinding
  echo Adding sslcert netsh http binding for $sslBinding...
  netsh http add sslcert ipport=$sslBinding certhash=$sslsetup['Certificate Hash'] appid=$sslsetup['Application ID'] certstorename=$certstorename verifyclientcertrevocation=$verifyclientcertrevocation verifyrevocationwithcachedclientcertonly=$verifyrevocationwithcachedcleintcertonly clientcertnegotiation=$clientCertNegotiation dsmapperusage=$dsmapperUsage
  echo Done. Inspect output.  
  Display-NetshSetup $sslBinding
}



function Add-NetshSetup($sslBinding, $certstorename, $certhash, $appid, 
  $verifyclientcertrevocation='disable', $verifyrevocationwithcachedcleintcertonly='disable',
  $clientCertNegotiation='enable', $dsmapperUsage='enable'){

  echo Adding sslcert netsh http binding for $sslBinding...
  netsh http add sslcert ipport=$sslBinding certhash=$certhash appid=$appid  clientcertnegotiation=$clientCertNegotiation dsmapperusage=$dsmapperUsage certstorename=$certstorename verifyclientcertrevocation=$verifyclientcertrevocation verifyrevocationwithcachedclientcertonly=$verifyrevocationwithcachedcleintcertonly 
   
  echo Done. Inspect output.  
  Display-NetshSetup $sslBinding
}





#Get-NetshSetup('0.0.0.0:443'); 
Display-NetshSetup
#Modify-NetshSetup 
Add-NetshSetup '0.0.0.0:443' 'MY' 'c0fe06da89bcb8f22da8c8cbdc97be413b964619' '{4dc3e181-e14b-4a21-b022-59fc669b0914}'
Display-NetshSetup