Từ chối từ xa (không cho phép cập nhật nông) sau khi thay đổi URL từ xa Git


163

Tôi có một dự án dưới sự kiểm soát phiên bản Git mà tôi đã làm việc trên cả máy chủ và máy tính cục bộ của mình. Ban đầu tôi có nguồn gốc từ xa được đặt làm máy tính cục bộ của mình nhưng bây giờ tôi muốn đổi nó thành BitBucket.

Trên máy chủ tôi đã sử dụng lệnh

git remote set-url origin bitbucket_address

Nhưng bây giờ khi tôi cố gắng đẩy dự án của mình, tôi đã gặp lỗi

 ! [remote rejected] master -> master (shallow update not allowed)

Điều gì gây ra điều này và làm cách nào để khắc phục nó?


3
Làm thế nào bạn sao chép phiên bản địa phương của bạn? git clone --depth?
Sói Sói

Đó là một thời gian trước đây và tôi không thể nhớ. Có cách nào để tìm ra?
rwolst 11/03/2015

2
Nên có một tập tin có tên shallowtrong .gitthư mục của bạn .
Sói Sói

Vâng, tôi có thể thấy một shallowtập tin.
rwolst 11/03/2015

Xem stackoverflow.com/a/50996201 để biết giải pháp chỉ cần loại bỏ (hoặc viết lại) lịch sử còn thiếu
caw 30/03/19

Câu trả lời:


328

Vì có vẻ như bạn đã sử dụng git clone --depth <number>để sao chép phiên bản địa phương của bạn. Điều này dẫn đến một bản sao nông . Một hạn chế của một bản sao như vậy là bạn không thể đẩy nó từ một kho lưu trữ mới .

Bây giờ bạn có hai lựa chọn:

  1. nếu bạn không quan tâm đến lịch sử hiện tại hoặc còn thiếu của mình, hãy xem câu hỏi này
  2. nếu bạn muốn giữ toàn bộ lịch sử của mình, thì hãy tiếp tục đọc:

Vì vậy, bạn muốn giữ lịch sử của bạn, eh? Điều này có nghĩa là bạn phải hủy bỏ kho lưu trữ của bạn. Để làm như vậy, bạn sẽ cần phải thêm điều khiển từ xa cũ của bạn một lần nữa.

git remote add old <path-to-old-remote>

Sau đó, chúng tôi sử dụng git fetchđể tìm nạp lịch sử còn lại từ điều khiển cũ (như được đề xuất trong câu trả lời này ).

git fetch --unshallow old

Và bây giờ bạn sẽ có thể đẩy vào kho lưu trữ từ xa mới của bạn.


Lưu ý : Sau khi hủy bỏ bản sao của bạn, rõ ràng bạn có thể xóa điều khiển từ xa cũ một lần nữa.


45
Điều gì xảy ra nếu tôi nhân bản một dự án khởi động và tôi không muốn / cần toàn bộ lịch sử? Có cách nào để tránh nó?
itamar

9
@itamar Đây có vẻ là một ví dụ tốt cho một câu hỏi mới hoàn toàn hợp lệ. Bạn có thể liên kết đến câu hỏi này để tham khảo.
Sói Sascha

14
Được hỏi dưới dạng stackoverflow.com/questions/29748197/ trên
itamar

2
Lưu ý rằng git fetch --unshallowcó thể mất một refspec để chỉ không cho phép một nhánh nhất định chứ không phải toàn bộ repo. Ví dụ:git fetch --unshallow origin refs/heads/mydeepbranch:refs/remotes/origin/mydeepbranch
clacke

5
Nếu bạn đang đẩy tới một repo chậm hơn một chút so với bất kỳ repo nào mà bạn đã nhân bản từ đó, không tạo ra một repo hoàn toàn mới, thì đủ để tham chiếu cục bộ của bạn đủ sâu để chứa tham chiếu từ xa. Vì vậy, nếu bạn origin/masterđã cam kết trước 20 lần so với oldrepo/masterkhi bạn clone --depth 1thực hiện và bạn đã thực hiện 17 lần xác nhận cục bộ kể từ đó, thì bạn đã thực hiện git fetch --depth 37 origin refs/heads/master:refs/remotes/origin/master(xin lỗi vì bất kỳ lỗi nào), và sau đó bạn có thể thực hiện git push oldrepo mastermà không gặp sự cố (có thể yêu cầu git 1.9.0 hoặc mới hơn).
clacke

27

Trong trường hợp repo của bạn là origin, và repo ban đầu là upstream:

git fetch --unshallow upstream

Điều này làm việc cho tôi, và khá dễ dàng sau đó là câu trả lời được bình chọn hàng đầu.
Mao Thắng Vương

11

Một tùy chọn khác nếu bạn muốn giữ lại repo như với các cam kết mới mà bạn đã thêm kể từ khi cam kết ban đầu nông cạn là: Sửa đổi cam kết này với một rebase tương tác .

  • Bắt đầu một rebase tương tác bao gồm cả cam kết (gốc) đầu tiên với

    git rebase --interactive --root
    
  • Thay đổi pick(các) cam kết ban đầu thành editvà lưu và đóng tệp.

    Nếu bạn đã nhân bản repo với độ sâu lớn hơn 1, bạn có thể cần phải làm tương tự cho tất cả các cam kết đó. Hoặc, thay vào đó, thực hiện fixupcho tất cả những điều này trong quá trình rebase tương tác.

  • Chuyển đổi cam kết này thành một cam kết thông thường, không được phép với

    git commit --amend --no-edit
    

    Điều này cũng sẽ thay đổi ID cam kết và thêm bạn làm đồng tác giả với cam kết ban đầu này.

  • Đừng quên kết thúc cuộc nổi loạn của bạn

    git rebase --continue
    

Cảm ơn bạn! Hoạt động như một lá bùa, khi kho lưu trữ ban đầu bị xóa và bạn chỉ có một bản sao nông của nó.
Vitalii Dmitriev

9

Nếu bạn muốn đẩy repo mới như hiện tại, bạn có thể thử điều này:

  • Trước tiên hãy xóa old git folderkhỏi repo hiện tại của bạn,sudo rm -rf .git
  • Sau đó khởi tạo lại git git init
  • Sau đó thêm repo từ xa mới git remote add your-new-repo
  • Sau đó đẩy nó.

Tôi thấy đây là một giải pháp tốt hơn, vì nó không cần phải đẩy đến cái cũ. Đôi khi điều này có thể xảy ra với nồi hơi.
rnpd

Về cơ bản, đây là câu trả lời từ câu hỏi liên quan mà bạn có thể tìm thấy ở đây .
Sói Sascha

@NachPD Tôi không chắc ý của bạn là gì, khi bạn nói rằng giải pháp kia yêu cầu "đẩy đến cái cũ". Bạn có nghĩa là một tìm nạp thay vì đẩy? Bởi vì nó không cần đẩy.
Sói Sascha

0

Nếu tìm nạp --unshallow không hoạt động. Phải có một số vấn đề với chi nhánh của bạn. Sửa nó bằng lệnh sau trước khi đẩy nó.

git filter-branch -- --all

Chỉ làm điều này với --unshallow không hoạt động vì có mối quan tâm AN TOÀN .

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.