Làm cách nào tôi có thể bỏ ghi chú lần cam kết cuối cùng trong kho lưu trữ git bare?


91

Cân nhắc rằng có một số lệnh git không có ý nghĩa gì trong kho lưu trữ trống (vì kho lưu trữ trống không sử dụng chỉ mục và không có thư mục làm việc),

git reset --hard HEAD^ 

không phải là giải pháp để bỏ ghi nhận thay đổi cuối cùng trong kho lưu trữ như vậy.

Tìm kiếm trên Internet, tất cả những gì tôi có thể tìm thấy liên quan đến chủ đề này là điều này , trong đó tôi được trình bày ba cách để làm điều này:
1. "cập nhật ref bằng tay (liên quan đến hệ thống ống nước)";
2. " git push -ffrom a non-bare repository";
3. " git branch -f this $that".

Bạn nghĩ giải pháp nào phù hợp hơn hoặc có những cách nào khác để thực hiện việc này? Thật không may, tài liệu tôi tìm thấy về kho git bare khá nghèo nàn.


8
@ Lavinia-Garbriela Dobrovol Đừng sử dụng những thứ phức tạp bên dưới. Bạn đang cố gắng chuyển HEAD sang một cam kết khác và đó là mục đích của git reset, ngay cả trong một repo trống. Theo câu trả lời của tôi bên dưới, hãy sử dụng: git reset --soft <commit> Với --soft, bạn không thử thay đổi cây làm việc và chỉ mục không tồn tại, vì vậy git cho phép bạn thực hiện việc đặt lại không có vấn đề gì.
Hazok

Câu trả lời:


130

Bạn có thể sử dụng git update-reflệnh. Để loại bỏ cam kết cuối cùng, bạn sẽ sử dụng:

$ git update-ref HEAD HEAD^

Hoặc nếu bạn không ở trong nhánh mà bạn không thể xóa lần cam kết cuối cùng:

$ git update-ref refs/heads/branch-name branch-name^

Bạn cũng có thể vượt qua sha1 nếu bạn muốn:

$ git update-ref refs/heads/branch-name a12d48e2

Xem tài liệu về lệnh git-update-ref .


@ Lavinia-Gabriela Dobrovolschi: đúng, tôi không quen với cú pháp chính xác.
VonC

@VonC Bạn có thể chỉ định <ref> in git update-ref <ref> <newvalue>là nhánh bên phải, chẳng hạn như "refs / heads / master" thay vì HEAD chẳng hạn. Tôi hy vọng tôi đã không hiểu sai câu hỏi của bạn.
Lavinia-Gabriela Dobrovolschi

@Sylvain: +1 chỉnh sửa tốt. @ Lavinia-Gabriela Dobrovolschi cảm ơn bạn vì những lựa chọn. Điều đó thực tế hơn nhiều (nếu bạn có quyền truy cập trực tiếp vào máy chủ từ xa, tôi cho là vậy).
VonC

3
Các ví dụ gây hiểu lầm liên quan đến branch-nameđối số. Khi sử dụng update-refvới một "chi nhánh", bạn hoàn toàn phải chỉ định tên tham chiếu đầy đủ của chi nhánh (nghĩa là thêm vào trước refs/heads/tên chi nhánh ngắn bình thường). Nếu bạn chỉ sử dụng tên ngắn, bạn sẽ phải tạo / cập nhật $GIT_DIR/branch-namethay vì $GIT_DIR/refs/heads/branch-name. Sự tồn tại của cả hai branch-namerefs/heads/branch-namesẽ gây ra cảnh báo “đổi tên… không rõ ràng”.
Chris Johnsen

Câu trả lời này phức tạp hơn nhiều so với những gì Zach đề xuất. Và giải pháp của anh ấy hoạt động tốt.
Krystian

32

Nếu bạn sử dụng thông tin sau trong repo trống:

git reset --soft <commit>

thì bạn sẽ không gặp phải các vấn đề mà bạn gặp phải khi sử dụng --hard--mixedcác tùy chọn trong một repo trần vì bạn không cố gắng thay đổi thứ gì đó mà repo không có (tức là cây làm việc và chỉ mục). Trong trường hợp cụ thể của bạn, bạn muốn sử dụng (từ repo trần):

git reset --soft HEAD^

Để chuyển các nhánh trên repo từ xa, hãy làm:

git symbolic-ref HEAD refs/heads/<branch_name>

Để xem việc sử dụng nhánh đã chọn hiện tại:

git symbolic-ref HEAD

https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html


3
Làm thế nào để bạn chọn chi nhánh mà bạn muốn di chuyển? Ví dụ của bạn hoạt động tốt trên tổng thể nhưng git checkout other_branchkhông hoạt động trần trụi.
Gauthier

1
Hmmm ... Tôi đang tự hỏi ai đã bỏ phiếu cho tôi về điều này. Câu hỏi không hỏi làm thế nào để chuyển các nhánh trên một repo từ xa, nó hỏi làm thế nào để đặt lại trên một repo trần. Để thay đổi nhánh mặc định trong repo từ xa, hãy sử dụng git Symbol-ref HEAD refs / heads / <branch_name>.
Hazok

7

Các git push -fcần làm việc tốt:
nếu bạn sao chép rằng repo trần, loại bỏ cam kết cuối cùng ( git reset --hard HEAD^như bạn đề cập đến, nhưng trong một repo không trống địa phương) và đẩy lùi ( -f):

  • bạn không thay đổi bất kỳ SHA1 nào cho các cam kết khác trước khi bạn xóa.
  • bạn chắc chắn rằng bạn đẩy lùi nội dung chính xác của repo trần trừ đi phần cam kết bổ sung (vì bạn vừa sao chép nó trước).

@ VonC Chào Von, tôi thấy bạn trả lời rất nhiều trên Git nên muốn hỏi bạn ... Tôi rất tò mò, tại sao git reset --soft <sha1>như trong câu trả lời dưới đây của tôi không phải là cách thực hành được khuyến nghị để di chuyển HEAD trên repo trần?
Hazok

Tôi đoán một lý do khác mà tôi yêu cầu là sử dụng soft reset cho các bản đại diện trần không phải là thông tin sẵn có và nhiều diễn đàn dường như có các cách giải quyết phức tạp không cần thiết khi có vẻ như soft reset là phương pháp tốt nhất do ít phải nhập và ít cơ hội nhất vì lỗi.
Hazok

2
@Zach: a reset --softsẽ hoạt động khi được thực hiện trực tiếp trên repo trần. Tôi nghi ngờ điều này hiếm khi được thực hiện vì repo trần thường là repo ngược dòng (tức là repo mà bạn đang đẩy dữ liệu vào) và hầu hết thời gian, bạn không có quyền truy cập cục bộ trực tiếp vào nó. Nhưng nếu bạn làm vậy, thì đây chắc chắn là một ví dụ điển hình khác về reset --softcách sử dụng "" (như trong stackoverflow.com/questions/5203535/… ) Vì vậy, hãy +1 cho câu trả lời của bạn.
VonC

2

Bạn cũng có thể sử dụng ký hiệu git refspec và làm như sau:

git push -f origin +<commit you want to revert to>:<destination_head | branch_name>

Điều này buộc cập nhật nhánh đích (như được biểu thị bằng ref) cho cam kết nguồn như được biểu thị bằng +<object ref>phần.


2
trừ khi có một acl trên cành - mà thường là trường hợp nếu bạn "cần phải làm điều đó trên repo trần bản thân" ...
David Schmitt
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.