วิธีการสร้างที่เก็บ Git ระยะไกลจากภายในเครื่อง


243

ฉันมีที่เก็บ Git ในพื้นที่ ฉันต้องการทำให้พร้อมใช้งานบนรีโมตเซิร์ฟเวอร์ที่เปิดใช้งาน ssh ฉันจะทำสิ่งนี้ได้อย่างไร

คำตอบ:


288

ผมคิดว่าคุณทำที่เก็บเปลือยในด้านระยะไกลgit init --bareเพิ่มด้านระยะไกลเป็นติดตามผลัก / ดึงสำหรับพื้นที่เก็บข้อมูลท้องถิ่นของคุณ ( git remote add origin URL) git push origin masterแล้วในประเทศที่คุณเพียงแค่พูดว่า ตอนนี้ที่เก็บอื่น ๆ สามารถpullจากที่เก็บระยะไกล


@Nips: ใช่ถูกต้องขอโทษ คุณผลักสาขาของแต่ละบุคคลแน่นอน!
Kerrek SB

ถ้าฉันใช้ GUI ล่ะจะเป็นอย่างไร ฉันจะตั้งค่าเซิร์ฟเวอร์สำหรับที่เก็บทั้งหมดและพีซีแต่ละเครื่องบนเครือข่ายเดียวกันเชื่อมต่อกับมันได้อย่างไร
SearchForKnowledge

4
ถ้าgit push origin masterล้มเหลวด้วยข้อผิดพลาด "ไม่พบที่เก็บ" ลองgit update-server-infoที่ด้านระยะไกลที่คุณทำgit init --bare
HongKilDong

7
@ KerrekSB เป็นไปได้ที่จะสร้าง repo เปล่าบนเซิร์ฟเวอร์โดยอัตโนมัติทันทีที่ฉันรัน git push master origin บนเครื่องของฉัน
ANINJa

@HongKilDong ฉันพยายามgit update-server-infoแต่ฉันได้รับข้อผิดพลาด fatal: Unable to look up Volumes (port 9418) (nodename nor servname provided, or not known)
Nayef

81

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

$ git clone --bare my_project my_project.git
Initialized empty Git repository in /opt/projects/my_project.git/

คำสั่งนี้ใช้พื้นที่เก็บข้อมูล Git ด้วยตัวเองโดยไม่มีไดเรกทอรีทำงานและสร้างไดเรกทอรีเฉพาะสำหรับมันเพียงอย่างเดียว

ตอนนี้คุณมีสำเนาของที่เก็บเปลือยของคุณแล้วสิ่งที่คุณต้องทำก็คือวางไว้บนเซิร์ฟเวอร์และตั้งค่าโปรโตคอลของคุณ สมมติว่าคุณตั้งค่าเซิร์ฟเวอร์ที่เรียกgit.example.comว่าคุณมีการเข้าถึง SSH และคุณต้องการเก็บที่เก็บ Git ทั้งหมดของคุณไว้ใน/opt/gitไดเรกทอรี คุณสามารถตั้งค่าพื้นที่เก็บข้อมูลใหม่ของคุณโดยการคัดลอกพื้นที่เก็บข้อมูลเปลือยของคุณมากกว่า:

$ scp -r my_project.git user@git.example.com:/opt/git

ณ จุดนี้ผู้ใช้รายอื่นที่มีการเข้าถึง SSH ไปยังเซิร์ฟเวอร์เดียวกันซึ่งมีการเข้าถึงการอ่าน/opt/gitไดเรกทอรีสามารถโคลนที่เก็บของคุณโดยการเรียกใช้

$ git clone user@git.example.com:/opt/git/my_project.git

หากผู้ใช้ SSHs เข้าสู่เซิร์ฟเวอร์และมีสิทธิ์ในการเขียนไปยัง/opt/git/my_project.gitไดเรกทอรีพวกเขาจะมีการเข้าถึงแบบพุชโดยอัตโนมัติ Git จะเพิ่มสิทธิ์การเขียนกลุ่มลงในที่เก็บอย่างถูกต้องโดยอัตโนมัติหากคุณเรียกใช้คำสั่ง git init พร้อม--sharedตัวเลือก

$ ssh user@git.example.com
$ cd /opt/git/my_project.git
$ git init --bare --shared

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


6
scpปัญหาการทำงานได้ดีขึ้น IMO init --bareในทางปฏิบัติกว่า มันยังรู้สึกแฮ็คที่น่าเกลียดถึงแม้ว่าจะทำการโคลนในเครื่องก่อนจากนั้นก็คัดลอกไปยังเซิร์ฟเวอร์ ... หวังว่า git จะมีคำสั่งให้ทำในครั้งเดียว
leftaroundabout

1
+1 รายการนี้เพราะ--sharedทำงานสำหรับฉัน ฉันสงสัยว่าจะเกิดอะไรขึ้นถ้าคุณใช้git init --sharedโดยไม่ต้องทำการ--bare...
icedwater

1
สร้างพื้นที่เก็บข้อมูลเปล่าภายในเครื่องและการscpที่รีโมตทำงานได้ดีขึ้นหากรีโมตไม่รองรับgit init --bare(เช่นกรณีของฉันด้วย git 1.5.5, 2008) ฉันคิดว่ามันน่าจะใช้ได้แม้ว่ารีโมตจะไม่มีคอมไพล์เลย
Yaroslav Nikitenko

1
การอ้างอิง: git-scm.com/book/en/v1/…
berbt

1
หมายเหตุเล็กน้อย: scp ขั้นตอนของโซลูชันถูกต้อง แต่ใช้งานได้หากผู้ใช้รีโมตมีเชลล์ปกติหากผู้ใช้ใช้ git-shell มันจะไม่ทำงาน
user1708042

9

หมายเหตุสำหรับผู้ที่สร้างสำเนาโลคัลบน Windows และต้องการสร้างที่เก็บแบบรีโมตที่สอดคล้องกันบนระบบ Unix-line ที่ไฟล์ข้อความรับการจบ LF บนโคลนเพิ่มเติมโดยนักพัฒนาบนระบบที่คล้าย Unix แต่ CRLF สิ้นสุดใน Windows

หากคุณสร้างที่เก็บ Windows ของคุณก่อนที่จะตั้งค่าการแปลบรรทัดสุดท้ายแสดงว่า คุณมีปัญหา การตั้งค่าเริ่มต้นของ Git นั้นไม่มีการแปลดังนั้นชุดการทำงานของคุณจึงใช้ CRLF แต่ที่เก็บของคุณ (เช่นข้อมูลที่เก็บไว้ภายใต้. git) ได้บันทึกไฟล์เป็น CRLF ด้วย

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

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

ฉันไม่แน่ใจว่ามีวิธีง่าย ๆ ที่จะบอกได้ว่าคุณลงท้ายด้วยบรรทัดใดในที่เก็บ Windows ของคุณ - ฉันเดาว่าคุณสามารถทดสอบได้โดยการตั้งค่า core.autocrlf = false แล้วทำการโคลน (ถ้า repo มี LF ลงท้ายด้วย) โคลนจะมี LF ด้วย)


5

มีความแตกต่างที่น่าสนใจระหว่างสองโซลูชันยอดนิยมด้านบน:

  1. หากคุณสร้างที่เก็บเปลือยเช่นนี้:

    cd / outside_of_any_repo
    mkdir my_remote.git
    cd my_remote.git
    git init --bare
    

แล้ว

cd  /your_path/original_repo
git remote add origin /outside_of_any_repo/my_remote.git
git push --set-upstream origin master

จากนั้นคอมไพล์ตั้งค่าใน 'original_repo' ด้วยความสัมพันธ์นี้:

original_repo origin --> /outside_of_any_repo/my_remote.git/

กับหลังเป็นระยะไกลอัปสตรีม และรีโมตอัพสตรีมไม่มีรีโมตอื่นในการกำหนดค่า

  1. อย่างไรก็ตามหากคุณทำอย่างอื่น:

    (จากในไดเรกทอรี original_repo)
    ซีดี ..
    git clone - เปลือย original_repo /outside_of_any_repo/my_remote.git
    

จากนั้น 'my_remote.git' จะปิดท้ายด้วยการกำหนดค่าโดยให้ 'ต้นกำเนิด' ชี้ไปที่ 'original_repo' เป็นรีโมตโดยใช้ remote.origin.url เท่ากับพา ธ ของไดเร็กทอรีในเครื่องซึ่งอาจไม่เหมาะสมถ้ามันถูกย้าย ไปยังเซิร์ฟเวอร์

ในขณะที่การอ้างอิง "ระยะไกล" นั้นง่ายต่อการกำจัดในภายหลังหากไม่เหมาะสม 'original_repo' ยังคงต้องตั้งค่าให้ชี้ไปที่ 'my_remote.git' เป็นรีโมตสตรีมแบบอัพสตรีม ที่จะแบ่งปันจาก) ดังนั้นในทางเทคนิคคุณสามารถไปถึงผลลัพธ์เดียวกันด้วยขั้นตอนเพิ่มเติมอีกสองสามวิธีด้วยวิธี # 2 แต่ดูเหมือนว่า # 1 จะเป็นวิธีที่ตรงกว่าในการสร้าง "repo ส่วนกลางที่แชร์กันเปล่า" ซึ่งมีต้นกำเนิดจากโลคอลท้องถิ่นซึ่งเหมาะสำหรับการย้ายไปยังเซิร์ฟเวอร์โดยมีขั้นตอนน้อยลง ฉันคิดว่ามันขึ้นอยู่กับบทบาทที่คุณต้องการให้ repo ระยะไกลเล่น (และใช่สิ่งนี้ขัดแย้งกับเอกสารที่นี่ )

Caveat: ฉันได้เรียนรู้ข้างต้น (ที่เขียนนี้ในช่วงต้นเดือนสิงหาคม 2019) โดยทำการทดสอบในระบบท้องถิ่นของฉันกับ repo จริงแล้วทำการเปรียบเทียบแบบทีละไฟล์ระหว่างผลลัพธ์ แต่! ฉันยังคงเรียนรู้ดังนั้นอาจมีวิธีที่ถูกต้องมากขึ้น แต่การทดสอบของฉันได้ช่วยฉันสรุปว่า # 1 เป็นวิธีที่ฉันชอบในปัจจุบัน


4

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

คุณสามารถสร้างคลังเก็บคอมไพล์เปลือยด้วยรหัสต่อไปนี้:

$ git clone --bare /path/to/project project.git

ตัวเลือกหนึ่งสำหรับการมีที่เก็บ git ระยะไกลกำลังใช้โปรโตคอล SSH:

โปรโตคอลการขนส่งทั่วไปสำหรับ Git เมื่อการโฮสต์ด้วยตนเองมีค่ามากกว่า SSH นี่เป็นเพราะการเข้าถึง SSH ไปยังเซิร์ฟเวอร์นั้นถูกตั้งค่าไว้แล้วในสถานที่ส่วนใหญ่ - และถ้าไม่ใช่ก็ทำได้ง่าย SSH เป็นโปรโตคอลเครือข่ายที่ผ่านการตรวจสอบและเนื่องจากเป็นแพร่หลายจึงเป็นเรื่องง่ายในการตั้งค่าและใช้งาน

ในการโคลนที่เก็บ Git บน SSH คุณสามารถระบุssh://URL ดังนี้:

$ git clone ssh://[user@]server/project.git

หรือคุณสามารถใช้ไวยากรณ์เหมือน scp ที่สั้นกว่าสำหรับโปรโตคอล SSH:

$ git clone [user@]server:project.git

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

ข้อดี

ข้อดีของการใช้ SSH นั้นมีมากมาย อันดับแรก SSH นั้นค่อนข้างง่ายในการติดตั้ง - SSH daemons เป็นเรื่องธรรมดาผู้ดูแลระบบเครือข่ายหลายคนมีประสบการณ์กับพวกเขาและการกระจาย OS หลาย ๆ ตัวถูกตั้งค่าไว้กับพวกเขาหรือมีเครื่องมือในการจัดการ ถัดไปการเข้าถึง SSH นั้นปลอดภัย - การถ่ายโอนข้อมูลทั้งหมดจะถูกเข้ารหัสและรับรองความถูกต้อง สุดท้ายเช่นเดียวกับ HTTPS, Git และโปรโตคอลท้องถิ่น SSH มีประสิทธิภาพทำให้ข้อมูลมีขนาดกะทัดรัดที่สุดเท่าที่จะทำได้ก่อนที่จะถ่ายโอน

ข้อเสีย

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

สำหรับข้อมูลเพิ่มเติมให้ตรวจสอบการอ้างอิง: Git บนเซิร์ฟเวอร์ - โปรโตคอล


3

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

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

ตรวจสอบที่นี่ - https://github.com/skbobade/ocgi


-3

โดยปกติคุณสามารถตั้งค่า repo คอมไพล์เพียงแค่ใช้initคำสั่ง

git init

ในกรณีของคุณมี repo บนรีโมทที่มีอยู่แล้ว ขึ้นอยู่กับวิธีที่คุณเข้าถึง repo ระยะไกลของคุณ (ด้วยชื่อผู้ใช้ภายใน url หรือคีย์ ssh ที่จัดการการตรวจสอบ) ใช้เพียงcloneคำสั่ง:

git clone git@[my.url.com]:[git-repo-name].git

นอกจากนี้ยังมีวิธีอื่นในการโคลน repo วิธีนี้คุณเรียกว่าหากคุณมีการตั้งค่าคีย์ ssh บนเครื่องของคุณซึ่งตรวจสอบการดึงที่เก็บของคุณ มีชุดค่าผสมอื่น ๆ ของ url หากคุณต้องการใส่รหัสผ่านและชื่อผู้ใช้ของคุณภายในเพื่อเข้าสู่พื้นที่เก็บข้อมูลระยะไกลของคุณ


1
แดกดันเป็นอย่างไร .... ใครบางคนเพิ่งลบคำตอบในวันนี้และตอนนี้ฉันกำลังดิ้นรนกับการผลักดันไฟล์ของฉัน ดูเหมือนว่าฉันต้องการออกกำลังกายคอมไพล์เพื่อคอมไพล์มันอีกครั้ง!
Alex Cio

7
ฉันคิดว่าปัญหาคือ OP ต้องการวิธีแก้ปัญหาเพื่อสร้าง repo ระยะไกลบนเซิร์ฟเวอร์ ssh แต่คุณอธิบายวิธีสร้าง repo ในเครื่องจากเซิร์ฟเวอร์ ssh ระยะไกล คุณไม่ได้ตอบคำถาม (ไม่ใช่ตอนที่ฉันกำลังลง)
เตอร์ - Reinstate Monica
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.