Tôi chỉ muốn lưu ý một cách tiếp cận khả thi khác - và đó là bằng cách sử dụng git
ghi chú git (1) , tồn tại kể từ phiên bản 1.6.6 ( Lưu ý đến Tự - Git ) (Tôi đang sử dụng git
phiên bản 1.7.9.5).
Về cơ bản, tôi thường git svn
sao chép một kho lưu trữ SVN với lịch sử tuyến tính (không có bố cục tiêu chuẩn, không có chi nhánh, không có thẻ) và tôi muốn so sánh các số sửa đổi trong git
kho lưu trữ nhân bản . Bản sao git này không có thẻ theo mặc định, vì vậy tôi không thể sử dụng git describe
. Chiến lược ở đây có thể sẽ chỉ hoạt động đối với lịch sử tuyến tính - không chắc nó sẽ diễn ra như thế nào với sự hợp nhất, v.v.; nhưng đây là chiến lược cơ bản:
- Yêu cầu
git rev-list
danh sách tất cả lịch sử cam kết
- Do
rev-list
theo mặc định theo "thứ tự thời gian đảo ngược", chúng tôi sẽ sử dụng công --reverse
tắc của nó để nhận danh sách các cam kết được sắp xếp theo thứ tự cũ nhất trước
- Sử dụng
bash
vỏ để
- tăng một biến truy cập trên mỗi cam kết như một bộ đếm sửa đổi,
- tạo và thêm một ghi chú git "tạm thời" cho mỗi lần xác nhận
- Sau đó, duyệt nhật ký bằng cách sử dụng
git log
với --notes
, cũng sẽ kết xuất ghi chú của cam kết, trong trường hợp này sẽ là "số sửa đổi"
- Khi hoàn tất, hãy xóa các ghi chú tạm thời ( NB: Tôi không chắc những ghi chú này có được cam kết hay không; chúng không thực sự hiển thị trong
git status
)
Trước tiên, hãy lưu ý rằng git
có một vị trí ghi chú mặc định - nhưng bạn cũng có thể chỉ định ref
(erence) cho ghi chú - sẽ lưu trữ chúng trong một thư mục khác bên dưới .git
; ví dụ, trong khi trong git
thư mục repo, bạn có thể gọi git notes get-ref
để xem thư mục nào sẽ là:
$ git notes get-ref
refs/notes/commits
$ git notes --ref=whatever get-ref
refs/notes/whatever
Điều cần lưu ý là nếu bạn notes add
với a --ref
, sau đó bạn cũng phải sử dụng lại tham chiếu đó - nếu không bạn có thể gặp lỗi như " Không tìm thấy ghi chú nào cho đối tượng XXX ... ".
Trong ví dụ này, tôi đã chọn gọi các ref
ghi chú là "linrev" (để sửa đổi tuyến tính) - điều này cũng có nghĩa là không có khả năng thủ tục sẽ can thiệp vào các ghi chú đã có. Tôi cũng đang sử dụng công --git-dir
tắc, vì là một người git
mới, tôi đã gặp một số vấn đề trong việc hiểu nó - vì vậy tôi muốn "nhớ lại sau" :)
; và tôi cũng sử dụng --no-pager
để ngăn chặn sinh sản less
khi sử dụng git log
.
Vì vậy, giả sử bạn đang ở trong một thư mục, với thư mục con myrepo_git
là git
kho lưu trữ; người ta có thể làm:
### 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.
Vì vậy, ít nhất trong trường hợp cụ thể của tôi về lịch sử tuyến tính hoàn toàn không có nhánh, các số sửa đổi dường như khớp với cách tiếp cận này - và ngoài ra, dường như cách tiếp cận này sẽ cho phép sử dụng git log
với phạm vi sửa đổi, trong khi vẫn nhận được số sửa đổi phù hợp - YMMV với một bối cảnh khác, mặc dù ...
Hy vọng điều này sẽ giúp ai đó,
Chúc mừng!
EDIT: Ok, ở đây dễ dàng hơn một chút, với các git
bí danh cho các vòng lặp ở trên, được gọi setlinrev
và unsetlinrev
; khi trong thư mục kho git của bạn, hãy làm ( Lưu ý bash
thoát khó chịu , xem thêm # 16136745 - Thêm bí danh Git có chứa dấu chấm phẩy ):
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
... vì vậy bạn chỉ có thể gọi git setlinrev
trước khi thử ghi nhật ký liên quan đến ghi chú sửa đổi tuyến tính; và git unsetlinrev
để xóa những ghi chú khi bạn hoàn thành; một ví dụ từ bên trong thư mục 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 <<
Thời gian cần thiết để hoàn thành các bí danh này, sẽ phụ thuộc vào kích thước của lịch sử kho lưu trữ.