วิธีการผลักดันไปยังพื้นที่เก็บข้อมูล Git ที่ไม่ได้เปลือยเปล่า?


150

ฉันมักจะทำงานบนเซิร์ฟเวอร์ระยะไกลผ่าน ssh (หน้าจอและ vim) ที่ฉันมีที่เก็บ Git บางครั้งฉันไม่ได้ออนไลน์ดังนั้นฉันจึงมีที่เก็บแยกต่างหาก (โคลนจากระยะไกล) บนแล็ปท็อปของฉัน

อย่างไรก็ตามฉันไม่สามารถดึงจากที่เก็บนี้ทางด้านระยะไกลได้เพราะโดยปกติฉันจะอยู่หลังไฟร์วอลล์หรือฉันไม่มี IP สาธารณะ

ฉันอ่านแล้วว่าฉันควรดันไปที่ที่เก็บเปล่า ฉันจะผลักดันการเปลี่ยนแปลงไปยังที่เก็บระยะไกลของฉันได้อย่างไร


เกี่ยวข้อง: stackoverflow.com/questions/12265729/…
prusswan

3
มี repos ระยะไกล 2 อันเปลือยและปกติและใช้ hooks ดูเหมือนยุ่งยาก แต่ตามgit พร้อมและวิกิพีเดียคอมไพล์อย่างเป็นทางการคุณควรเพียงผลักดันไปสู่การซื้อคืนเปลือย นี้อาจเป็นเหตุผลที่โฮสต์ repo คอมไพล์มากที่สุด (เช่น GitHub, Bitbucket) รวมถึงการโพสต์ได้รับตะขอเพื่อให้คุณสามารถโพสต์ไปยัง URL git pull github masterบนเซิร์ฟเวอร์ของคุณซึ่งจะทำงานสคริปต์ที่รันตัวอย่างเช่น
Jake Berger

คำตอบ:


137

receive.denyCurrentBranch updateInstead

ตัวเลือกนี้ถูกเพิ่มใน Git 2.3และทำให้เซิร์ฟเวอร์อัปเดตทรีทำงานของตัวเองถ้ามันสะอาด

ดังนั้นหากคุณมั่นใจว่าคุณยอมรับเสมอก่อนที่จะดึงในพื้นที่และรักษาโครงสร้างการทำงานที่สะอาดบนเซิร์ฟเวอร์ (ซึ่งคุณควรทำเพื่อหลีกเลี่ยงการรวมความขัดแย้ง) ตัวเลือกนี้เป็นทางออกที่ดี

ตัวอย่างการใช้งาน:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

เอาท์พุท:

a
b

เป็นไปได้ไหมที่จะผลักดันโดยไม่สร้าง repo ที่เปลือยเปล่าเหมือนอย่างที่ heroku ทำ
ANINJa

2
@ANinJa ฉันไม่เข้าใจใช่มั้ยนั่นเป็นแบบอย่างของฉันใช่ไหม
Ciro Santilli 郝海东冠状病六四事件法轮功

เป็น--localตัวเลือก?
Yukulélé

@ Yukulélé --localมีผลกระทบเฉพาะไดเรกทอรีปัจจุบัน--globalส่งผลกระทบต่อ Repos คอมไพล์ทั้งหมดที่มีให้ดู~/.gitconfig man git-config
Ciro Santilli 郝海东冠状病六四事件法轮功

1
ขอบคุณ @CiroSantilli 新疆改造中心六四事件法轮功หลังจากอ่านหมอฉันยืนยันว่ามันไม่จำเป็น "(คุณสามารถพูดได้ - เฉพาะ แต่นั่นคือค่าเริ่มต้น)"
Yukulélé

146

ตัวเลือกที่ดีที่สุด

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

ลองดูกรณีที่ง่ายที่สุดและสมมติว่าคุณมีสาขาเดียวในแต่ละ repo: master เมื่อคุณผลักดันไปยัง repo ระยะไกลจากแล็ปท็อปของคุณแทนการกด master -> master, push master -> laptop-master (หรือชื่อที่คล้ายกัน) วิธีนี้การพุชจะไม่ส่งผลต่อสาขาหลักที่เช็คเอาท์ในปัจจุบันใน repo ระยะไกล ในการทำสิ่งนี้จากแล็ปท็อปคำสั่งนั้นค่อนข้างง่าย:

git push origin master:laptop-master

ซึ่งหมายความว่าสาขาหลักของโลคัลจะถูกส่งไปยังสาขาที่ชื่อ "แล็ปท็อป - มาสเตอร์" ในที่เก็บระยะไกล ใน repo ระยะไกลของคุณคุณจะมีสาขาใหม่ที่ชื่อว่า "laptop-master" ที่คุณสามารถผสานเข้ากับ remote master ของคุณเมื่อคุณพร้อม

ตัวเลือกอื่น

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

หากคุณต้องการลองแค่กด master -> master คำสั่งนั้นจะเป็นแค่:

git push origin

แต่เมื่อคุณกลับไปที่ repo ระยะไกลคุณอาจต้องการทำgit reset --hard HEADแผนผังการทำงานให้สอดคล้องกับเนื้อหาที่ถูกผลัก สิ่งนี้อาจเป็นอันตรายได้ได้เพราะหากมีการเปลี่ยนแปลงที่ไม่ผูกมัดในแผนผังงานระยะไกลที่คุณต้องการเก็บไว้ ให้แน่ใจว่าคุณรู้ว่าอะไรคือผลที่ตามมาของสิ่งนี้ก่อนที่คุณจะลองทำ

แก้ไขตั้งแต่ Git 2.3 คุณสามารถใช้ "ดันต่อการปรับใช้" คอมไพล์ผลักดัน: https://github.com/blog/1957-git-2-3-has-been-released แต่การผลักไปยังสาขาที่แยกต่างหากจากนั้นการรวมจะดีกว่าเนื่องจากเป็นการรวมที่เกิดขึ้นจริง


1
เป็นไปได้ไหมที่จะทำการแยกสาขาโดยอัตโนมัติหลังจากกดต้นแบบแล็ปท็อป?
rdoubleui

3
@rdoubleui: คุณหมายถึง "การรวมอัตโนมัติ" หรือไม่? ถ้าใช่ไม่ใช่เป็นไปไม่ได้ที่จะทำการผสานอัตโนมัติเนื่องจากการผสานไม่ได้รับประกันว่าจะเป็นไปได้หากไม่มีการแทรกแซงจากมนุษย์ อาจมีข้อขัดแย้งที่จำเป็นต้องแยกออก
Dan Molding

7
(?) ในรุ่นต่อมาgit config receive.denyCurrentBranch ignoreจะต้องมีการทำมาก่อนที่จะผลักดัน Repos ไม่ใช่เปลือย
prusswan

3
คำตอบที่ดี @DanMoulding ขอบคุณ @rdui: คุณสามารถบันทึกบรรทัดคำสั่งเช่นต่อไปนี้เป็นฟังก์ชั่นทุบตี:git push origin master:laptop-master && ssh user@remotemachine 'cd repos_path && git merge laptop-master'
รวย

@rduiui เพื่อทำการรวมอัตโนมัติคุณสามารถใช้ gitolite และตั้งค่า (ซับซ้อนเล็กน้อย) เพื่อทำให้ non-bare กระทำทุกสิ่งที่สกปรกและกดลงบน gitolite (รุ่นเปลือย) โดยใช้ทริกเกอร์ pre-git หลังจากนั้นหากการรวมไม่สามารถแก้ไขได้ในแบบไม่เปลือยมันจะปฏิเสธการพุชของคุณดังนั้นคุณรู้ว่าคุณต้องดึงก่อนแก้ไขการผสานและดันอีกครั้ง ฉันยังไม่ได้ตั้งค่า แต่ฉันอยู่ในกระบวนการและคิดว่ามันสามารถทำงานได้

17

ฉันอยากจะแนะนำให้มีพื้นที่เก็บข้อมูลเปล่าและ repos ทำงาน (ไม่เปลือย) ท้องถิ่นในเซิร์ฟเวอร์ของคุณ คุณสามารถผลักดันการเปลี่ยนแปลงจากแล็ปท็อปไปยังเซิร์ฟเวอร์ repo เปล่าแล้วดึงจาก repo ที่เปลือยไปยังเซิร์ฟเวอร์ repo ที่ทำงาน เหตุผลที่ฉันพูดแบบนี้เป็นเพราะคุณอาจมีสาขาที่สมบูรณ์ / ไม่สมบูรณ์จำนวนมากในเซิร์ฟเวอร์ซึ่งคุณจะต้องการทำซ้ำบนแล็ปท็อป

วิธีนี้คุณไม่ต้องกังวลเกี่ยวกับสถานะของสาขาเช็คเอาต์บน repo เซิร์ฟเวอร์ที่ทำงานในขณะที่ผลักดันการเปลี่ยนแปลงไปยังเซิร์ฟเวอร์


4

อีกทางเลือกหนึ่งคือการตั้งค่าอุโมงค์ย้อนกลับ SSH เพื่อให้คุณสามารถดึงแทนการกด

# start the tunnel from the natted box you wish to pull from (local)
$ ssh -R 1234:localhost:22 user@remote

# on the other box (remote)
$ git remote add other-side ssh://user@localhost:1234/the/repo
$ git pull other-side

และหากคุณต้องการให้อุโมงค์ทำงานในพื้นหลัง

$ ssh -fNnR 1234:localhost:22 user@remote

1

คุณทำได้:

$git config --bool core.bare true

สิ่งนี้สามารถทำได้ในพื้นที่เก็บข้อมูลเปลือยหรือส่วนกลางเพื่อที่จะยอมรับไฟล์ใด ๆ ที่ถูกผลักจากที่เก็บไม่เปลือย หากคุณทำเช่นนี้ในพื้นที่เก็บข้อมูลที่ไม่ได้เปลือยเราจะไม่สามารถผลักดันไฟล์ใด ๆ จากพื้นที่เก็บข้อมูลที่ไม่ได้เปลือยไปยังพื้นที่ว่างเปล่า

หากคุณกำลังฝึกฝน GIT โดยการสร้าง repo ส่วนกลางและไม่ใช่เปลือยในพีซีมันอาจไม่แสดงไฟล์ที่ถูกพุชในพีซีบางเครื่อง แต่มันถูกพุช คุณสามารถตรวจสอบได้โดยใช้

$git log ใน repo กลาง

นอกเหนือจากถ้าคุณกดไปที่ GitHub มันจะแสดงไฟล์ที่นั่น

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