วิธีที่ดีที่สุดในการ“ git clone” ในโฟลเดอร์ที่มีอยู่คืออะไร?


479

ฉันมีสำเนาการทำงานของโครงการโดยไม่มีข้อมูลเมตาควบคุมแหล่งที่มา ตอนนี้ฉันต้องการทำคอมไพล์ git-clone ในโฟลเดอร์นี้และทำการเปลี่ยนแปลงในเครื่องของฉัน

git-clone ไม่อนุญาตให้ฉันโคลนเข้าไปในโฟลเดอร์ที่มีอยู่ การปฏิบัติที่ดีที่สุดที่นี่คืออะไร?


4
การอภิปรายที่ดีกว่าที่นี่
cdunn2001

1
@MEM ฉันชอบคำตอบนี้มากกว่า แต่ก็ใช้งานได้ ... stackoverflow.com/a/5377989/11236
ripper234

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

1
นี่เป็นเรื่องที่บ้ามากที่ไม่มีวิธีที่ดีในการทำเช่นนั้นมีประโยชน์ดังนั้นเมื่อคุณต้องการโคลน projet ไปยังโฟลเดอร์แชร์ที่เมานท์
โทมัส Decaux

คำตอบ:


558

ซึ่งสามารถทำได้โดยการโคลนไปยังไดเรกทอรีใหม่แล้วย้าย.gitไดเรกทอรีไปยังไดเรกทอรีที่มีอยู่ของคุณ

หากไดเรกทอรีที่มีอยู่ของคุณชื่อ "รหัส"

git clone https://myrepo.com/git.git temp
mv temp/.git code/.git
rm -rf temp

สิ่งนี้สามารถทำได้โดยไม่ต้องชำระเงินระหว่างคำสั่ง clone ข้อมูลเพิ่มเติมสามารถพบได้ที่นี่


25
โปรดทราบว่านี่เป็นคำแนะนำจาก @ChrisJohnsen ที่เขาทิ้งไว้ในความคิดเห็น ฉันพบว่ามีประโยชน์และต้องการทำให้เป็นคำตอบจริง คริสถ้าคุณตอบคำถามฉันจะลบอันนี้อย่างมีความสุข
amicitas

2
ขอบคุณ! แม้ว่าขั้นตอนนี้จะไม่เหมือนกับ "การชำระเงิน git -." คิดว่าไฟล์ทั้งหมดจะถูกลบใช่ไหม?
mrooney

2
ไม่ตราบใดที่คุณใช้git cloneเป็นคำสั่งแรกไม่จำเป็นต้องมีคำสั่งชำระเงินเพิ่มเติม หากคุณใช้บางอย่างเช่นgit clone --no-checkoutในขั้นตอนแรกแทนหลังจากย้ายไดเรกทอรี. git แล้วคุณจะต้องใช้git reset HEADเพื่อบอก git ว่าไฟล์ยังไม่ถูกลบ
amicitas

3
ฉันจะเพิ่มนี้เป็นขั้นตอนที่สาม: mv temp / .gitignore code / .gitignore
Daniel Aranda

1
@KalpeshSoni git statusใช่คอมไพล์จะรู้เกี่ยวกับการแก้ไขไฟล์และมันจะเป็นไปได้ที่จะเห็นการเปลี่ยนแปลงโดยใช้คอมไพล์ปกติคำสั่งเช่น
amicitas

284

อย่าโคลนดึงข้อมูลแทน ในธุรกรรมซื้อคืน:

git init
git remote add origin $url_of_clone_source
git fetch origin
git checkout -b master --track origin/master # origin/master is clone's default

จากนั้นคุณสามารถรีเซ็ตต้นไม้เพื่อให้ได้สิ่งที่คุณต้องการ:

git reset origin/master # or whatever commit you think is proper...

และคุณเป็นเหมือนโคลน

คำถามที่น่าสนใจที่นี่ (และคำถามที่ไม่มีคำตอบ): วิธีการค้นหาว่าต้นไม้ที่เปลือยเปล่าของคุณนั้นมีพื้นฐานมาจากไหน


7
ฉันไม่ได้เป็นแฟนของสิ่งนี้ - ต่อการตั้งค่า github "เคล็ดลับ: ผู้ช่วยหนังสือรับรองทำงานเฉพาะเมื่อคุณโคลน URL ที่เก็บ HTTPS" ฉันใช้ผู้ช่วยประจำตัวและสิ่งนี้ทำให้ฉันลงหลุมกระต่ายที่ไร้ผลมานาน
แอนดรู

5
'git checkout - track กำเนิด / master' ทำงานได้ดีแทน 'git checkout -b master - track กำเนิด / master' ไม่จำเป็นต้องรีเซ็ต
felipecrp

1
ฉันได้รับข้อผิดพลาด "ข้อผิดพลาด Git: ไฟล์ต้นไม้ทำงานที่ไม่ได้ติดตามต่อไปนี้จะถูกเขียนทับโดยเช็คเอาต์" ดังนั้นฉันจึงเพิ่มคำสั่งนี้: git clean -d -fx ""
shakaran

1
ไม่แนะนำให้เลือกอย่างแน่นอนในทุกสถานการณ์ แต่นี่คือสิ่งที่ฉันต้องการ
Chaim Eliyah

1
@ AndreasKrey คำตอบเดิมของคุณ (ซึ่งฉันเข้าไปในประวัติการแก้ไขเพื่อดู) ทำสิ่งที่ต้องการโดยคำถาม (และฉัน) barfs ตอบรับการเปลี่ยนแปลงที่เช็คเอาต์โดยไม่ใช้ -f ซึ่งละทิ้งการเปลี่ยนแปลงในท้องถิ่นและเป็นสิ่งที่ฉันไม่ต้องการ ถ้าฉันเป็นคุณฉันจะลองย้อนกลับไปที่คำตอบเดิมของคุณ
Ajean

77

ต่อไปนี้ฉันทำเพื่อชำระเงินที่สาขาหลักในไดเรกทอรีที่มีอยู่:

git init
git remote add origin [my-repo]
git fetch
git checkout origin/master -ft

2
นี่เป็นคำตอบที่ยอดเยี่ยมและหลีกเลี่ยงการ จำกัด ระบบไฟล์ใด ๆ
user151841

1
นี่ควรเป็นคำตอบที่ยอมรับได้เนื่องจากไม่ใช่แฮ็ค
php_nub_qq

5
ที่จริงแล้วสิ่งนี้ทำในสิ่งที่ OP (และฉัน) ไม่ต้องการซึ่งเป็นการเขียนทับการเปลี่ยนแปลงในท้องถิ่น
Ajean

upvote ของฉันระบุว่าสิ่งนี้ช่วยฉันไม่ใช่ว่าเป็นคำตอบที่ดีที่สุดสำหรับคำถามของ OP
TecBrat

2
บางคนสามารถอธิบายได้ว่าทำไมจึงใช้การ-tตั้งค่าสถานะที่นี่
jfowkes

38

ฉันต้องการgit cloneไปยังไดเรกทอรีใหม่และคัดลอกเนื้อหาของไดเรกทอรีที่มีอยู่ไปยังโคลนใหม่


4
หากคุณทำเช่นนั้นตรวจสอบให้แน่ใจว่าคุณได้ตรวจสอบความแตกต่างก่อนที่จะทำอย่างระมัดระวัง - นี่เป็นกรณีคลาสสิคแน่นอนที่คุณสามารถย้อนกลับการเปลี่ยนแปลงที่เกิดขึ้นใน repo ต้นทางโดยไม่ได้ตั้งใจตั้งแต่เมื่อใดก็ตามที่คุณได้รับสำเนาการทำงาน ในสำเนาการทำงานเพื่อหาการเปลี่ยนแปลงที่คุณทำกับสิ่งที่มันเป็นก่อนที่คุณจะเริ่มทำการเปลี่ยนแปลงเพื่อรวมเข้ากับการเปลี่ยนแปลงอื่น ๆ ที่เกิดขึ้นใน repo ฉันเคยเห็นสิ่งนี้เกิดขึ้นครั้งแล้วครั้งเล่าในสถานการณ์เช่นนี้จนถึงจุดที่ฉัน "ท้อแท้อย่างยิ่ง" ตัวเองและคนที่ฉันทำงานด้วยจากที่เคยทำมัน
Ben Clifford

72
git clone wherever tmp && git mv tmp/.git . && rm -rf tmpกล่าวอีกนัยหนึ่งการย้าย.gitdir ออกจากโคลนชั่วคราวนั้นดูง่ายกว่าการทำความสะอาดแผนผังการทำงานของโคลนและคัดลอกไฟล์ที่มีอยู่ที่นั่น
Chris Johnsen

1
@ChrisJohnsen: คุณควรจะได้ทำให้มันเป็นคำตอบที่แน่นอนวิธีที่ดีที่สุดที่จะทำมัน IMHO
สเตฟาโน

2
@ChrisJohnsen git mv tmp/.git .ส่งคืนให้fatal: cannot move directory over file, source=tmp/.git, destination=.gitฉัน ใครรู้ว่าปัญหาคืออะไร?
เดนนิส

6
@Dennis, มันเป็นตัวพิมพ์ผิด: คำสั่งนั้นควรเป็นแบบธรรมดาmv, ไม่ใช่git mv; แม้ว่านี่จะไม่ได้อธิบายว่าทำไมคุณถึงมี.gitไฟล์อยู่แล้ว (ที่มีgitdir: some/path/to/a/git-dirคำว่า“ gitfile” ถ้ามันไม่อยู่ที่นั่นคุณก็จะเห็นมันfatal: Not a git repository (or any of the parent directories): .gitแทน)
Chris Johnsen

34

การใช้ไดเรกทอรีชั่วคราวนั้นใช้ได้ แต่จะทำงานได้ถ้าคุณต้องการหลีกเลี่ยงขั้นตอนนั้น จากรูทของไดเรกทอรีทำงานของคุณ:

$ rm -fr .git
$ git init
$ git remote add origin your-git-url
$ git fetch
$ git reset --mixed origin/master

20
git reset --hard origin/masterจะลบไฟล์ในเครื่องใด ๆ
Mouad Debbar

1
ที่จะเพิ่มในสิ่งที่ชี้แล้วออกไปต่างระหว่างhardและmixedเป็นที่ผสมจะทำให้การเปลี่ยนแปลงในท้องถิ่น (ดังนั้นหากคุณในภายหลังพยายามที่จะดึงมันจะแสดงให้คุณเช่นไม่สามารถดึงกับ rebase:. คุณมีการเปลี่ยนแปลง unstaged โปรดกระทำหรือซ่อนพวกเขา ) ในขณะที่ยากจะยกเลิกการเปลี่ยนแปลงในท้องถิ่นเหล่านั้น
aexl

คุณสะกดคำจากระยะไกลผิด
เกล็นเดย์ตัน

10
git clone your_repo tmp && mv tmp/.git . && rm -rf tmp && git reset --mixed

7
การใช้git reset --hardจะทำให้เกิดการเปลี่ยนแปลงไฟล์ในเครื่องโดยเฉพาะไม่ใช่สิ่งที่ OP นี้ร้องขอ --mixedควรใช้แทน
Caleb

4

หากต้องการโคลน repo git ลงในไดเรกทอรีว่างที่มีอยู่ทำต่อไปนี้:

cd myfolder
git clone https://myrepo.com/git.git . 

แจ้งให้ทราบ.ในตอนท้ายของgit cloneคำสั่งของคุณ ที่จะดาวน์โหลด repo ลงในไดเรกทอรีการทำงานปัจจุบัน


4
fatal: destination path '.' already exists and is not an empty directory.
Roland Kofler

ไดเรกทอรีจะต้องว่างเปล่า
okTalk

4
OP กำลังขอวิธีโคลนในโครงการที่มีอยู่โดยระบุว่าโคลนคอมไพล์บ่น คำตอบที่ไม่ดี
mix3d

ใช้งานได้เฉพาะเมื่อคุณสร้างไดเรกทอรีใหม่ให้เรียกใช้คำสั่งด้านบนโดยไม่ต้องใช้ "git init"
Bilal Ahmed

3

มีคำตอบมากมายที่ต้องทำในแบบที่ OP ถาม แต่น่าสังเกตว่าการทำในทางตรงกันข้ามนั้นง่ายกว่า:

git clone repo-url tmp/
cp -R working/ tmp/

ตอนนี้คุณมีสถานะเป้าหมายที่ต้องการ - โคลนนิ่งสด + การเปลี่ยนแปลงในท้องถิ่น


2

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

mv $dir $dir.orig
git clone $url $dir
rsync -av --delete --exclude '.git' $dir.orig/ $dir/
rm -rf $dir.orig

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

ในทางกลับกันถ้าคุณต้องทำอย่างนั้นจริง ๆ คุณสามารถได้ผลลัพธ์เดียวกันกับสิ่งนี้:

cd $dir
git clone --no-checkout $url tempdir
mv tempdir/.git .
rmdir tempdir
git reset --mixed HEAD

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

* ทั้งสองตัวอย่างสมมติว่าคุณเริ่มต้นจากเชลล์ในไดเรกทอรีหลักของโครงการของคุณ


2

นี่คือวิธีที่ดีที่สุดของทั้งหมดที่ฉันเจอ

โคลนเฉพาะโฟลเดอร์. git ของที่เก็บ (ไม่รวมไฟล์ตามที่มีอยู่existing-dir) ลงในไดเรกทอรีชั่วคราวที่ว่างเปล่า

  1. git clone --no-checkout repo-path-to-clone existing-dir/existing-dir.tmp // อาจต้องการ - no-hardlinks สำหรับการโคลน repo ในพื้นที่

ย้ายโฟลเดอร์. git ไปยังไดเรกทอรีด้วยไฟล์ สิ่งนี้ทำให้existing-dirrepo คอมไพล์

  1. mv existing-dir/existing-dir.tmp/.git existing-dir/

ลบไดเรกทอรีชั่วคราว

  1. rmdir existing-dir/existing-dir.tmp

  2. cd existing-dir

Git คิดว่าไฟล์ทั้งหมดจะถูกลบซึ่งจะเปลี่ยนสถานะของ repo เป็น HEAD

คำเตือน: การเปลี่ยนแปลงใด ๆ ในตัวเครื่องของไฟล์จะหายไป

  1. git reset --mixed HEAD

1
ดูเหมือนว่าฮาร์ดรีเซ็ตจะไม่ต้องการใน 99% ของกรณีที่คุณต้องทำเช่นนี้
สเตฟานเฟเบียน

0

หากคุณกำลังใช้อย่างน้อยคอมไพล์ 1.7.7 (ซึ่งสอนตัวเลือก) เพื่อเปิดไดเรกทอรีปัจจุบันเป็นสำเนาการทำงาน:clone--config

git clone example.com/my.git ./.git --mirror --config core.bare=false

สิ่งนี้ทำงานโดย:

  • การโคลนที่เก็บลงในที่ใหม่ .gitโฟลเดอร์
  • --mirror ทำให้โคลนใหม่ลงในโฟลเดอร์เมตาดาต้าล้วนๆ .gitต้องการ
  • --config core.bare=falseตอบโต้นัยbare=trueของ--mirrorตัวเลือกดังนั้นจึงอนุญาตให้ที่เก็บมีไดเรกทอรีการทำงานที่เกี่ยวข้องและทำหน้าที่เหมือนโคลนปกติ

สิ่งนี้จะไม่ทำงานหากมี.gitเมตาดาต้าไดเรกทอรีอยู่ในไดเรกทอรีที่คุณต้องการเปลี่ยนเป็นสำเนาที่ใช้งานได้


1
โปรดทราบว่าเทคนิคนี้จะส่งผลให้ใน[core]ส่วนของการตั้งค่าในท้องถิ่นรวมทั้งและbare = true bare = falseปัญหาที่มากขึ้นคือมันจะมีค่าที่ไม่ถูกต้องสำหรับoriginรีโมตโดยมี[remote "origin"]ส่วนรวมถึงmirror = trueและข้อมูลจำเพาะการดึงข้อมูลที่จะทำงานไม่ถูกต้องกับสำเนาที่ใช้งานได้ หลังจากแก้ไขปัญหาเหล่านี้แล้วการโคลนนิ่งตามปกติและการย้ายสำเนาการทำงานใหม่.gitจะมีประสิทธิภาพมากขึ้น
Araxia

0

โดยปกติฉันจะโคลนที่เก็บเริ่มต้นก่อนจากนั้นย้ายทุกอย่างในโฟลเดอร์ที่มีอยู่ไปยังที่เก็บเริ่มต้น มันใช้งานได้ทุกครั้ง

ข้อดีของวิธีนี้คือคุณจะไม่พลาดที่เก็บข้อมูลเริ่มต้นรวมถึง README หรือ. gitignore

คุณยังสามารถใช้คำสั่งด้านล่างเพื่อทำตามขั้นตอนต่อไปนี้:

$ git clone https://github.com/your_repo.git && mv existing_folder/* your_repo

0

คุณสามารถทำได้โดยพิมพ์บรรทัดคำสั่งต่อไปนี้ซ้ำ:

mkdir temp_dir   //  Create new temporary dicetory named temp_dir
git clone https://www...........git temp_dir // Clone your git repo inside it
mv temp_dir/* existing_dir // Move the recently cloned repo content from the temp_dir to your existing_dir
rm -rf temp_dir // Remove the created temporary directory

0

เพียงแค่ใช้ ในตอนท้ายของgit cloneคำสั่ง (อยู่ในไดเรกทอรีนั้น) ดังนี้:

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