การปฏิบัติที่ดีที่สุดสำหรับการวางหลายโครงการในที่เก็บ git คืออะไร? [ปิด]


188

ด้วยเหตุผลบางอย่างฉันมีเพียงหนึ่งที่เก็บที่จะใช้
แต่ฉันมีหลายโครงการรวมถึงjavaโครงการphp scriptsและAndroidโครงการแอพ

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

ใครสามารถบอกวิธีปฏิบัติที่ดีที่สุดในการแก้ปัญหาได้


1
วิธีแก้ปัญหาที่เป็นไปได้คือstackoverflow.com/questions/5514739/…หรือstackoverflow.com/a/7931825/828197
Ragnarokkr

2
คุณไม่ได้โดดเดี่ยว. ฉันมีกรณีที่คล้ายกันกับ repos ของฉันที่ฉันใช้เพื่อการเรียนรู้ (ตัวอย่าง: github.com/hopbit/java-sandbox ) ฉันไม่ต้องการที่จะสร้าง repo ใหม่เพื่อลองตัวอย่างสำหรับหนังสือ / กวดวิชาใหม่ทุกเล่มที่ฉันเริ่มอ่าน ...
ŁukaszSiwiński

เหตุผลหนึ่งที่คุณต้องการทำคือถ้าคุณมีหนึ่งโครงการที่เป็นรหัสผลิตภัณฑ์ที่คุณปรับใช้กับสภาพแวดล้อมรันไทม์เช่นการทดสอบหรือการผลิต โครงการที่สองคือแอปพลิเคชันที่ระบบทดสอบ (ตัวอย่าง BDD) โครงการแรก มีความสัมพันธ์ที่ใกล้ชิดระหว่างโครงการทั้งสองนี้และตอนนี้คุณสามารถรักษา / อ้างอิงทั้งโครงการโดยใช้ที่เก็บเดียว
Lance ใจดี

สรุปดังนี้"Git ไม่มีความคิดว่าสิ่งเหล่านี้เป็นส่วนหนึ่งของโครงการเดียวกันหรือแตกต่างกัน"
ahmednabil88

คำตอบ:


198

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

โซลูชันที่ 1

พื้นที่เก็บข้อมูลเดียวสามารถมีหลายอิสระสาขาที่เรียกว่าสาขาเด็กกำพร้า สาขาเด็กกำพร้าแยกจากกันอย่างสิ้นเชิง; พวกเขาไม่แบ่งปันประวัติศาสตร์

git checkout --orphan BRANCHNAME

สิ่งนี้จะสร้างสาขาใหม่ซึ่งไม่เกี่ยวข้องกับสาขาปัจจุบันของคุณ แต่ละโครงการควรอยู่ในสาขาที่เป็นของตนเอง

ตอนนี้ไม่ว่าจะด้วยเหตุผลใด Git ก็ต้องทำความสะอาดหลังจากเช็คเอาต์ของเด็กกำพร้า

rm .git/index
rm -r *

ตรวจสอบให้แน่ใจว่าได้ทำทุกสิ่งก่อนที่จะลบ

เมื่อสาขาเด็กกำพร้าสะอาดคุณสามารถใช้งานได้ตามปกติ

โซลูชันที่ 2

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

# repo 1
git push origin master:master-1

# repo 2
git push origin master:master-2

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

6
ฉันไม่แน่ใจว่าฉันเข้าใจวิธีแก้ปัญหา 2 คุณกำลังบอกว่าคุณยอมรับไฟล์. git ทั้งหมดลงใน repo หลัก git หรือไม่? อะไรคือความแตกต่างระหว่างการใช้กิ่งที่กำพร้าหลายกับ vs การใช้หลายกิ่ง
Nate

14
@Nate สิ่งที่เขาพูดคือ: ทำที่เก็บในเครื่องสองอันแยกกันจากนั้นดันทั้งสองไปที่ที่เก็บระยะไกลเดียวกันบน GitHub
The Guy with The Hat

1
ขอบคุณ @TheGuywithTheElfHat ตอนนี้ฉันดูอีกครั้ง (9 เดือนต่อมา) ดูเหมือนว่าฉันจะชัดเจน โซลูชันที่ 2 ยังคงสร้างกิ่งที่กำพร้า แต่ฉันเห็นได้ว่าวิธีนี้จัดการได้ง่ายขึ้นอย่างไร
เนท

21
โซลูชัน 2 ต้องการคำอธิบายเพิ่มเติม
eC Droid

19

โซลูชันที่ 3

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

เริ่มต้นโครงการทั้งหมดจากหนึ่งไดเรกทอรีว่างเปล่ามุ่งมั่น

อย่าคาดหวังสิ่งมหัศจรรย์จากโซลูชันนี้ อย่างที่ฉันเห็นคุณมักจะมีปัญหากับไฟล์ที่ไม่ได้ติดตาม Git ไม่มีเงื่อนงำจริง ๆ ว่าจะทำอย่างไรกับพวกเขาดังนั้นหากมีไฟล์กลางที่สร้างโดยคอมไพเลอร์และถูกละเว้นโดยไฟล์. gitignore ของคุณมีโอกาสที่พวกเขาจะถูกปล่อยให้แขวนอยู่ในบางครั้งถ้าคุณลองเปลี่ยนอย่างรวดเร็ว ระหว่าง - ตัวอย่าง - โครงการซอฟต์แวร์ของคุณและโครงการวิทยานิพนธ์ปริญญาเอก

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

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

สร้างพื้นที่เก็บข้อมูลว่างเปล่า

cd some_empty_directory
git init
touch .gitignore
git add .gitignore
git commit -m empty
git tag EMPTY

เริ่มโครงการของคุณจากที่ว่างเปล่า

ทำงานในโครงการหนึ่ง

git branch software EMPTY
git checkout software
echo "array board[8,8] of piece" > chess.prog

git add chess.prog 
git commit -m "chess program"

เริ่มโครงการอื่น

เมื่อใดก็ตามที่คุณต้องการ.

git branch thesis EMPTY
git checkout thesis
echo "the meaning of meaning" > philosophy_doctorate.txt
git add philosophy_doctorate.txt 
git commit -m "Ph.D"

สลับไปมา

ย้อนกลับไปข้างหน้าระหว่างโครงการเมื่อใดก็ตามที่คุณต้องการ ตัวอย่างนี้กลับไปที่โครงการซอฟต์แวร์หมากรุก

git checkout software
echo "while not end_of_game do make_move()" >> chess.prog
git add chess.prog 
git commit -m "improved chess program"

ไฟล์ที่ไม่ได้ติดตามจะน่ารำคาญ

อย่างไรก็ตามคุณจะรำคาญไฟล์ที่ไม่ได้ติดตามเมื่อทำการสลับระหว่างโครงการ / สาขา

touch untracked_software_file.prog
git checkout thesis 
ls
    philosophy_doctorate.txt  untracked_software_file.prog

มันไม่ใช่ปัญหาที่ผ่านไม่ได้

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

git checkout EMPTY 
ls
    untracked_software_file.prog
rm -r *
    (directory is now really empty, apart from the repository stuff!)
git checkout thesis
ls
    philosophy_doctorate.txt

โดยตรวจสอบให้แน่ใจว่าไดเรกทอรีว่างเปล่าก่อนที่จะตรวจสอบโปรเจ็กต์ใหม่ของเราเราทำให้แน่ใจว่าไม่มีไฟล์ที่ไม่ได้ติดตามการแขวนจากโปรเจ็กต์อื่น

การปรับแต่ง

$ GIT_AUTHOR_DATE='2001-01-01:T01:01:01' GIT_COMMITTER_DATE='2001-01-01T01:01:01' git commit -m empty

หากระบุวันที่เดียวกันเมื่อใดก็ตามที่ยอมรับที่เก็บข้อมูลที่ว่างการสร้างที่เก็บที่ว่างเปล่าที่สร้างขึ้นเองนั้นสามารถมีรหัส SHA1 เดียวกันได้ สิ่งนี้อนุญาตให้ที่เก็บสองแห่งถูกสร้างขึ้นอย่างอิสระจากนั้นผสานเข้าด้วยกันในทรีเดียวที่มีรูททั่วไปในหนึ่งที่เก็บในภายหลัง

ตัวอย่าง

# Create thesis repository. 
# Merge existing chess repository branch into it

mkdir single_repo_for_thesis_and_chess
cd single_repo_for_thesis_and_chess
git init
touch .gitignore
git add .gitignore
GIT_AUTHOR_DATE='2001-01-01:T01:01:01' GIT_COMMITTER_DATE='2001-01-01:T01:01:01' git commit -m empty
git tag EMPTY
echo "the meaning of meaning" > thesis.txt
git add thesis.txt
git commit -m "Wrote my PH.D"
git branch -m master thesis

# It's as simple as this ...
git remote add chess ../chessrepository/.git
git fetch chess chess:chess

ผลลัพธ์

ไดอะแกรมของที่เก็บที่ถูกผสาน

ใช้ไดเรกทอรีย่อยต่อโครงการหรือไม่

นอกจากนี้ยังอาจช่วยถ้าคุณเก็บโครงการของคุณในไดเรกทอรีย่อยที่เป็นไปได้เช่นแทนที่จะมีไฟล์

chess.prog
philosophy_doctorate.txt 

มี

chess/chess.prog
thesis/philosophy_doctorate.txt 

chess/untracked_software_file.progในกรณีนี้ไฟล์ซอฟต์แวร์ของคุณจะไม่ได้ติดตาม เมื่อทำงานในthesisไดเรกทอรีคุณไม่ควรถูกรบกวนโดยไฟล์โปรแกรมหมากรุกที่ไม่ได้ติดตามและคุณอาจพบโอกาสที่คุณสามารถทำงานได้อย่างมีความสุขโดยไม่ต้องลบไฟล์ที่ไม่ได้ติดตามจากโครงการอื่น

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

ชื่อสาขาสามารถมีอักขระ '/'

ดังนั้นคุณอาจต้องการตั้งชื่อสาขาของคุณเช่น

project1/master
project1/featureABC
project2/master
project2/featureXYZ

9

git submodulesผมจะใช้

ดูที่นี่Git repository ใน Git repository

ตามกุมภาพันธ์ 2019 ฉันอยากจะแนะนำ Monorepos


5
"ฉันมีที่เก็บใช้เพียงแห่งเดียวเท่านั้น" คุณสนใจที่จะอธิบายว่าคุณจะเก็บ submodules หลาย ๆ อันในที่เก็บเดียวกันได้อย่างไร
อีวาน

4
git submodule add [url to git repo]- git-scm.com/book/en/v2/Git-Tools-Submodules
prasanthv

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