Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Branch: master
Fetching contributors…

Cannot retrieve contributors at this time

228 lines (190 sloc) 7.969 kB
# Initial implementation by Jeremy Skinner
# http://www.jeremyskinner.co.uk/2010/03/07/using-git-with-windows-powershell/
$global:GitTabSettings = New-Object PSObject -Property @{
AllCommands = $false
}
$global:ops = @{
reflog = 'expire','delete','show'
remote = 'add','rename','rm','set-head','show','prune','update'
stash = 'list','show','drop','pop','apply','branch','save','clear','create'
svn = 'init', 'fetch', 'clone', 'rebase', 'dcommit', 'branch', 'tag', 'log', 'blame', 'find-rev', 'set-tree', 'create-ignore', 'show-ignore', 'mkdirs', 'commit-diff', 'info', 'proplist', 'propget', 'show-externals', 'gc', 'reset'
}
function script:gitCmdOperations($command, $filter) {
$ops.$command |
where { $_ -like "$filter*" }
}
$script:someCommands = @('add','am','annotate','archive','bisect','blame','branch','bundle','checkout','cherry','cherry-pick','citool','clean','clone','commit','config','describe','diff','difftool','fetch','format-patch','gc','grep','gui','help','init','instaweb','log','merge','mergetool','mv','notes','prune','pull','push','rebase','reflog','remote','rerere','reset','revert','rm','shortlog','show','stash','status','submodule','svn','tag','whatchanged')
function script:gitCommands($filter, $includeAliases) {
$cmdList = @()
if (-not $global:GitTabSettings.AllCommands) {
$cmdList += $someCommands -like "$filter*"
} else {
$cmdList += git help --all |
where { $_ -match '^ \S.*' } |
foreach { $_.Split(' ', [StringSplitOptions]::RemoveEmptyEntries) } |
where { $_ -like "$filter*" }
}
if ($includeAliases) {
$cmdList += gitAliases $filter
}
$cmdList | sort
}
function script:gitRemotes($filter) {
git remote |
where { $_ -like "$filter*" }
}
function script:gitBranches($filter, $includeHEAD = $false) {
if ($filter -match "^(?<from>\S*\.{2,3})(?<to>.*)") {
$prefix = $matches['from']
$filter = $matches['to']
}
$branches = @(git branch | foreach { if($_ -match "^\*?\s*(?<ref>.*)") { $matches['ref'] } }) +
@(git branch -r | foreach { if($_ -match "^ (?<ref>\S+)(?: -> .+)?") { $matches['ref'] } }) +
@(if ($includeHEAD) { 'HEAD','FETCH_HEAD','ORIG_HEAD','MERGE_HEAD' })
$branches |
where { $_ -ne '(no branch)' -and $_ -like "$filter*" } |
foreach { $prefix + $_ }
}
function script:gitStashes($filter) {
(git stash list) -replace ':.*','' |
where { $_ -like "$filter*" } |
foreach { "'$_'" }
}
function script:gitIndex($filter) {
if($GitStatus) {
$GitStatus.Index |
where { $_ -like "$filter*" } |
foreach { if($_ -like '* *') { "'$_'" } else { $_ } }
}
}
function script:gitFiles($filter) {
if($GitStatus) {
$GitStatus.Working |
where { $_ -like "$filter*" } |
foreach { if($_ -like '* *') { "'$_'" } else { $_ } }
}
}
function script:gitDeleted($filter) {
if($GitStatus) {
@($GitStatus.Working.Deleted) |
where { $_ -like "$filter*" } |
foreach { if($_ -like '* *') { "'$_'" } else { $_ } }
}
}
function script:gitAliases($filter) {
git config --get-regexp ^alias\. | foreach {
if($_ -match "^alias\.(?<alias>\S+) .*") {
$alias = $Matches['alias']
if($alias -like "$filter*") {
$alias
}
}
} | Sort
}
function script:expandGitAlias($cmd, $rest) {
if((git config --get-regexp "^alias\.$cmd`$") -match "^alias\.$cmd (?<cmd>[^!].*)`$") {
return "git $($Matches['cmd'])$rest"
} else {
return "git $cmd$rest"
}
}
function GitTabExpansion($lastBlock) {
if($lastBlock -match "^$(Get-AliasPattern git) (?<cmd>\S+)(?<args> .*)$") {
$lastBlock = expandGitAlias $Matches['cmd'] $Matches['args']
}
# Handles tgit <command> (tortoisegit)
if($lastBlock -match "^$(Get-AliasPattern tgit) (?<cmd>\S*)$") {
# Need return statement to prevent fall-through.
return $tortoiseGitCommands | where { $_ -like "$($matches['cmd'])*" }
}
switch -regex ($lastBlock -replace "^$(Get-AliasPattern git) ","") {
# Handles git reflog <op>
# Handles git remote <op>
# Handles git stash <op>
# Handles git svn <op>
"^(?<cmd>reflog|remote|stash|svn)\s+(?<op>\S*)$" {
gitCmdOperations $matches['cmd'] $matches['op']
}
# Handles git remote (rename|rm|set-head|set-branches|set-url|show|prune) <stash>
"^remote.* (?:rename|rm|set-head|set-branches|set-url|show|prune).* (?<remote>\S*)$" {
gitRemotes $matches['remote']
}
# Handles git stash (show|apply|drop|pop|branch) <stash>
"^stash (?:show|apply|drop|pop|branch).* (?<stash>\S*)$" {
gitStashes $matches['stash']
}
# Handles git branch -d|-D|-m|-M <branch name>
# Handles git branch <branch name> <start-point>
"^branch.* (?<branch>\S*)$" {
gitBranches $matches['branch']
}
# Handles git <cmd> (commands & aliases)
"^(?<cmd>\S*)$" {
gitCommands $matches['cmd'] $TRUE
}
# Handles git help <cmd> (commands only)
"^help (?<cmd>\S*)$" {
gitCommands $matches['cmd'] $FALSE
}
# Handles git push remote <branch>
# Handles git pull remote <branch>
"^(?:push|pull).* (?:\S+) (?<branch>\S*)$" {
gitBranches $matches['branch']
}
# Handles git pull <remote>
# Handles git push <remote>
# Handles git fetch <remote>
"^(?:push|pull|fetch).* (?<remote>\S*)$" {
gitRemotes $matches['remote']
}
# Handles git reset HEAD <path>
# Handles git reset HEAD -- <path>
"^reset.* HEAD(?:\s+--)? (?<path>\S*)$" {
gitIndex $matches['path']
}
# Handles git cherry-pick <commit>
# Handles git diff <commit>
# Handles git difftool <commit>
# Handles git log <commit>
# Handles git show <commit>
"^(?:cherry-pick|diff|difftool|log|show).* (?<commit>\S*)$" {
gitBranches $matches['commit'] $true
}
# Handles git reset <commit>
"^reset.* (?<commit>\S*)$" {
gitBranches $matches['commit'] $true
}
# Handles git add <path>
"^add.* (?<files>\S*)$" {
gitFiles $matches['files']
}
# Handles git checkout -- <path>
"^checkout.* -- (?<files>\S*)$" {
gitFiles $matches['files']
}
# Handles git rm <path>
"^rm.* (?<index>\S*)$" {
gitDeleted $matches['index']
}
# Handles git checkout <branch name>
# Handles git merge <branch name>
# handles git rebase <branch name>
# Handles git reflog show <branch name>
"^(?:checkout|merge|rebase|reflog\s+show).*\s(?<branch>\S*)$" {
gitBranches $matches['branch'] $true
}
}
}
if (Test-Path Function:\TabExpansion) {
Rename-Item Function:\TabExpansion TabExpansionBackup
}
function TabExpansion($line, $lastWord) {
$lastBlock = [regex]::Split($line, '[|;]')[-1].TrimStart()
switch -regex ($lastBlock) {
# Execute git tab completion for all git-related commands
"^$(Get-AliasPattern git) (.*)" { GitTabExpansion $lastBlock }
"^$(Get-AliasPattern tgit) (.*)" { GitTabExpansion $lastBlock }
# Fall back on existing tab expansion
default { if (Test-Path Function:\TabExpansionBackup) { TabExpansionBackup $line $lastWord } }
}
}
Jump to Line
Something went wrong with that request. Please try again.