Git: ตั้งค่ารีโมตการดึงข้อมูลอย่างเดียวหรือไม่


132

เมื่อฉันทำงานgit remote -vในหนึ่งในที่เก็บ Git ของฉันที่มีการกำหนดค่ารีโมตฉันเห็นว่าแต่ละรีโมตมีทั้งการดึงและการกดสเปค:

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

สำหรับรีโมตที่ชี้ไปที่นักพัฒนาเพียร์ไม่จำเป็นต้องกดและ Git จะปฏิเสธที่จะผลักดันไปยังพื้นที่เก็บข้อมูลที่ไม่ได้เปลือยเลย มีวิธีใดที่จะกำหนดค่ารีโมทเหล่านี้เป็น "แบบดึงข้อมูลอย่างเดียว" โดยไม่มีที่อยู่หรือความสามารถในการพุช


4
@sehe ไม่คุณไม่สามารถ หากไม่มีการระบุ URL การพุชการพุชจะใช้การดึง URL
yoyo

คำตอบ:


191

ฉันไม่คิดว่าคุณจะลบ URL การผลักออกได้คุณสามารถแทนที่มันเพื่อให้เป็นอย่างอื่นที่ไม่ใช่ URL แบบดึงได้ ดังนั้นฉันคิดว่าสิ่งที่ใกล้เคียงที่สุดที่คุณจะได้รับคือ:

$ 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

คุณกำลังตั้งค่าพุช URL ไว้no-pushingซึ่งตราบใดที่คุณไม่มีโฟลเดอร์ชื่อเดียวกันในไดเรกทอรีทำงานของคุณ git จะไม่สามารถค้นหาได้ คุณจำเป็นต้องบังคับให้คอมไพล์ใช้ตำแหน่งที่ไม่มีอยู่จริง


14
ใช่คุณจะคิดว่า "git remote set-url --delete --push. *" จะทำการหลอกลวง แต่ถ้าคุณลบ url ที่กดออกไปมันจะใช้ค่าเริ่มต้นกลับไปที่ url การดึงข้อมูล
yoyo

6
ฉันชอบใช้บางอย่างเช่น ' DISALLOWED ' ซึ่งเห็นได้ชัดกว่า แต่นั่นเป็นเพียงเรื่องของรสนิยม
Pierre-Olivier Vares

@ Pierre-OlivierVares เกี่ยวกับ'DONTPUSH' ! :)
Ali Shakiba

ในปีงบประมาณหลังจากทำเช่นนี้ไฟล์ปรับแต่ง git ของคุณควรมีลักษณะดังนี้: (โปรดสังเกตตัวเลือกpushurlใหม่) [remote "origin"] fetch = + refs / heads / *: refs / remotes / origin / * url = ssh: // host / path / to / repo pushurl = ssh: // host / no-pushing / repo
jaywilliams

1
ในทำนองเดียวกันกับ @ Pierre-OlivierVares ฉันไปด้วยgit remote set-url --push origin -- --read-only--- สังเกตสิ่งพิเศษ--เพื่อให้อนุญาตชื่อที่มีเครื่องหมายขีดกลาง สิ่งนี้รู้สึกว่าอ่านได้มากขึ้นสำหรับฉัน
lindes

13

นอกเหนือจากการเปลี่ยน URL การพุชเป็นสิ่งที่ไม่ถูกต้อง (เช่นgit remote set-url --push origin DISABLED) แล้วยังสามารถใช้pre-pushฮุกได้อีกด้วย

วิธีที่รวดเร็วในการหยุดgit pushคือ symlink /usr/bin/falseเป็น hook:

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

การใช้ตะขอช่วยให้สามารถควบคุมแรงกดได้ละเอียดยิ่งขึ้นหากต้องการ ดู.git/hooks/pre-push.sampleตัวอย่างของวิธีป้องกันการผลักดันการทำงานระหว่างทำ

เพื่อป้องกันการกดไปที่สาขาที่เฉพาะเจาะจงหรือ จำกัด การดันไปยังสาขาเดียวสิ่งนี้ในเบ็ดตัวอย่าง:

$ 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" ]]

repo ทดสอบพร้อมรีโมทหลายตัว:

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

originอนุญาตให้กดเพื่อ:

$ 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

ไม่อนุญาตให้กดไปที่รีโมทอื่น:

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

โปรดทราบว่าpre-pushเบ็ดสคริปต์สามารถปรับเปลี่ยนเป็นเหนือสิ่งอื่นใดพิมพ์ข้อความไปยัง stderr บอกว่าการผลักถูกปิดการใช้งาน


ความคิดที่ดี! หากไม่มีสคริปต์ที่ซับซ้อนมากขึ้นคุณจะต้องปิดการใช้งานการผลักดันสำหรับรีโมททั้งหมด
v01pe

1
@ v01pe ใช่ ฉันได้อัปเดตคำตอบเพื่อรวมสคริปต์ตัวอย่างแล้ว มันไม่จำเป็นต้องใช้อะไรมากนักในการกรองไปยังสาขาเดียว เชลล์ oneliner จะทำ
Rodolfo Carvalho

4

คำสั่งทั่วไป "Git จะปฏิเสธที่จะผลักดันไปยังพื้นที่เก็บข้อมูลที่ไม่ใช่เปลือย" ไม่เป็นความจริง Git จะปฏิเสธที่จะผลักดันไปยังพื้นที่เก็บข้อมูลระยะไกลที่ไม่ได้เปลือยเท่านั้นหากคุณพยายามผลักดันการเปลี่ยนแปลงที่อยู่ในสาขาเดียวกันกับไดเรกทอรีการทำงานที่ได้รับการตรวจสอบจากที่เก็บของที่เก็บระยะไกล

คำตอบนี้ให้คำอธิบายง่ายๆ: https://stackoverflow.com/a/2933656/1866402

(ฉันกำลังเพิ่มสิ่งนี้เป็นคำตอบเพราะฉันยังไม่มีชื่อเสียงพอที่จะเพิ่มความคิดเห็น)


พื้นที่เก็บข้อมูลเปล่าไม่มีไดเรกทอรีการทำงานที่ได้ชำระเงินแล้วตามคำจำกัดความ คุณสามารถกดไปที่สาขาใดสาขาหนึ่งในนั้นได้
Ed Randall

1

หากคุณมีการตั้งค่าระยะไกลอยู่แล้วและต้องการป้องกันตัวเองจากการทำบางสิ่งบางอย่างเช่นการกดไปที่โดยตรงmasterหรือตั้งใจrelease/productionคุณสามารถป้องกันการใช้งาน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

สำหรับบันทึกno_pushไม่ใช่ชื่อพิเศษ มันเป็นเพียงชื่อของสาขาที่ไม่มีอยู่ใด ๆ ดังนั้นคุณสามารถใช้$ git config branch.master.pushRemote create_a_pr_and_do_not_push_directly_to_masterและมันจะทำงานได้ดี

ข้อมูลเพิ่มเติม: git-config pushRemote


0

หากคุณมีสิทธิ์ควบคุมพื้นที่เก็บข้อมูลคุณสามารถทำได้โดยใช้สิทธิ์ ผู้ใช้ที่กำลังดึงที่เก็บไม่ควรมีสิทธิ์เขียนบนที่เก็บต้นแบบ


หากคุณไม่สามารถแก้ไขไฟล์ได้คุณจะไม่สามารถทำการเปลี่ยนแปลงใหม่ได้
เพียงนักเรียน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.