Я не думаю, что это возможно напрямую (если вы заранее не знаете точный список для включения / исключения, что сводит на нет цель обхода DAG)
На самом деле, ОП Кену Хиракаве удалось получить ожидаемую линейную историю по:
git log --pretty=format:"%h%n" --ancestry-path --reverse $prev_commit..$end_commit
И для каждого коммита убедитесь, что он является прямым потомком предыдущего коммита.
Вот сценарий , написанный Кеном Хиракавой .
Вот мой скрипт для создания группы доступности базы данных, упомянутой в разделе Упрощение истории на странице справки git log, для --ancestry-path
:
В конце вы найдете bash-скрипт, который я использовал для создания похожей истории (назовите его с именем корневого каталога и вашим именем пользователя).
Я определяю:
$ git config --global alias.lgg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
Я получаю:
$ git lgg
* d7c4459 - (HEAD, M, fromA) M <VonC>
* 82b011d - (L) Merge commit 'J' into fromA <VonC>
|\
| * 190265b - (J, master) J <VonC>
| * ef8e325 - (I) Merge commit 'F' <VonC>
| |\
| | * 4b6d976 - (F, fromB) F <VonC>
| * | 45a5d4d - (H) H <VonC>
| * | 834b239 - (G) Merge commit 'E' <VonC>
| |\ \
| | |/
| | * f8e9272 - (E) E <VonC>
| | * 96b5538 - (D) D <VonC>
| * | 49eff7f - (C) C <VonC>
| |/
| * 02c3ef4 - (B) B <VonC>
* | c0d9e1e - (K) K <VonC>
|/
* 6530d79 - (A) A <VonC>
Оттуда я не могу исключить одного из родителей коммита I.
Путь предков возвращает:
$ git lgg --ancestry-path D..M
* d7c4459 - (HEAD, M, fromA) M <VonC>
* 82b011d - (L) Merge commit 'J' into fromA <VonC>
* 190265b - (J, master) J <VonC>
* ef8e325 - (I) Merge commit 'F' <VonC>
|\
| * 4b6d976 - (F, fromB) F <VonC>
* | 45a5d4d - (H) H <VonC>
* | 834b239 - (G) Merge commit 'E' <VonC>
|/
* f8e9272 - (E) E <VonC>
, что соответствует справочной странице журнала:
Обычный D..M
вычисляет набор коммитов, которые являются предками M
, но исключает те, которые являются предками D
.
Это полезно, чтобы увидеть, что произошло с историей, приведшей к M
со времени D
, в том смысле, что «того, что есть у M
, не было в D
».
Результатом в этом примере будут все коммиты, кроме A
и B
(и, конечно, D
).
Когда мы хотим выяснить, какие коммиты в M
загрязнены ошибкой, введенной D
, и нуждаются в исправлении , тем не менее, мы можем захотеть просмотреть только подмножество D..M
, которое на самом деле являются потомками D
, т.е. исключая C
и K
.
Это именно то, что делает опция --ancestry-path
.
#!/bin/bash
function makeCommit() {
local letter=$1
if [[ `git tag -l $letter` == "" ]] ; then
echo $letter > $root/$letter
git add .
git commit -m "${letter}"
git tag -m "${letter}" $letter
else
echo "commit $letter already there"
fi
}
function makeMerge() {
local letter=$1
local from=$2
if [[ `git tag -l $letter` == "" ]] ; then
git merge $from
git tag -m "${letter}" $letter
else
echo "merge $letter already done"
fi
}
function makeBranch() {
local branch=$1
local from=$2
if [[ "$(git branch|grep $1)" == "" ]] ; then
git checkout -b $branch $from
else
echo "branch $branch already created"
git checkout $branch
fi
}
root=$1
user=$2
if [[ ! -e $root/.git ]] ; then
git init $root
fi
export GIT_WORK_TREE="./$root"
export GIT_DIR="./$root/.git"
git config --local user.name $2
makeCommit "A"
makeCommit "B"
makeCommit "C"
makeBranch "fromB" "B"
makeCommit "D"
makeCommit "E"
makeCommit "F"
git checkout master
makeMerge "G" "E"
makeCommit "H"
makeMerge "I" "F"
makeCommit "J"
makeBranch "fromA" "A"
makeCommit "K"
makeMerge "L" "J"
makeCommit "M"