Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add last checkouts to tabcompletion #641

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/GitTabExpansion.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ function script:gitCommands($filter, $includeAliases) {
$cmdList | Sort-Object
}

function script:lastCheckouts($filter){
git reflog |
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two suggestions here:

  1. Specify an explicit --format=%gs (I think?) to get only the log output you need. There might be other flags you can also specify to optimize the operation (e.g. --no-decorate).
  2. reflog can get quite long under active development, so I would add a --max-count=<number> to avoid scanning thousands of references.

Copy link
Author

@mpawelski mpawelski Nov 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I came up with two options and I'm not sure which will be better 🤔

  1. git log --walk-reflogs --max-count=100 --format=%gs
    get more number of reflogs and then search for "'checkout: moving from (.) to (.)'" pattern from result.
  2. git log --walk-reflogs --max-count=10 --grep-reflog='checkout: moving from ' --fixed-strings --format=%gs
    get less number of reflogs but already filtered to one with data that we need (containing "checkout: moving from" in reflog subject).

For me option 2) seems more tempting because you get less data from git command. However the performance can depend on how big is you reflog and how many entries it has that are not what we are looking for (we want only reflogs with "checkout: moving from" subject). In other words you don't know how many reflogs git will traverse to get you list of 10 reflogs you want.

I think 2) is fine. How many crazy operations (like rebases of huge number of commits) you would have to do between switching branch 10 times to have huge reflog that can affect performance?

What do you think? Which option would you like to have?

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*" } |
Expand Down Expand Up @@ -387,6 +394,7 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) {
# Handles git checkout <ref>
"^(?:checkout).* (?<ref>\S*)$" {
& {
lastCheckouts $matches['ref']
gitBranches $matches['ref'] $true
gitRemoteUniqueBranches $matches['ref']
gitTags $matches['ref']
Expand Down
13 changes: 12 additions & 1 deletion test/TabExpansion.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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' {
Expand Down