В настоящее время я использую 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 ..
Ты можешь :
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)