Создание 'git log' игнорирует изменения для определенных путей
Как я могу сделать git log
показывать только коммиты, которые меняли файлы, отличные от тех, которые я указываю?
С git log
, я могу отфильтровать коммиты, которые я вижу, тем, кто касается определенного набора путей. Я хочу, чтобы инвертировать этот фильтр так, чтобы он записывал только те пути касания, кроме указанных.
Я могу получить то, что хочу,
git log --format="%n/%n%H" --name-only | ~/filter-log.pl | git log --stdin --no-walk
где filter-log.pl
:
#!/usr/bin/perl
use strict;
use warnings;
$/ = "\n/\n";
<>;
while (<>) {
my ($commit, @files) = split /\n/, $_;
if (grep { $_ && $_ !~ m[^(/$|.etckeeper$|lvm/(archive|backup)/)] } @files) {
print "$commit\n";
}
}
за исключением того, что я хочу что-то более элегантное, чем это.
Обратите внимание, что я не спрашиваю, как сделать git игнорировать файлы. Эти файлы следует отслеживать и фиксировать. Это просто, что большую часть времени мне не интересно видеть их.
Связанный вопрос: Как инвертировать` git log --grep = <pattern> `или Как показать журналы git, которые не соответствуют шаблону Это тот же вопрос, кроме сообщений commit, а не путей.
Обсуждение форума по этому вопросу с 2008 года: Re: Исключение файлов из git -diff Это выглядело многообещающим, но поток, кажется, высушил вверх.
Ответы
Ответ 1
Теперь он реализован (git 1.9/2.0, первый квартал 2014 года) с введением в магии pathspec :(exclude)
и его краткой формой :!
в commit ef79b1f и commit 1649612, Nguyễn Thái Ngọc Duy (pclouds
), документацию можно найти здесь.
Теперь вы можете регистрировать все, кроме содержимого подпапок:
git log -- . ":(exclude)sub"
git log -- . ":!sub"
Или вы можете исключить определенные элементы в этой подпапке
-
конкретный файл:
git log -- . ":(exclude)sub/sub/file"
git log -- . ":!sub/sub/file"
-
любой данный файл в sub
:
git log -- . ":(exclude)sub/*file"
git log -- . ":!sub/*file"
git log -- . ":(exclude,glob)sub/*/file"
Вы можете сделать это исключение без учета регистра!
git log -- . ":(exclude,icase)SUB"
Как отметил Кенни Эвитт
Если вы запускаете Git в оболочке Bash, используйте ':!sub'
или ":\!sub"
чтобы избежать ошибок bash:... event not found
Примечание: Git 2.13 (Q2 2017) добавит синоним ^
к !
Смотрите коммит 859b7f1, коммит 42ebeb9 (08 февраля 2017 г.) Линуса Торвальдса (torvalds
).
(Объединено с Junio C Hamano - gitster
- в коммите 015fba3, 27 февраля 2017 г.)
магия пути: добавьте ' ^
' в качестве псевдонима для ' !
'
Выбор из !
"поскольку отрицательный путь указывает, что он не только не соответствует тому, что мы делаем для ревизий, но также является ужасным символом для расширения оболочки, поскольку требует цитирования.
Поэтому добавьте ' ^
' в качестве альтернативного псевдонима для исключающей записи pathspec.
Ответ 2
tl; dr: shopt -s extglob && git log !(unwanted/glob|another/unwanted/glob)
Если вы используете Bash, вы можете использовать расширенный globbing , чтобы получить только нужные файлы:
$ cd -- "$(mktemp --directory)"
$ git init
Initialized empty Git repository in /tmp/tmp.cJm8k38G9y/.git/
$ mkdir aye bee
$ echo foo > aye/foo
$ git add aye/foo
$ git commit -m "First commit"
[master (root-commit) 46a028c] First commit
0 files changed
create mode 100644 aye/foo
$ echo foo > bee/foo
$ git add bee/foo
$ git commit -m "Second commit"
[master 30b3af2] Second commit
1 file changed, 1 insertion(+)
create mode 100644 bee/foo
$ shopt -s extglob
$ git log !(bee)
commit ec660acdb38ee288a9e771a2685fe3389bed01dd
Author: My Name <[email protected]>
Date: Wed Jun 5 10:58:45 2013 +0200
First commit
Вы можете комбинировать это с globstar
для рекурсивного действия.
Ответ 3
Вы можете временно игнорировать изменения в файле с помощью
git update-index --skip-worktree path/to/file
Вперед, все изменения этих файлов будут проигнорированы git status
, git commit -a
и т.д. Когда вы будете готовы зафиксировать эти файлы, просто отмените его:
git update-index --no-skip-worktree path/to/file
и зафиксировать как обычно.