2013-01-08 19 views
7

Một điều tôi bỏ lỡ khi sử dụng svn là đánh số đơn giản các số sửa đổi. Tôi có thể dễ dàng nhìn thấy nếu phiên bản được triển khai trong môi trường thử nghiệm là trước hoặc sau một cam kết nhất định.tìm hiểu xem một cam kết git đã được kiểm tra trước hoặc sau một cam kết khác cho các băm

Với git sử dụng băm cho các cam kết của nó, cách để biết liệu một cam kết đã được thực hiện trước hoặc sau một cam kết khác?

Trả lời

7

Mọi thứ, như bạn lưu ý, không đơn giản như vậy trong Git. Đặc biệt, định nghĩa "trước" và "sau" cần làm rõ hơn một chút.

Nếu bạn tin tưởng những người cam kết vào kho lưu trữ của bạn không gây rối với dấu thời gian, và bạn đã biết cả hai cam kết trên cùng một chi nhánh, bạn có thể so sánh dấu thời gian của các cam kết và chỉ xem cái nào trước đó. Sử dụng lệnh sau cho mỗi cam kết và so sánh kết quả.

git log -1 --format='%ci' <commit> 

Với Git, bạn không nhất thiết có thể tin tưởng dấu thời gian, tuy nhiên, không giống như Subversion không có kho lưu trữ trung tâm có công việc sản xuất chúng. Bạn cũng không thể chắc chắn rằng hai cam kết trên cùng một nhánh (mặc dù vấn đề đó cũng tồn tại với Subversion).

Để tránh những vấn đề đó, hãy nói về việc một cam kết có phải là tổ tiên của tổ chức khác hay không, thay vì cho dù nó là trước hay sau nó.Trong cam kết đồ thị sau, B và C là tổ tiên của A, trong khi B không phải là tổ tiên của C hay ngược lại:

B (master) 
| C (branch) 
|/ 
A (root) 

Để xác định xem cam A là tổ tiên của cam kết B, sử dụng lệnh sau đây (dựa trên an article at git ready):

git rev-list <commitA> | grep $(git rev-parse <commitB>) 

các danh sách phần đầu tiên tất cả các cam kết đó là tổ tiên của cam A; phần thứ hai nhận được băm đầy đủ của cam kết B, sau đó tìm kiếm danh sách tổ tiên cho cam kết đó. Nếu bạn thấy bất kỳ đầu ra nào, commit A là một tổ tiên của commit B. Hoán đổi các đối số để làm việc nếu commit A là một tổ tiên của commit B thay vào đó.

Biểu mẫu thứ hai này chậm hơn, nhưng cung cấp cho bạn sự chắc chắn tuyệt đối rằng một cam kết là tổ tiên của người khác.

+0

Vậy dấu thời gian đại diện cho khi tôi làm git log -1 --format = '% ci' ? Tôi chỉ cố hiểu một kịch bản khi tôi không thể tin vào dấu thời gian. – Glide

+0

@Glide: Dấu thời gian đó biểu thị thời gian thực hiện cam kết. Tuy nhiên, vì cam kết ban đầu được thực hiện trên kho lưu trữ cục bộ của nhà phát triển, nếu đồng hồ trên máy tính của họ sai hoặc họ sử dụng một mẹo như chơi với 'GIT_COMMITTER_DATE', dấu thời gian đó có thể không chính xác. –

+0

Hey, lệnh hoạt động nhưng những gì bạn nói về cách nó hoạt động không chính xác. Lệnh git rev-list thực sự xác định xem commit B có phải là tổ tiên của commit hay không. Bạn nói "phần đầu tiên liệt kê tất cả các commit là tổ tiên của commit A". Mà nó dường như, từ một số thử nghiệm tôi chỉ làm. Vì vậy nếu bạn đang tìm kiếm thông qua danh sách đó cho một SHA cam kết, thì grep sẽ thành công IFF cam kết B là trong danh sách tổ tiên đó, tức là tổ tiên của cam kết A - đối lập với những gì bạn đã viết. – eeeeaaii

0

Nếu bạn sử dụng thẻ bạn có thể làm

git describe --tags 

này sẽ cho bạn biết bao nhiêu cam kết kể từ khi thẻ ngoái.

2

Sử dụng git show trên mỗi cam kết để tìm ngày cam kết. Không có cách nào chỉ nhìn vào băm để xác định thứ tự, vì nó không là gì ngoài một băm.

Bạn có thể sử dụng chuỗi định dạng tùy chỉnh để chỉ hiển thị những gì bạn muốn, kiểm tra man pages để biết thêm thông tin.

git show --format="%ci" <commit> 
2

Bạn có thể nhận được tất cả cam kết thông tin từ các bản ghi trong đó cho thấy băm, tác giả, ngày tháng và bình luận:

git log 

Bạn có thể kéo một cụ thể cam kết thời gian của/ngày từ cam kết bản ghi. Một cái gì đó như:

git log -1 --format="%cd" <commit> 

Các '% cd' mang đến cho bạn những ngày ở định dạng của nhật ký, bạn cũng có thể làm:

  • % cD: phong cách RFC2822
  • % cr: relative
  • % ct: UNIX timestamp
  • % ci: định dạng ISO 8601

Từ đó, yo u có thể làm một số so sánh với một số kịch bản nếu bạn cần phải tự động hóa.

3

git rev-list --count có thể trợ giúp. Giả 110a187 đi kèm 4 cam kết trước 5d41af1, sau đó:

$ git rev-list --count 110a187..5d41af1 
4 
$ git rev-list --count 5d41af1..110a187 
0 

Như vậy cái gì đó như:

test $(git rev-list --count $a..$b) == 0 && \ 
     echo "$a is not an ancestor of $b" 
+0

Nếu @Glide có nghĩa là cha mẹ/hậu duệ thay vì thời gian, thì câu trả lời này chính xác hơn trong trường hợp các cam kết được đưa vào chi nhánh thông qua việc hợp nhất từ ​​các nhánh khác nhau. –

Các vấn đề liên quan