From a46724de313d7178205014e66795f776eea42bbb Mon Sep 17 00:00:00 2001 From: Mariusz Pawelski Date: Sun, 4 Nov 2018 02:02:01 +0100 Subject: [PATCH 1/4] Add last checkouts for 'git checkout' TabCompletion. This adds functionality to suggest last used branches (and commits) when tab completing "git checkout" command. This is inspired by "@{-N}" syntax that you can use use now in git (for example "git checkout @{-1}" switch to last used branch. --- src/GitTabExpansion.ps1 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/GitTabExpansion.ps1 b/src/GitTabExpansion.ps1 index afa2bc028..6f476bd61 100644 --- a/src/GitTabExpansion.ps1 +++ b/src/GitTabExpansion.ps1 @@ -101,6 +101,13 @@ function script:gitCommands($filter, $includeAliases) { $cmdList | Sort-Object } +function script:lastCheckouts($filter){ + git reflog | + Where-Object { $_ -match ': checkout: moving from (.*) to (.*)' } | + ForEach-Object { $Matches[1] } | + Where-Object { $_ -like "$filter*" } +} + function script:gitRemotes($filter) { git remote | Where-Object { $_ -like "$filter*" } | @@ -387,6 +394,7 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) { # Handles git checkout "^(?:checkout).* (?\S*)$" { & { + lastCheckouts $matches['ref'] gitBranches $matches['ref'] $true gitRemoteUniqueBranches $matches['ref'] gitTags $matches['ref'] From 007f138664905bb62a1386759a8b03fdccf8cf27 Mon Sep 17 00:00:00 2001 From: Mariusz Pawelski Date: Sun, 4 Nov 2018 20:08:08 +0100 Subject: [PATCH 2/4] Write tests for last checkouts completion --- test/TabExpansion.Tests.ps1 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/test/TabExpansion.Tests.ps1 b/test/TabExpansion.Tests.ps1 index 99ce4656c..d718cd10b 100644 --- a/test/TabExpansion.Tests.ps1 +++ b/test/TabExpansion.Tests.ps1 @@ -187,7 +187,7 @@ Describe 'TabExpansion Tests' { Context 'Add/Reset/Checkout TabExpansion Tests' { BeforeEach { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssigments', '')] - $repoPath = NewGitTempRepo + $repoPath = NewGitTempRepo -MakeInitialCommit } AfterEach { RemoveGitTempRepo $repoPath @@ -203,6 +203,17 @@ Describe 'TabExpansion Tests' { $result = & $module GitTabExpansionInternal 'git add ' $gitStatus $result | Should BeExactly $fileName } + It 'Tab completes last checkouts first' { + &$gitbin checkout -q -b 'test-branch-b' 2>$null + &$gitbin checkout -q -b 'test-branch-c' 2>$null + &$gitbin checkout -q -b 'test-branch-a' 2>$null + &$gitbin checkout -q 'master' 2>$null + + $result = & $module GitTabExpansionInternal 'git checkout ' + $firstThreeResults = $result[0..2] + + $firstThreeResults | Should -BeExactly @('test-branch-a', 'test-branch-c', 'test-branch-b') + } } Context 'Alias TabExpansion Tests' { From a19eed9f90f02dc3cf8b9dbd6634ecffd37e9dae Mon Sep 17 00:00:00 2001 From: Mariusz Date: Fri, 23 Nov 2018 12:51:53 +0100 Subject: [PATCH 3/4] Add filter and limit for reflog command that gets last used branches. --- src/GitTabExpansion.ps1 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/GitTabExpansion.ps1 b/src/GitTabExpansion.ps1 index 6f476bd61..6f7e2cdc2 100644 --- a/src/GitTabExpansion.ps1 +++ b/src/GitTabExpansion.ps1 @@ -102,8 +102,10 @@ function script:gitCommands($filter, $includeAliases) { } function script:lastCheckouts($filter){ - git reflog | - Where-Object { $_ -match ': checkout: moving from (.*) to (.*)' } | + # for performance reasons we limit the number of returned entries from reflog to avoid scanning + # all reflog entries which can be huge in some cases. Number 10 is chose as "good enough" for most cases. + git log --walk-reflogs --max-count=10 --grep-reflog='checkout: moving from ' --fixed-strings --format=%gs | + Where-Object { $_ -match 'checkout: moving from (.*) to (.*)' } | ForEach-Object { $Matches[1] } | Where-Object { $_ -like "$filter*" } } From 66b06fd870e33cb3bdb337779eb3a0b96a5e4200 Mon Sep 17 00:00:00 2001 From: Mariusz Date: Fri, 23 Nov 2018 14:01:02 +0100 Subject: [PATCH 4/4] Fix quoting that broke unit test. We got this message from git when we ran git log command: "fatal: ambiguous argument 'moving': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git [...] -- [...]'" This change in quoting fixes it. --- src/GitTabExpansion.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GitTabExpansion.ps1 b/src/GitTabExpansion.ps1 index 6f7e2cdc2..40cb9a441 100644 --- a/src/GitTabExpansion.ps1 +++ b/src/GitTabExpansion.ps1 @@ -104,7 +104,7 @@ function script:gitCommands($filter, $includeAliases) { function script:lastCheckouts($filter){ # for performance reasons we limit the number of returned entries from reflog to avoid scanning # all reflog entries which can be huge in some cases. Number 10 is chose as "good enough" for most cases. - git log --walk-reflogs --max-count=10 --grep-reflog='checkout: moving from ' --fixed-strings --format=%gs | + git log --walk-reflogs --max-count=10 '--grep-reflog="checkout: moving from "' --fixed-strings --format=%gs | Where-Object { $_ -match 'checkout: moving from (.*) to (.*)' } | ForEach-Object { $Matches[1] } | Where-Object { $_ -like "$filter*" }