Làm thế nào để kiểm tra trong Git theo ngày?


314

Tôi đang làm việc trên một hồi quy trong mã nguồn. Tôi muốn nói với Git: "kiểm tra nguồn dựa trên ngày / giờ được tham số hóa". Điều này có thể không?

Tôi cũng đã có những thay đổi theo quan điểm hiện tại mà tôi không muốn mất. Lý tưởng nhất, tôi muốn chuyển đổi qua lại giữa nguồn hiện tại và một số phiên bản tôi quan tâm dựa trên một ngày trước đó.


9
Chỉ trong trường hợp bạn không biết về nó, git bisect là khá tuyệt vời để tìm hồi quy. Tôi sẽ nói, hãy sử dụng cú pháp {1 năm trước} như Andy đã nói, để tìm một cam kết tốt, sau đó sử dụng nó làm git bisect goodđiểm ban đầu của bạn .
MatrixFrog

Tôi cảm thấy như đây là một trường hợp sử dụng tốt cho tags.
Jess

Câu trả lời:


365

Để giữ những thay đổi hiện tại của bạn

Bạn có thể giữ công việc của mình được cất đi mà không cần phải cam kết với git stash. Bạn sẽ sử dụng git stash popđể lấy lại. Hoặc bạn có thể (như carleeto đã nói)git commit nó đến một chi nhánh riêng.

Thanh toán theo ngày bằng cách sử dụng rev-parse

Bạn có thể kiểm tra một cam kết trước một ngày cụ thể bằng cách sử dụng rev-parsenhư thế này:

git checkout 'master@{1979-02-26 18:30:00}'

Thông tin chi tiết về các tùy chọn có sẵn có thể được tìm thấy trong git-rev-parse.

Như đã lưu ý trong các bình luận, phương pháp này sử dụng reflog để tìm cam kết trong lịch sử của bạn. Theo mặc định, các mục này hết hạn sau 90 ngày . Mặc dù cú pháp sử dụng reflog ít dài dòng hơn nhưng bạn chỉ có thể quay lại 90 ngày.

Thanh toán theo ngày bằng cách sử dụng danh sách rev

Tùy chọn khác, không sử dụng reflog, là sử dụng rev-listđể nhận được cam kết tại một thời điểm cụ thể với:

git checkout `git rev-list -n 1 --first-parent --before="2009-07-27 13:37" master`

Lưu ý --first-Parent nếu bạn chỉ muốn lịch sử của mình chứ không phải các phiên bản do hợp nhất mang lại. Đó là những gì bạn thường muốn.


2
@Rocky Bạn có thể cho chúng tôi biết thêm chi tiết Rocky không? Bạn đang nhập gì vào dòng lệnh và tại sao bạn nói nó không hoạt động? Bạn nhận được một thông báo lỗi?
Andy

8
@Rocky: Vấn đề là tham số cần được đặt trong dấu ngoặc kép, bash khác phân tách các đối số tại khoảng trắng. Hãy thử git co 'master@{2 days ago}'.
Mark Wilden

13
Lưu ý: tùy thuộc vào khoảng cách bạn quay lại, điều này có thể không hoạt động vì nó sử dụng reflog (sẽ hết hạn sau một thời gian). Bạn sẽ thấy 'cảnh báo: Đăng nhập' chủ 'chỉ quay lại ...'. Giải pháp của Rocky sẽ luôn hoạt động. kiểm tra gitgit rev-list -n 1 --before="2009-07-27 13:37" master
Mark Nadig

3
Tôi đã chỉnh sửa câu trả lời của bạn vì backticks không được dùng nữa và khó đọc. Subshells $(...)được ưa thích.
Amedee Van Gasse

1
@Andy Chúc mừng sinh nhật lần thứ 40, Andy! (giả sử đó là những gì 1979-02-26 có nghĩa :))
David Blevins

123

Giải pháp của Andy không hiệu quả với tôi. Ở đây tôi tìm thấy một cách khác:

git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`

Git: thanh toán theo ngày


3
Khi tôi thực hiện lệnh trên, tôi có error: unknown switch `n'ý tưởng nào để khắc phục điều này không?
Tim

15

Có vẻ như bạn cần một cái gì đó dọc theo dòng này: Thanh toán Git dựa trên ngày

Nói cách khác, bạn sử dụng rev-listđể tìm cam kết và sau đó sử dụng thanh toán để thực sự có được nó.

Nếu bạn không muốn mất các thay đổi theo giai đoạn của mình, điều dễ nhất là tạo một chi nhánh mới và cam kết chúng với chi nhánh đó. Bạn luôn có thể chuyển đổi qua lại giữa các chi nhánh.

Chỉnh sửa: Liên kết không hoạt động, vì vậy đây là lệnh:

git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`

2
Liên kết tuyệt vời! Vì vậy, git checkout branch@{date}ngừng hoạt động khi reflog hết hạn, nhưng bạn có thể sử dụng git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`.
cdunn2001

10

Để những người thích một đường ống để thay thế lệnh

git rev-list -n1 --before=2013-7-4 master | xargs git checkout

9

Trong trường hợp của tôi, -n 1tùy chọn không hoạt động. Trên Windows tôi đã thấy rằng chuỗi lệnh sau hoạt động tốt:

git rev-list -1 --before="2012-01-15 12:00" master

Điều này trả về SHA của cam kết thích hợp cho ngày đã cho và sau đó:

git checkout SHA

4

Các git rev-parsegiải pháp của @Andy đề xuất hoạt động tốt nếu ngày bạn quan tâm là cam kết ngày của . Tuy nhiên, nếu bạn muốn thanh toán dựa trên ngày của tác giả , rev-parsesẽ không hoạt động, vì nó không cung cấp tùy chọn sử dụng ngày đó để chọn các cam kết. Thay vào đó, bạn có thể sử dụng như sau.

git checkout $(
  git log --reverse --author-date-order --pretty=format:'%ai %H' master |
  awk '{hash = $4} $1 >= "2016-04-12" {print hash; exit 0 }
)

(Nếu bạn cũng muốn chỉ định thời gian sử dụng $1 >= "2016-04-12" && $2 >= "11:37"trong vị từ awk .)


3

Đi xa hơn với rev-listtùy chọn, nếu bạn muốn tìm cam kết hợp nhất gần đây nhất từ ​​nhánh chính của bạn vào nhánh sản xuất của bạn (như một ví dụ hoàn toàn giả thuyết):

git checkout `git rev-list -n 1 --merges --first-parent --before="2012-01-01" production`

Tôi cần tìm mã trên các máy chủ sản xuất kể từ một ngày nhất định. Điều này tìm thấy nó cho tôi.


2

Nếu bạn muốn có thể quay lại phiên bản chính xác của kho lưu trữ tại thời điểm bạn thực hiện một bản dựng, tốt nhất là gắn thẻ cam kết mà bạn thực hiện bản dựng.

Các câu trả lời khác cung cấp các kỹ thuật để trả lại kho lưu trữ cho cam kết gần đây nhất trong một nhánh vào một thời điểm nhất định - nhưng chúng có thể không phải lúc nào cũng đủ. Ví dụ: nếu bạn xây dựng từ một chi nhánh và sau đó xóa chi nhánh hoặc xây dựng từ một chi nhánh bị hủy bỏ sau đó, thì cam kết bạn đã xây dựng có thể trở thành "không thể truy cập" trong git từ bất kỳ chi nhánh hiện tại nào. Các đối tượng không thể truy cập trong git cuối cùng có thể bị xóa khi kho được nén.

Đặt một thẻ vào cam kết có nghĩa là nó không bao giờ trở nên không thể truy cập được, bất kể bạn làm gì với các nhánh sau đó (cấm loại bỏ thẻ).


Mặc dù điều này không cho tôi câu trả lời mà tôi tìm kiếm, nhưng nó xứng đáng được đề cập đến vì đã chỉ ra một khía cạnh không được đề cập cho đến nay. Đây có thể là nguồn gốc của các vấn đề ngăn bạn tiếp cận phiên bản phù hợp.
manuelvigarcia

1
git rev-list -n 1 --before="2009-07-27 13:37" origin/master

lấy chuỗi in (ví dụ XXXX) và làm:

git checkout XXXX

2
Đây không phải là một bản sao của câu trả lời @bartoszkp sao? chỉ cần thêm tham chiếu đến nguồn gốc, nên bình luận về câu trả lời khác ...
manuelvigarcia

vâng, trên thực tế hầu như, chỉ cần làm rõ những gì cần sao chép cho những người không biết SHA là gì (như tôi), trong trường hợp của tôi văn bản đó không rõ ràng và đây là mã của tôi sau khi tìm ra giải pháp, không được sao chép, thực tế bạn có thể thấy các tùy chọn cũng rất khác nhau
Luca C.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.