Git log --grep: поиск в диапазоне от HEAD до последнего (произвольного) имени ветки

В настоящее время я использую Git как часть инструмента, в котором мне нужно отметить некоторые изменения репозитория Git. Поэтому я создаю несколько «маркерных коммитов». Теперь я хочу знать, как эффективно находить эти коммиты.

Все репозитории Git имеют определенную структуру. Хочу описать на конкретном примере:

Рассмотрим произвольный (большой) репозиторий с отсоединенным HEAD, который всегда имеет линейную цепочку до произвольного имени следующей ветки. git log --oneline в этом репозитории будет выглядеть так:

9b6eea6063ae (HEAD) foo
51206b9c09db bar
8ec634b9e864 baz
...
2fba8a89a6ee marker123
75a8e54af67e (some_branch) ipsum
...

Теперь я хочу найти, существует ли коммит с именем marker123 на пути к последней ветке.

С помощью git log --grep marker123 --format=oneline --max-count=1 | grep . я нашел команду, которая ищет это имя и не возвращает ошибку, когда фиксация существует, и ошибку, когда ее нет. Однако, если коммит marker123 не существует, он ищет всю историю. Могу ли я ограничить поиск git log диапазоном между HEAD и some_branch? Моя главная проблема в том, что я не знаю заранее имя some_branch. Я только знаю, что он находится где-то в линейной цепочке обратных коммитов и является именем ветки. В частности, я не знаю, как определить диапазон фиксации для git log.

Примечание: я знаю это поведение немного из git rebase -i без дополнительной спецификации целевого коммита. Затем он также выполняет перебазирование, начиная с последней (удаленной?) ветки.

Вот скрипт для настройки двух репозиториев и демонстрации проблемы:

#!/bin/sh

echo "Setup a repository, where the search works."
mkdir git-test; cd git-test
git init --initial-branch=random_name
git commit --allow-empty -m "marker123"
git tag "This-commit-never-ever-should-be-found"
git commit --allow-empty -m "ipsum"
git checkout --detach HEAD
git commit --allow-empty -m "marker123"
git commit --allow-empty -m "baz"
git commit --allow-empty -m "bar"
git commit --allow-empty -m "foo"

git log --oneline # situation of the example
echo -e "\nSearch for marker:"
git log --grep "marker123" --oneline -1 | grep .
echo "Errorcode $?"

cd ..

echo "Setup a repository, where the search does not work."
mkdir git-test2; cd git-test2
git init --initial-branch=random_name
git commit --allow-empty -m "marker123"
git tag "This-commit-never-ever-should-be-found"
git commit --allow-empty -m "ipsum"
git checkout --detach HEAD
# git commit --allow-empty -m "marker123" # this commit is missing here
git commit --allow-empty -m "baz"
git commit --allow-empty -m "bar"
git commit --allow-empty -m "foo"

git log --oneline # situation of the example
echo -e "\nSearch for marker:"
git log --grep "marker123" --oneline -1 | grep . # this should result in an error
echo "Errorcode $?"
git log --grep "marker123" --oneline -1 "random_name..HEAD" | grep . # this works here but only if random_name is known
echo "Errorcode $?"

cd ..

71
1

Ответ:

Решено

Ты можешь :

  • перечислите ветки, не содержащие HEAD:
git branch --no-contains HEAD
  • используйте этот список в команде git log HEAD --not [list of branches ...]:
git log --oneline HEAD --not $(git branch --no-contains HEAD)

Если приведенная выше команда дает вам ожидаемую историю, вы можете добавить любые параметры, которые считаете подходящими, в git log:

git log --grep marker123 -1 --oneline HEAD --not $(git branch --no-contains HEAD)