Git: "Không thể 'bí' nếu không có lần cam kết trước đó" trong khi rebase


96

Tôi có những điều sau trong văn bản việc cần làm của git rebase -i HEAD~2:

pick 56bcce7 Closes #2774
pick e43ceba Lint.py: Replace deprecated link

# Rebase 684f917..e43ceba onto 684f917 (2 command(s))
#
...

Bây giờ, khi tôi cố gắng chọn cái đầu tiên ( 56bcce7) và chọn cái thứ hai bằng cách thêm "s" trước cái đầu tiên, tôi gặp lỗi sau:

Cannot 'squash' without a previous commit

Ai đó có thể giải thích cho tôi ý nghĩa của nó không, và tôi phải làm thế nào?

Tôi muốn loại bỏ cam kết đầu tiên ( 56bcce7) và "chọn và đặt lại từ khóa" e43cebacam kết thứ hai ( )


1
Thay đổi HEAD ~ 2 thành HEAD ~ 3 nếu bạn thực sự muốn bí.
ElpieKay

1
Và có thể sử dụng --root, nếu ĐẦU ~ 2 là bạn đầu tiên cam kết: stackoverflow.com/a/598788/2444812
Sybille Peters

Câu trả lời:


81

Rebase tương tác trình bày các cam kết theo thứ tự ngược lại với những gì bạn đã quen khi sử dụng git log. git rebase -iphát lại các cam kết đã chọn theo thứ tự chính xác (từ trên xuống) mà chúng được liệt kê trong tệp hướng dẫn rebase đã lưu. Khi thu nhỏ, cam kết được chọn để thu nhỏ sẽ được kết hợp với cam kết đứng trước nó trong danh sách (đã chỉnh sửa), tức là cam kết từ dòng trước đó. Trong trường hợp của bạn - không có cam kết trước cho 56bcce7. Bạn phải làm một trong những điều sau

  • git rebase -i HEAD~3(nếu bạn muốn đi 56bcce7vào 684f917)
  • Nếu bạn muốn kết hợp 56bcce7với e43cebae43cebakhông phụ thuộc vào 56bcce7, thì chỉ cần sắp xếp lại chúng:

    r e43ceba Lint.py: Replace deprecated link
    s 56bcce7 Closes #2774
    

    CẬP NHẬT : Câu trả lời của Gus dưới đây gợi ý một cách tốt hơn để làm điều tương tự, mà không cần sắp xếp lại hai cam kết:

    r 56bcce7 Closes #2774
    s e43ceba Lint.py: Replace deprecated link
    

    Thao tác này sẽ tách / hợp nhất hai cam kết thành một. Khi rebase tương tác yêu cầu một thông báo cam kết được làm lại từ khóa cho 56bcce7, hãy cung cấp thông báo cam kết mô tả sự kết hợp của 56bcce7e43ceba.


1
Tôi muốn 56bcce7 lao vào e43ceba. Vì vậy, làm cách nào để thực hiện Bước 1 ở đây?
Dawny33

83

Tôi đã gặp sự cố tương tự mà tôi đã giải quyết như sau:

Đây là nhóm cam kết mà tôi muốn xóa:

1 s 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 pick 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users

Như bạn thấy, tôi không muốn. 4, nhưng 1, 2 và 3 không có cam kết nào trước đó để đi vào . Do đó, Không thể 'bí' mà không có lỗi cam kết trước đó .

Giải pháp của tôi là sử dụng rtùy chọn cho# r, reword = use commit, but edit the commit message

Vì vậy, danh sách cam kết của tôi trông như thế này:

1 r 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 s 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users

Sau khi lưu, trình bao tương tác yêu cầu tôi ghi lại cam kết đã chọn.

Sau đó, nhật ký cam kết của tôi dẫn đến một cam kết duy nhất dẫn đến lịch sử cam kết sạch hơn.


2
giống như tôi nếu bạn gặp lỗi vì bạn không chọn bất kỳ cam kết nào cho từ khóa hoặc chọn và nhận được lỗi được đề cập (trên câu hỏi), bạn sẽ cần phải làm git rebase --edit-todovà sửa khi tham khảo câu trả lời này và sau đó làmgit rebase --continue
old-

Câu trả lời này ngắn gọn và đến mức, thực sự hữu ích, cảm ơn
gonzofish

16

Tôi đã gặp sự cố này và lý do tại sao nó xảy ra trong trường hợp của tôi là bạn không thể bỏ các cam kết cũ hơn vào một cam kết mới. Đây là một ví dụ cho biết bạn có 3 cam kết:

1 pick 01mn9h78 The lastest commit
2 pick a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back

Bây giờ nếu bạn nói git rebase -i HEAD~3và bạn làm điều gì đó như

1 pick 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 s 093479uf An old commit i made a while back

Điều này sẽ dẫn đến lỗi:

lỗi: không thể 'bí' nếu không có cam kết trước Bạn có thể sửa lỗi này bằng 'git rebase --edit-todo' và sau đó chạy 'git rebase --continue'. Hoặc bạn có thể hủy bỏ rebase bằng 'git rebase --abort'.

Giải pháp :

Khi xóa các cam kết, bạn nên xóa các cam kết gần đây thành các cam kết cũ chứ không phải ngược lại, do đó trong ví dụ, nó sẽ như thế này:

1 s 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back

Điều này sẽ hoạt động tốt, trong trường hợp bạn muốn tất cả các thông báo cam kết của mình, tôi sẽ đề xuất sửa chữa thay vì .


5
Cảm ơn bạn- Tôi không thường xuyên bỏ qua các cam kết và lời khuyên nên chọn cam kết cũ nhất là điều đã giúp tôi vượt qua lỗi git không hữu ích.
0x574F4F54 14/09/18

3

Bí mật với logic ngược lại . Bạn sẽ có thể chọn thông báo cam kết mong muốn ở bước sau.

  • pickcam kết đầu tiên mà bạn không muốn thông báo cam kết.
  • squashhoặc fixup(các) cam kết mà bạn muốn hợp nhất, cho đến một cam kết có thông báo cam kết mà bạn thực sự muốn.
pick 56bcce7 Closes #2774
squash e43ceba Lint.py: Replace deprecated link
  • xác nhận thay đổi ( :x)
  • xóa (các) thông báo cam kết mà bạn không muốn và chỉ để lại thông báo từ cam kết mà bạn muốn (trong trường hợp này Lint.py: Replace deprecated link:).
  • xác nhận sự lựa chọn ( :x)

Hy vọng nó rõ ràng hơn cho ai đó ✌🏽


1

Tốt nhất bạn chỉ nên nói trong trình chỉnh sửa tương tác có chứa các cam kết, git luôn hiển thị từ dưới lên trên và người ta nên để lại mục "chọn" ở trên cùng để nhận các dấu nháy từ bên dưới.


1

Tôi vừa thử cách tiếp cận này.

git log -n3

Điều này sẽ hiển thị 3 cam kết cuối cùng sẽ cho tôi ý tưởng về cam kết mới nhất là gì và cam kết nào đã đi trước đó. Hiện đã tuyên bố phục hồi,

git rebase -i HEAD ~ 3

Chọn cam kết cuối cùng mà chúng tôi cần để loại bỏ hai cam kết còn lại. Id cam kết được chọn làm cam kết cơ sở sẽ như thế nào,

chọn commit_id

Đối với hai id cam kết còn lại, hãy thay đổi chúng thành,

commit_id bí

hoặc đơn giản,

s commit_id


0

Tôi cũng đã gặp vấn đề này ngay bây giờ, đó chỉ là bất cẩn. Bạn có thể giải quyết vấn đề như tiếp theo: khi bạn cố gắng bỏ qua dòng đầu tiên (56bcce7) và chọn dòng thứ hai, bạn nên thêm "s" trước dòng thứ hai nhưng không phải là người đầu tiên. bạn cũng có thể tham khảo trang web tiếp theo: http://backlogtool.com/git-guide/en/stepup/stepup7_5.html


1
Chào ! Sẽ tốt hơn nếu bạn xem Cách tạo một ví dụ Tối thiểu, Hoàn chỉnh và Có thể xác minh cho nỗ lực trong tương lai tại Stack tràn. -Cảm ơn
Momin
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.