我不認爲這是可能的,直接的(除非你事先知道確切的名單包含/排除,這否定了走在DAG的目的)
其實,OP Ken Hirakawa設法得到預期的線性史:
git log --pretty=format:"%h%n" --ancestry-path --reverse $prev_commit..$end_commit
而對於每次提交,並確保它是以前的直接子提交。
這裏是script writtten by Ken Hirakawa。
這裏是我的腳本來創建git的日誌手冊頁的History Simplification節中提到的DAG,爲--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>
從那裏,我不能排除的父母一方犯一
祖先路徑不會返回:
$ 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
祖先的人。
這對於查看從D
以來導致M
的歷史記錄發生了什麼很有用,意思是「M
在D
中不存在什麼」。
在這個例子中的結果將是所有的提交,當然除了A
和B
(和D
本身)。
當我們想找出M
什麼承諾被污染與D
介紹了錯誤和需要修復,但是,我們可能希望只查看實際上的D
後裔的D..M
子集,即排除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"
我不認爲他會喜歡的答案,但有一個需要了解的基本點:線性日誌並沒有真正使用git的工作,因爲它不是一個線性發展。對於想要知道進入分支的所有更改的人員來說,這是不幸的,例如,當您嘗試生成ChangeLog文件時。從git生成ChangeLog文件並進行大量合併實際上效果不佳,因爲ChangeLog文件是線性歷史記錄,而且開發不是。 –
@Wes:是的,Git是一個* content *管理器,如果內容(來自兩次提交之間可訪問的提交)是合併的結果,如果日誌返回DAG,可以忽略部分if對所述內容作出貢獻的歷史。 – VonC
我完全同意你們兩個,但我想沒有一個單一的線路,這是不值得驚訝的。我將接受VonC的答案,因爲它回答了我的問題,但我編輯了問題以包含我提出的解決方案。請看看 –