С 2011 года, как комментирует OP, Git поддерживает полное завершение имени файла, начиная с ~ 1.8.2.
Но с Git 2.18 (Q2 2018) завершение оболочки (в contrib/
), которое дает список путей, было несколько оптимизировано.
См. commit 78a2d21 (4 апреля 2018 г.) от Clemens Buchacher (drizzd
).
(объединено Хунио C Хамано -- gitster
-- в commit 3a940e9 а>, 25 апреля 2018 г.)
completion
: улучшить ls-files
производительность фильтра
Из вывода ls-files
мы удаляем все, кроме самого левого компонента пути, а затем удаляем дубликаты. Мы делаем это в цикле while
, который является узким местом в производительности при большом количестве итераций (например, для 60000 файлов в linux.git
).
$ COMP_WORDS=(git status -- ar) COMP_CWORD=3; time _git
real 0m11.876s
user 0m4.685s
sys 0m6.808s
Замена цикла командой cut значительно повышает производительность:
$ COMP_WORDS=(git status -- ar) COMP_CWORD=3; time _git
real 0m1.372s
user 0m0.263s
sys 0m0.167s
Измерения проводились с помощью Msys2 bash, который используется Git для Windows.
При фильтрации вывода ls-files
мы стараемся не касаться абсолютных путей. Это избыточно, потому что ls-files
никогда не будет выводить абсолютные пути. Удалите ненужные операции.
Изначально о проблеме сообщалось Git для Windows, проблема 1533.
Код обхода каталогов имел избыточные рекурсивные вызовы, что делало его характеристики производительности экспоненциальными по отношению к глубине дерева, что было исправлено в Git 2.27 (второй квартал 2020 г.).
См. commit c0af173, зафиксировать 95c11ec, , коммит 1684644, зафиксировать 8d92fb2, зафиксировать 2df179d, зафиксировать 0126d14, зафиксировать cd129ee, зафиксировать 446f46d , коммит 7260c7b, commit ce5c61a (01 апреля 2020 г.), автор Элайджа Ньюрен (newren
).
См. коммит 0bbd0e8 (01 апр. 2020) Деррик Столи (derrickstolee
).
(объединено Хунио С Хамано -- gitster
-- в commit 6eacc39, 29 апреля 2020 г.)
completion
: исправить 'git add
' на путях в неотслеживаемом каталоге.
Подписано: Элайджа Ньюрен
Как сообщается в списке рассылки git, начиная с git-2.25,
git add untracked-dir/
была завершена вкладка
git add untracked-dir/./
Причиной этого было то, что с commit b9670c1f5e (dir
: исправить проверки в каталоге с общим префиксом , 19 декабря 2019 г., Git v2.25.0-rc0 -- слияние),
git ls-files -o --directory untracked-dir/
(или эквивалент git -C untracked-dir ls-files -o --directory
) начал сообщать
untracked-dir/
вместо того, чтобы перечислять пути под этим каталогом.
Возможно, также стоит отметить, что настоящая команда, о которой идет речь, была
git -C untracked-dir ls-files -o --directory '*'
что эквивалентно:
git ls-files -o --directory 'untracked-dir/*'
который ведет себя так же для целей этой проблемы ('*
' может соответствовать пустой строке), но становится актуальным для предлагаемого исправления.
Сначала, основываясь на отчете, я решил попытаться рассматривать это как регрессию и попытался найти способ восстановить старое поведение, не нарушая других вещей или, по крайней мере, нарушая как можно меньше.
Однако в В конце концов, я не мог придумать способ сделать это, который не просто вызвал бы гораздо больше проблем, чем решил.
Старое поведение было ошибкой:
- Хотя старый git избегал очистки чего-либо с помощью
git clean -f .git
, он стирал все в этом каталоге с помощью git clean -f .git/
.
Несмотря на разницу в используемой команде, это имеет значение, поскольку точно такое же изменение, которое исправило очистку, изменило поведение ls-файлов. .
- Старый git сообщал о разных результатах, основанных исключительно на наличии или отсутствии завершающей косой черты для
$SUBDIR
в команде git ls-files -o --directory $SUBDIR
.
- Старый git нарушал задокументированное поведение, заключающееся в отказе от рекурсии в каталогах, которые соответствовали спецификации пути, когда было указано
--directory
.
- И, в конце концов, commit b9670c1f5e (
dir
: исправление проверок каталога общих префиксов, 2019 г. -12-19, Git v2.25.0-rc0) не упустил из виду эту проблему; в нем прямо указано, что поведение команды было изменено, чтобы привести ее в соответствие с документацией.
(Кроме того, если это поможет, несмотря на то, что этот коммит был объединен в серии 2.25, об этой ошибке не сообщалось ни в цикле 2.25, ни даже в течение большей части цикла 2.26 — о ней сообщалось за день до выпуска 2.26.
Таким образом, влияние изменения, по крайней мере, несколько невелико.)
Вместо того, чтобы полагаться на ошибку ls-files
в сообщении о неправильном содержимом, измените вызов ls-файлов, используемых git-completion, чтобы он захватывал пути на одну глубину глубже.
Для этого замените «$DIR/*
» (соответствует $DIR/
плюс 0 или более символов) на «$DIR/?*
» (соответствует $DIR/
плюс 1 или более символов).
Обратите внимание, что символ '?
' не следует добавлять при попытке завершить имя файла (например, символ 'git ls-files -o --directory merge.c?*"' would not correctly return "[
merge.c](https://github.com/git/git/blob/c0af173a136785b3cfad4bd414b2fb10a130760a/merge.c)" when such a file exists), so we have to make sure to add the '
?`' только в тех случаях, когда указанный путь является каталогом.
Предупреждение: Git 2.29 (4 квартал 2020 г.) исправляет регрессию, появившуюся в цикле 2.27.
См. commit cada730 (20 июля 2020 г.) от Мартин Огрен (none
).
(объединено Хунио С. Хамано -- gitster
-- в commit 82fafc7 а>, 30 июля 2020 г.)
dir
: проверьте пути перед возвратом path_excluded
Подготовил: Андреас Шваб
Проверил: Элайджа Ньюрен
Подписал: Мартин Огрен
В 95c11ecc73 (исправить подверженный ошибкам API fill_directory()
; сделать так, чтобы он возвращал только совпадения, 2020- 01 апреля, Git v2.27.0-rc0 -- слияние, указанное в пакет № 5), мы научили fill_directory()
, а точнее treat_path()
, проверять любые пути, чтобы мы могли бы упростить абонентов.
Но при этом мы добавили слишком ранний возврат для исключенного случая. В итоге мы не проверяем пути, а это означает, что мы возвращаем path_excluded
вместо того, чтобы вернуть path_none
. В результате git status --ignored -- pathspec
(man) могут показывать пути, которые на самом деле не соответствуют pathspec
.
Переместите исключенную проверку вниз после того, как мы проверили все пути.
person
VonC
schedule
01.05.2018
git status
, а затем знаю, что набрать дляgit diff
. (Но чаще всего я используюgitk
для просмотра различий.) - person Paŭlo Ebermann   schedule 17.05.2011