Lỗi Git Push: từ chối cập nhật chi nhánh đã kiểm tra


196

Tôi đã giải quyết một số xung đột hợp nhất, sau đó đã cố gắng Đẩy các thay đổi của tôi và nhận được lỗi sau:

c:\Program Files (x86)\Git\bin\git.exe push --recurse-submodules=check "origin" master:master
Done
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To C:/Development/GIT_Repo/Project
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'C:/Development/GIT_Repo/Project'

Có ai biết những gì có thể gây ra lỗi này?



6
Bây giờ bạn thực sự có một cách an toàn để chuyển sang repo không trần với Git 2.3.0 (tháng 2 năm 2015) và git config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC

Câu trả lời:


229

Lý do: Bạn đang đẩy đến Kho lưu trữ không trống

Có hai loại kho: trần và không trần

Các kho lưu trữ trần không có một bản sao làm việc và bạn có thể đẩy chúng. Đó là những loại kho lưu trữ bạn có trong Github! Nếu bạn muốn tạo một kho lưu trữ trần, bạn có thể sử dụng

git init --bare

Vì vậy, trong ngắn hạn, bạn không thể đẩy đến một kho lưu trữ không trống. . Những gì bạn có thể làm, là tìm nạp và hợp nhất từ ​​kho lưu trữ khác. Đây là cách pull requestmà bạn có thể thấy trong Github hoạt động. Bạn yêu cầu họ kéo bạn ra và bạn không ép buộc họ.


Cập nhật : Cảm ơn VonC đã chỉ ra điều này, trong các phiên bản git mới nhất (hiện là 2.3.0), việc đẩy sang nhánh đã kiểm tra của kho lưu trữ không trống là có thể . Tuy nhiên, bạn vẫn không thể đẩy sang một cây làm việc bẩn , dù sao đó không phải là một hoạt động an toàn.


1
Đúng! Điều này đúng cảm ơn bạn! Khi tôi có khoảng một triệu việc phải làm, tôi vô tình nhân bản thư mục làm việc .... doh!
Funky

25
Trên thực tế, bạn có thể đẩy đến một kho lưu trữ không trống, bạn chỉ không thể đẩy đến một chi nhánh hiện đang được kiểm tra .
Không ở đâu người đàn ông

1
Có hàng tá kịch bản khác, thực sự. Ví dụ: một số kho lưu trữ của tôi chỉ trên máy trạm và máy tính xách tay của tôi (không phải mã, nhưng tôi ghi chú). Trên mỗi tôi có hai nhánh, "máy trạm" và "máy tính xách tay". Trên máy trạm, tôi chỉ kiểm tra "máy trạm" và tôi chỉ đẩy đến nhánh "máy trạm" trên máy tính xách tay (và ngược lại).
Người đàn ông hư không

8
Bây giờ bạn thực sự có một cách an toàn để chuyển sang repo không trần với Git 2.3.0 (tháng 2 năm 2015) và git config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC

1
@skelly Bản sao của bạn không trống, trong khi bản sao trên github. Vì vậy, trong khi cả hai bản sao đều có lịch sử, bản sao trên github không có bất kỳ cam kết nào được kiểm tra, nhưng bản sao của bạn thì có, cho phép bạn làm việc!
Shahbaz

115

Tôi đã giải quyết vấn đề này bằng cách xác minh đầu tiên rằng điều khiển từ xa không có bất cứ điều gì được kiểm tra (nó thực sự không được phép), và sau đó làm cho nó trần trụi với:

$ git config --bool core.bare true

Sau đó git đẩy hoạt động tốt.


3
Đây là bản sửa lỗi một lớp lót mà tôi đang tìm kiếm .. nhưng có thể giải thích các repos không trần như câu trả lời
@shahbaz

Điều này sẽ cho phép lịch sử thay đổi được đẩy, nhưng những thay đổi đó sẽ không được phản ánh trong repo không trần.
jhill515

sẽ bạn git config core.bare falsegit reset --hard ?
máy bay

1
Như đã đề cập ở trên, điều khiển từ xa sẽ không được sửa đổi khi bạn nhấn vào nó.
dùng1097111

46

Tóm lược

Bạn không thể đẩy đến một nhánh đã kiểm tra của kho lưu trữ vì nó sẽ gây rối với người dùng của kho lưu trữ đó theo cách có thể sẽ kết thúc với việc mất dữ liệu và lịch sử . Nhưng bạn có thể đẩy đến bất kỳ chi nhánh nào khác của cùng một kho lưu trữ.

Vì kho lưu trữ trần không bao giờ có bất kỳ chi nhánh nào được kiểm tra, bạn luôn có thể đẩy đến bất kỳ chi nhánh nào của kho lưu trữ trần.

Khám nghiệm tử thi

Khi một chi nhánh được kiểm tra, cam kết sẽ thêm một cam kết mới với đầu của chi nhánh hiện tại làm cha mẹ của nó và di chuyển đầu của chi nhánh thành cam kết mới đó.

Vì thế

A ← B
    ↑
[HEAD,branch1]

trở thành

A ← B ← C
        ↑
    [HEAD,branch1]

Nhưng nếu ai đó có thể đẩy vào nhánh đó ở giữa, người dùng sẽ tự nhận được trong chế độ đầu git tách ra :

A ← B ← X
    ↑   ↑
[HEAD] [branch1]

Bây giờ người dùng không còn ở nhánh 1 nữa, mà không yêu cầu rõ ràng để kiểm tra một nhánh khác. Tồi tệ hơn, người dùng hiện đang ở bên ngoài bất kỳ chi nhánh nào và mọi cam kết mới sẽ bị treo lủng lẳng :

      [HEAD]
        ↓
        C
      ↙
A ← B ← X
        ↑
       [branch1]

Theo giả thuyết, nếu tại thời điểm này, người dùng kiểm tra một chi nhánh khác, thì cam kết lơ lửng này sẽ trở thành trò chơi công bằng cho người thu gom rác của Git .



21

cd vào thư mục repo / mà bạn đang đẩy vào máy từ xa và nhập

$ git config core.bare true

Điều này không hoạt động. Các kho lưu trữ trống sau khi đẩy vào nó.
Sören

như đã nói bởi jhil515 ở trên, các tệp không trống không được cập nhật, chỉ có các cơ sở dữ liệu.
Denis Cousineau

19

Đối với tôi, những điều sau đây đã lừa

git config --global receive.denyCurrentBranch updateInstead

Tôi đã thiết lập ổ F:, gần như toàn bộ, để đồng bộ giữa máy tính để bàn Windows 10 và máy tính xách tay Windows 10 của tôi, sử dụng Git. Tôi đã kết thúc việc chạy lệnh trên trên cả hai máy.

Đầu tiên tôi chia sẻ ổ F của máy tính để bàn trên mạng. Sau đó, tôi đã có thể sao chép nó trên máy tính xách tay của mình bằng cách chạy:

F: git clone 'file://///DESKTOP-PC/f'

Thật không may, tất cả các tệp đã kết thúc dưới "F: \ f \" trên máy tính xách tay của tôi, không phải dưới F: \ trực tiếp. Nhưng tôi đã có thể cắt và dán chúng bằng tay. Git vẫn làm việc từ vị trí mới sau đó.

Sau đó, tôi đã thử thực hiện một số thay đổi cho các tệp trên máy tính xách tay, cam kết chúng và đẩy chúng trở lại máy tính để bàn. Điều đó không hoạt động cho đến khi tôi chạy lệnh git config được đề cập ở trên.

Lưu ý rằng tôi đã chạy tất cả các lệnh này từ trong Windows PowerShell, trên cả hai máy.

CẬP NHẬT: Tôi vẫn có vấn đề đẩy thay đổi, trong một số trường hợp. Cuối cùng tôi cũng bắt đầu kéo các thay đổi thay vào đó, bằng cách chạy phần sau trên máy tính, tôi muốn kéo (các) cam kết mới nhất tới:

git pull --all --prune


1
Tôi thích địa phương này hơn git repo:git config receive.denyCurrentBranch updateInstead
klor

14

Vì đã có sẵn một kho lưu trữ, đang chạy

git config --bool core.bare true

trên kho lưu trữ từ xa nên đủ

Từ tài liệu core.bare

Nếu đúng (Bare = true), kho lưu trữ được coi là trống không có thư mục làm việc liên quan. Nếu đây là trường hợp một số lệnh yêu cầu thư mục làm việc sẽ bị vô hiệu hóa, chẳng hạn như git-add hoặc git-merge (nhưng bạn sẽ có thể đẩy vào nó).

Cài đặt này được tự động đoán bởi git-clone hoặc git-init khi kho được tạo. Theo mặc định, kho lưu trữ kết thúc bằng "/.git" được coi là không trống (Bare = false), trong khi tất cả các kho lưu trữ khác được giả định là trần (Bare = true).


12

TLD

  1. Kéo và đẩy lại : git pull &&& git push.
  2. Vẫn còn một vấn đề? Đẩy vào nhánh khác: git push origin master:foovà hợp nhất nó trên repo từ xa.
  3. Hoặc buộc đẩy bằng cách thêm -f( denyCurrentBranchcần phải bỏ qua).

Về cơ bản lỗi có nghĩa là kho lưu trữ của bạn không cập nhật với mã từ xa (chỉ mục và cây công việc của nó không phù hợp với những gì bạn đã đẩy).

Thông thường bạn nên pullđầu tiên để có được những thay đổi gần đây và pushnó một lần nữa.

Nếu không giúp được, hãy thử đẩy vào các chi nhánh khác nhau, ví dụ:

git push origin master:foo

sau đó hợp nhất nhánh này trên kho lưu trữ từ xa trở lại với master.

Nếu bạn đã thay đổi một số cam kết trong quá khứ một cách có chủ ý thông qua git rebasevà bạn muốn ghi đè repo bằng các thay đổi của mình, bạn có thể muốn buộc đẩy bằng cách thêm -f/ --forcetham số (không được khuyến nghị nếu bạn không làm rebase). Nếu vẫn sẽ không làm việc, bạn cần phải thiết lập receive.denyCurrentBranchđể ignoretrên xa theo đề nghị của một thông điệp git qua:

git config receive.denyCurrentBranch ignore

3

Có thể repo từ xa của bạn là trong chi nhánh mà bạn muốn đẩy. Bạn có thể thử kiểm tra một chi nhánh khác trong máy từ xa của bạn. Tôi đã làm điều này, hơn là những lỗi này đã biến mất và tôi đã đẩy thành công vào repo từ xa của mình. Lưu ý rằng tôi sử dụng ssh để kết nối máy chủ của riêng tôi thay vì github.com.


1

Tôi có lỗi này vì repo git (vô tình) được khởi tạo hai lần trên cùng một vị trí: đầu tiên là repo không trần và ngay sau đó là repo trần. Vì thư mục .git vẫn còn, git giả định kho lưu trữ không trống. Loại bỏ thư mục .git và dữ liệu thư mục làm việc đã giải quyết vấn đề.


1
Trong tình huống của tôi, đây là trường hợp. Xóa .gitthư mục trên điều khiển từ xa cho phép tôi đẩy cam kết ban đầu.
tim.rohrer

0

Tôi đã gặp lỗi này khi tôi đang chơi xung quanh trong khi đọc progit. Tôi đã tạo một kho lưu trữ cục bộ, sau đó tìm nạp nó trong một repo khác trên cùng hệ thống tệp, thực hiện chỉnh sửa và cố gắng đẩy. Sau khi đọc câu trả lời của NowhereMan, một cách khắc phục nhanh là vào thư mục "từ xa" và tạm thời kiểm tra một cam kết khác, đẩy từ thư mục tôi đã thực hiện thay đổi, sau đó quay lại và đặt lại đầu vào chủ.

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.