2012-06-27 42 views
38

Tôi đã chơi xung quanh với git (vẫn rất noob) và tôi muốn biết sự khác biệt giữa "đặt lại" và "rebase". Là một trong những mạnh hơn khác?Sự khác biệt giữa "git reset" so với "git rebase" là gì?

Giả sử tôi muốn xóa 3 cam kết in đậm từ lịch sử, cái nào sẽ tốt hơn để sử dụng, hoặc tôi nên gắn thẻ và sau đó xóa nó với git tag -d <tagname>?

17a64df 2012-06-21 | Xin chào sử dụng style.css (HEAD, origin/style, master),
a6792e4 2012-06-21 | Đã thêm biểu định kiểu css
801e13e 2012-06-21 | Đã thêm README
5854339 2012-06-21 | Đã thêm index.html
0b1dd4c 2012-06-21 | Đã chuyển hello.html sang lib
55649c3 2012-06-21 | Thêm tác giả/nhận xét qua email
9b2f3ce 2012-06-21 | Đã thêm nhận xét của tác giả
cdb39b0 2012-06-21 | Cam kết thẻ p với văn bản (v1.1)
b7b5fce 2012-06-21 | Điều này hoàn nguyên cam kết a6faf60631b5fbc6ee79b52a1bdac4c971b69ef8.
a6faf60 2012-06-21 | Hoàn nguyên "Rất tiếc, chúng tôi không muốn cam kết này"
a006669 2012-06-21 | Rất tiếc, chúng tôi không muốn cam kết này
262d1f7 2012-06-21 | Đã thêm tiêu đề HTML (v1)
b1846e5 2012-06-21 | Đã thêm thẻ trang HTML chuẩn (v1-beta)
bf1131e 2012-06-21 | Đã thêm HI TAG
02b86d0 2012-06-21 | Cam kết đầu tiên

Trả lời

43

Chúng hoàn toàn khác nhau. git-reset hoạt động với các tham chiếu, trên thư mục làm việc của bạn và chỉ mục mà không cần chạm vào bất kỳ đối tượng cam kết nào (hoặc các đối tượng khác). Mặt khác, git-rebase được sử dụng để ghi lại các đối tượng cam kết trước đó.

Vì vậy, nếu bạn muốn viết lại lịch sử, git-rebase là những gì bạn muốn. Lưu ý rằng bạn nên không bao giờ ghi đè lịch sử đã được đẩy và sẵn sàng cho người khác, vì việc rebasing ghi lại các đối tượng khiến chúng không tương thích với các đối tượng cũ, dẫn đến một mớ hỗn độn cho bất kỳ ai khác có liên quan.

Điều đó đang được nói, những gì bạn muốn làm ist interactive rebasing. Gọi nó sử dụng git rebase -i 262d1f7 và bạn sẽ nhận được một cửa sổ tìm kiếm như thế này:

pick 262d1f7 Added HTML header (v1) 
pick a006669 Oops, we didn't want this commit 
pick a6faf60 Revert "Oops, we didn't want this commit" 
pick b7b5fce This reverts commit a6faf60631b5fbc6ee79b52a1bdac4c971b69ef8. 
pick cdb39b0 Commit p tags with text (v1.1) 
pick 9b2f3ce Added an author comment 
pick 55649c3 Add an author/email comment 
pick 0b1dd4c Moved hello.html to lib 
pick 5854339 Added index.html 
pick 801e13e Added README 
pick a6792e4 Added css stylesheet 
pick 17a64df Hello uses style.css (HEAD, origin/style, master), 

Ở đó, bạn chỉ cần xóa dòng cho các cam kết mà bạn muốn xóa, lưu và thoát trình soạn thảo và Git sẽ viết lại lịch sử của bạn. Một lần nữa, không làm điều này nếu bạn đã đẩy các thay đổi. Nói chung có những cam kết như vậy trong lịch sử là hoàn toàn tốt đẹp.

+0

Cảm ơn bạn đã trả lời và giải thích sự khác biệt là gì. – Q10

+0

đang xóa các dòng khỏi lệnh rebase giống như thay đổi từ "pick" thành "s" cho squash? – Ninjaxor

+4

@Ninjaxor Không, xóa các đường sẽ xóa hoàn toàn các cam kết và các thay đổi mà chúng đã giới thiệu từ lịch sử. Nó là như thể cam kết không bao giờ được thực hiện. Ví dụ, nếu bạn loại bỏ một cam kết đã thêm một dòng, thì dòng đó sẽ không xuất hiện trong bất kỳ cam kết sau này sau khi rebase. Mặt khác, việc đè bẹp sẽ vẫn giữ các thay đổi được giới thiệu trong cam kết trong khi chỉ loại bỏ chính cam kết riêng biệt đó. – poke

8

Mặc dù điều này không so sánh sự khác biệt giữa hai, here's một bài viết tuyệt vời giải thích việc rebase dễ hiểu.

+1

URL hiện là http://www.jarrodspillers.com/git/2009/08/19/git-merge-vs-git-rebase-avoiding-rebase-hell.html – AnneTheAgile

+1

Bài viết đó cho biết lợi ích duy nhất là có ít hợp nhất hơn cam kết và các cam kết hợp nhất còn lại có ý nghĩa hơn. Điều này dường như không đáng để mạo hiểm. Có lợi thế nào khác không? –

+0

Bài viết đó rất hữu ích. Giải thích tốt nhất tôi đã thấy trên internet cho đến nay. –

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