![](/img/trans.png)
[英]Git log history simplification, elaborations example in git log's manual
[英]git log history simplification
假設我有以下歷史
D---E-------F
/ \ \
B---C---G---H---I---J
/ \
A-------K---------------L--M
git log --ancestry-path D..M 會給我
E-------F
\ \
G---H---I---J
\
L--M
但是,我只想要以下內容
E
\
G---H---I---J
\
L--M
或者
E-------F
\
I---J
\
L--M
本質上,我只想遍歷一條路徑,而不是兩條。
這可能嗎? 如果是這樣,命令是什么?
編輯:
我試過使用--first-parent,但這不完全是。 git 日志 --first-parent G..M 給我
F
\
H---I---J
\
L--M
它包括 F,因為 F 是 I 的第一個父母。相反,我想
H---I---J
\
L--M
任何幫助,將不勝感激
解決方案(對我有用):
正如@VonC 所說,沒有一個單線可以做到這一點。 所以我最終使用了 bash 腳本。
例如,git log --first-commit G..M 是
H - F - I - J - L - M
然而,F 的父母是 E,而不是 H。所以我們省略 F,給我
H - I - J - L - M
耶!
我不認為這是直接可能的(除非您事先知道要包含/排除的確切列表,這否定了走 DAG 的目的)
實際上, OP Ken Hirakawa通過以下方式獲得了預期的線性歷史:
git log --pretty=format:"%h%n" --ancestry-path --reverse $prev_commit..$end_commit
對於每個提交,確保它是前一個提交的直接子級。
這是平川健寫的劇本。
這是我的腳本,用於創建 git 日志手冊頁的歷史簡化部分中提到的 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>
從那里,我不能排除提交 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
祖先的提交。
這有助於了解自D
以來導致M
的歷史發生了什么,從某種意義上說,“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"
我不得不承認我不理解您的解決方案-它不適用於我的示例-但是如果我正確理解了您的用例(給定一對提交,您需要它們之間的任意線性路徑,沒有拆分) ,我有同樣的問題,以下解決方案似乎有效:
生成的腳本如下所示:
#!/bin/bash
output_set=""; child_to_match=""; # init
while read -r; do
if { [ -n "$REPLY" ]; } && { [[ "${REPLY:41}" =~ "$child_to_match" ]] || [ -z "$child_to_match" ]; }; then
child_to_match=${REPLY:0:40}
output_set="$output_set $child_to_match"
fi
done <<< "$(git rev-list --ancestry-path --children $1)"
if [[ -n $output_set ]]; then
git show -s $output_set "${@:2}"
fi
It can be called like single-ancestry-path.sh RANGE_EXPRESSION DECORATION_ARGS
, supporting generally the same decoration arguments as git log
(it is in fact git show
, being called once per commit), so taking the famous lg2
example from https:// stackoverflow.com/a/9074343/74296 ,調用可能如下所示:例如:
single-ancestry-path.sh master..MyBranch --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
已經 9 年了,所以我希望有一個更簡單的答案,但我找不到。
我也不喜歡合並帶來的問題,並且已經放棄了在我的主流歷史中出現的問題。 每當有一個大的合並到一個主分支上時,我都會用相同的內容重新提交它,但作為一個單一的提交。
D---E--------F Co-Developer / B---C---G'---H---I'--J Team Leader / A-------K----------------L'--M Main Stream
在這里,G'、I' 和 L' 將是我重新提交合並結果的點。 分支描述只是描述了我可以可視化發生的問題樹的場景。 因此,G 和 G'(類似於 I 和 I')的內容將是相同的,團隊負責人已合並到開發人員的最新工作中。 和 L' 一樣,L 的特點融入了主流。
I totally understand that avoiding a problem is not the same as solving it, and sympathize with those facing the problem now.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.