ฉันต้องการจะบันทึกแนวทางที่เป็นไปได้อีกวิธีหนึ่งและนั่นก็คือการใช้git
git-notes (1)ซึ่งมีอยู่ตั้งแต่ v 1.6.6 ( หมายเหตุถึง Self - Git ) (ฉันใช้git
รุ่น 1.7.9.5)
โดยทั่วไปฉันเคยgit svn
โคลนที่เก็บ SVN ที่มีประวัติเชิงเส้น (ไม่มีรูปแบบมาตรฐานไม่มีสาขาไม่มีแท็ก) และฉันต้องการเปรียบเทียบหมายเลขการแก้ไขในที่git
เก็บที่โคลน git describe
โคลนคอมไพล์นี้ไม่ได้มีแท็กไปโดยปริยายดังนั้นผมจึงไม่สามารถใช้ กลยุทธ์ที่นี่น่าจะใช้ได้เฉพาะกับประวัติเชิงเส้นเท่านั้น - ไม่แน่ใจว่ามันจะเกิดขึ้นได้อย่างไรกับการรวมกัน ฯลฯ แต่นี่คือกลยุทธ์พื้นฐาน:
- ขอ
git rev-list
รายชื่อประวัติการกระทำทั้งหมด
- เนื่องจาก
rev-list
เป็นค่าเริ่มต้นใน "ลำดับเหตุการณ์ย้อนกลับ" เราจะใช้--reverse
สวิตช์เพื่อรับรายการการกระทำที่เรียงลำดับตามเก่าที่สุดก่อน
- ใช้
bash
เปลือกเพื่อ
- เพิ่มตัวแปรตัวนับในแต่ละการกระทำเป็นการแก้ไขตัวนับ
- สร้างและเพิ่มบันทึกชั่วคราว git "ชั่วคราว" สำหรับแต่ละการกระทำ
- จากนั้นเรียกดูบันทึกโดยใช้
git log
ด้วย--notes
ซึ่งจะทิ้งบันทึกย่อของการกระทำซึ่งในกรณีนี้จะเป็น "หมายเลขการแก้ไข"
- เมื่อเสร็จแล้วให้ลบบันทึกชั่วคราว ( หมายเหตุ: ฉันไม่แน่ใจว่าบันทึกเหล่านี้มีความมุ่งมั่นหรือไม่; พวกเขาไม่ได้แสดงจริง ๆ
git status
)
ก่อนแจ้งให้ทราบว่าgit
มีการตั้งค่าเริ่มต้นของการบันทึก - แต่คุณยังสามารถระบุref
(erence) สำหรับบันทึก - ซึ่งจะเก็บไว้ในไดเรกทอรีที่แตกต่างกันภายใต้.git
; ตัวอย่างเช่นในขณะที่อยู่ในgit
โฟลเดอร์ repo คุณสามารถโทรgit notes get-ref
เพื่อดูไดเรกทอรีที่จะ:
$ git notes get-ref
refs/notes/commits
$ git notes --ref=whatever get-ref
refs/notes/whatever
สิ่งที่ควรสังเกตคือถ้าคุณnotes add
ใช้ a --ref
คุณต้องใช้การอ้างอิงนั้นอีกครั้งหลังจากนั้นมิฉะนั้นคุณอาจได้รับข้อผิดพลาดเช่น " ไม่พบบันทึกย่อสำหรับวัตถุ XXX ... "
สำหรับตัวอย่างนี้ฉันได้เลือกที่จะเรียกref
บันทึกย่อของ "linrev" (สำหรับการแก้ไขเชิงเส้น) - นี่ก็หมายความว่ามันไม่น่าเป็นไปได้ที่กระบวนการจะแทรกแซงกับบันทึกที่มีอยู่แล้ว ฉันยังใช้--git-dir
สวิตช์เนื่องจากเป็นgit
มือใหม่ฉันมีปัญหาในการทำความเข้าใจ - ดังนั้นฉันต้องการที่จะ "จำไว้เพื่อใช้ในภายหลัง" :)
; และฉันยังใช้--no-pager
ในการวางไข่ของปราบเมื่อใช้less
git log
ดังนั้นสมมติว่าคุณอยู่ในไดเรกทอรีพร้อมโฟลเดอร์ย่อย myrepo_git
ซึ่งเป็นที่git
เก็บ เราสามารถทำได้:
### check for already existing notes:
$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
### iterate through rev-list three, oldest first,
### create a cmdline adding a revision count as note to each revision
$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
TCMD="$TCMD add $ih -m \"(r$((++ix)))\""; \
echo "$TCMD"; \
eval "$TCMD"; \
done
# git --git-dir=./myrepo_git/.git notes --ref linrev add 6886bbb7be18e63fc4be68ba41917b48f02e09d7 -m "(r1)"
# git --git-dir=./myrepo_git/.git notes --ref linrev add f34910dbeeee33a40806d29dd956062d6ab3ad97 -m "(r2)"
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev add 04051f98ece25cff67e62d13c548dacbee6c1e33 -m "(r15)"
### check status - adding notes seem to not affect it:
$ cd myrepo_git/
$ git status
# # On branch master
# nothing to commit (working directory clean)
$ cd ../
### check notes again:
$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# (r15)
### note is saved - now let's issue a `git log` command, using a format string and notes:
$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad: >>%s<< %N" HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000: >>test message 15 << (r15)
# 77f3902: _user_: Sun Apr 21 18:29:00 2013 +0000: >>test message 14<< (r14)
# ...
# 6886bbb: _user_: Sun Apr 21 17:11:52 2013 +0000: >>initial test message 1<< (r1)
### test git log with range:
$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad: >>%s<< %N" HEAD^..HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000: >>test message 15 << (r15)
### erase notes - again must iterate through rev-list
$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
TCMD="$TCMD remove $ih"; \
echo "$TCMD"; \
eval "$TCMD"; \
done
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# Removing note for object 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# git --git-dir=./myrepo_git/.git notes --ref linrev remove f34910dbeeee33a40806d29dd956062d6ab3ad97
# Removing note for object f34910dbeeee33a40806d29dd956062d6ab3ad97
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 04051f98ece25cff67e62d13c548dacbee6c1e33
# Removing note for object 04051f98ece25cff67e62d13c548dacbee6c1e33
### check notes again:
$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
อย่างน้อยในกรณีเฉพาะของฉันเกี่ยวกับประวัติเชิงเส้นอย่างสมบูรณ์โดยไม่มีสาขาหมายเลขการแก้ไขดูเหมือนจะตรงกับวิธีการนี้ - และนอกจากนี้ดูเหมือนว่าวิธีนี้จะอนุญาตให้ใช้git log
กับช่วงการแก้ไขในขณะที่ยังได้รับหมายเลขการแก้ไขที่ถูกต้อง - YMMV ด้วยบริบทที่แตกต่างแม้ว่า ...
หวังว่านี่จะช่วยใครซักคน
ไชโย!
แก้ไข: ตกลงที่นี่มันง่ายขึ้นเล็กน้อยด้วยgit
นามแฝงสำหรับลูปข้างต้นเรียกว่าsetlinrev
และunsetlinrev
; เมื่ออยู่ในโฟลเดอร์ที่เก็บ git ของคุณให้ทำ ( สังเกตการbash
หลบหนีที่น่ารังเกียจดูที่# 16136745 - เพิ่มนามแฝง Git ที่มีเครื่องหมายอัฒภาค ):
cat >> .git/config <<"EOF"
[alias]
setlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
TCMD=\"git notes --ref linrev\"; \n\
TCMD=\"$TCMD add $ih -m \\\"(r\\$((++ix)))\\\"\"; \n\
#echo \"$TCMD\"; \n\
eval \"$TCMD\"; \n\
done; \n\
echo \"Linear revision notes are set.\" '"
unsetlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
TCMD=\"git notes --ref linrev\"; \n\
TCMD=\"$TCMD remove $ih\"; \n\
#echo \"$TCMD\"; \n\
eval \"$TCMD 2>/dev/null\"; \n\
done; \n\
echo \"Linear revision notes are unset.\" '"
EOF
... เพื่อให้คุณสามารถเรียกใช้git setlinrev
ก่อนที่จะพยายามบันทึกที่เกี่ยวข้องกับการแก้ไขเชิงเส้นบันทึก; และgit unsetlinrev
เพื่อลบบันทึกย่อเหล่านั้นเมื่อคุณทำเสร็จแล้ว; ตัวอย่างจากในไดเรกทอรี git repo:
$ git log --notes=linrev --format=format:"%h: %an: %ad: >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000: >>test message 15 <<
$ git setlinrev
Linear revision notes are set.
$ git log --notes=linrev --format=format:"%h: %an: %ad: >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000: >>test message 15 << (r15)
$ git unsetlinrev
Linear revision notes are unset.
$ git log --notes=linrev --format=format:"%h: %an: %ad: >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000: >>test message 15 <<
เวลาที่ใช้เชลล์เพื่อทำสมนามเหล่านี้ให้เสร็จสมบูรณ์ขึ้นอยู่กับขนาดของประวัติที่เก็บ