Git: Thiết lập một điều khiển từ xa chỉ tìm nạp?


132

Khi tôi chạy git remote -vtrong một trong các kho Git của mình có cấu hình (các) điều khiển từ xa, tôi thấy rằng mỗi điều khiển từ xa có cả thông số kỹ thuật tìm nạp và đẩy:

$ git remote -v
<remote-name> ssh://host/path/to/repo (fetch)
<remote-name> ssh://host/path/to/repo (push)

Đối với điều khiển từ xa chỉ đến các nhà phát triển ngang hàng, không cần phải đẩy và Git sẽ từ chối đẩy đến một kho lưu trữ không trống. Có cách nào để định cấu hình các điều khiển từ xa này là "chỉ tìm nạp" không có địa chỉ hoặc khả năng đẩy không?


4
@sehe, không, bạn không thể. Không có URL đẩy được chỉ định, các lần đẩy sẽ sử dụng URL tìm nạp.
yoyo

Câu trả lời:


191

Tôi không nghĩ bạn có thể xóa URL đẩy, bạn chỉ có thể ghi đè nó thành một cái gì đó không phải là URL kéo. Vì vậy, tôi nghĩ rằng gần nhất bạn sẽ nhận được là một cái gì đó như thế này:

$ git remote set-url --push origin no-pushing
$ git push
fatal: 'no-pushing' does not appear to be a git repository
fatal: The remote end hung up unexpectedly

Bạn đang đặt URL đẩy tới no-pushing, miễn là bạn không có thư mục cùng tên trong thư mục làm việc của mình, git sẽ không thể định vị được. Về cơ bản, bạn đang buộc git sử dụng một vị trí không tồn tại.


14
Yup, bạn sẽ nghĩ "git remote set-url --delete --push. *" Sẽ thực hiện thủ thuật, nhưng nếu bạn xóa url đẩy thì nó sẽ mặc định trở lại url tìm nạp.
yoyo

6
Cá nhân tôi thích sử dụng một cái gì đó như ' BỊ XÓA ', dễ thấy hơn. Nhưng đó chỉ là vấn đề của hương vị.
Pierre-Olivier Vares

@ Pierre-OlivierVares Còn 'DONTPUSH' thì sao?! :)
Ali Shakiba

FYI, sau khi thực hiện việc này, tệp cấu hình git của bạn sẽ trông như thế này: (Lưu ý tùy chọn đẩy mới ) [remote "origin"] fetch = + refs / Heads / *: refs / remotes / origin / * url = ssh: // host / path / to / repo pushurl = ssh: // host / no-push / repo
jaywilliams

1
Tương tự như @ Pierre-OlivierVares, tôi đã đi cùng git remote set-url --push origin -- --read-only--- lưu ý phần bổ sung --để cho phép một tên có dấu gạch ngang hàng đầu. Điều này cảm thấy dễ đọc hơn đối với tôi.
lindes

13

Ngoài việc thay đổi URL đẩy thành một cái gì đó không hợp lệ (ví dụ git remote set-url --push origin DISABLED:), người ta cũng có thể sử dụng pre-pushhook.

Một cách nhanh chóng để dừng lại git pushlà symlink /usr/bin/falseđể trở thành cái móc:

$ ln -s /usr/bin/false .git/hooks/pre-push
$ git push
error: failed to push some refs to '...'

Sử dụng móc cho phép kiểm soát lực đẩy tốt hơn nếu muốn. Xem .git/hooks/pre-push.sampleví dụ về cách ngăn chặn các cam kết đang thực hiện.

Để tránh đẩy vào một nhánh cụ thể hoặc để hạn chế đẩy sang một nhánh duy nhất, điều này trong một ví dụ móc:

$ cat .git/hooks/pre-push
#!/usr/bin/sh

# An example hook script to limit pushing to a single remote.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If this script exits with a non-zero status nothing will be pushed.

remote="$1"
url="$2"

[[ "$remote" == "origin" ]]

Một repo thử nghiệm với nhiều điều khiển từ xa:

$ git remote -v
origin  ../gitorigin (fetch)
origin  ../gitorigin (push)
upstream        ../gitupstream (fetch)
upstream        ../gitupstream (push)

Đẩy đến originđược cho phép:

$ git push origin
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 222 bytes | 222.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../gitorigin
 * [new branch]      master -> master

Không được phép đẩy vào bất kỳ điều khiển từ xa nào khác:

$ git push upstream
error: failed to push some refs to '../gitupstream'

Lưu ý rằng pre-pushtập lệnh hook có thể được sửa đổi thành, trong số những thứ khác, in một thông báo tới stderr nói rằng việc đẩy đã bị vô hiệu hóa.


Ý tưởng tốt! Nếu không có một kịch bản phức tạp hơn, bạn sẽ vô hiệu hóa đẩy cho tất cả các điều khiển từ xa tho.
v01pe

1
@ v01pe có. Tôi đã cập nhật câu trả lời để bao gồm một tập lệnh mẫu. Nó không thực sự cần nhiều để lọc đẩy đến một nhánh. Một vỏ oneliner sẽ làm.
Rodolfo Carvalho

4

Tuyên bố chung "Git sẽ từ chối đẩy đến một kho lưu trữ không trống" là không đúng sự thật. Git sẽ chỉ từ chối đẩy vào một kho lưu trữ từ xa không trống nếu bạn đang cố gắng đẩy các thay đổi nằm trên cùng nhánh với thư mục làm việc đã kiểm tra của kho lưu trữ từ xa.

Câu trả lời này đưa ra một lời giải thích đơn giản: https://stackoverflow.com/a/2933656/1866402

(Tôi đang thêm câu này dưới dạng câu trả lời vì tôi chưa có đủ danh tiếng để thêm nhận xét)


một kho lưu trữ trần không có thư mục làm việc đã kiểm tra, theo định nghĩa. Bạn có thể đẩy đến một chi nhánh cụ thể trên đó.,
Ed Randall

1

Nếu bạn đã có một thiết lập từ xa và chỉ muốn ngăn mình làm điều gì đó như vô tình đẩy trực tiếp đến masterhoặc release/production, bạn có thể ngăn việc này bằng cách sử dụng git config.

# prevent pushing to branch: master
$ git config branch.master.pushRemote no_push

# prevent pushing to branch: release/production
$ git config branch.release/production.pushRemote no_push

Đối với hồ sơ, no_pushkhông phải là một tên đặc biệt. Nó chỉ là tên của bất kỳ chi nhánh không tồn tại. Vì vậy, bạn có thể sử dụng$ git config branch.master.pushRemote create_a_pr_and_do_not_push_directly_to_master và nó sẽ hoạt động tốt.

Thông tin thêm: git-config pushRemote


0

Nếu bạn có quyền kiểm soát kho lưu trữ, bạn có thể đạt được điều này bằng cách sử dụng quyền. Người dùng đang tìm nạp kho lưu trữ không nên có quyền ghi trên kho lưu trữ chính.


Nếu bạn không thể sửa đổi các tệp, bạn cũng không thể tìm nạp các thay đổi mới.
Chỉ là học sinh
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.