Mevcut bir klasöre “git clone” yazmanın en iyi yolu nedir?


479

Kaynak denetimi meta verileri olmadan projenin çalışan bir kopyası var. Şimdi, bu klasöre git-clone eşdeğerini yapmak ve yerel değişiklikleri tutmak istiyorum.

git-clone varolan bir klasöre kopyalamama izin vermiyor. Buradaki en iyi uygulama nedir?


4
Daha iyi tartışma burada .
cdunn2001

1
@MEM Bu yanıtı daha çok seviyorum, ama ya çalışıyor ... stackoverflow.com/a/5377989/11236
ripper234

2
@ ripper234 - Evet. Aynı durumdaydım ve sadece bu adımları attım ve sorun yok. Hepsi temiz ve güzel. Sanırım bir tercih meselesi, sonuç olarak, her ikisinin de belirttiğiniz gibi çalışması. Şerefe.
MEM

1
Bu o kadar çılgın ki, bunu başarmanın temiz bir yolu yok, bir projeyi monte edilmiş bir paylaşım klasörüne kopyalamak istediğinizde çok kullanışlıdır.
Thomas Decaux

Yanıtlar:


558

Bu, yeni bir dizine klonlayıp ardından .gitdizini mevcut dizininize taşıyarak yapılabilir .

Mevcut dizininiz "kod" olarak adlandırılmışsa.

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

Bu, klon komutu sırasında bir ödeme yapmadan da yapılabilir; daha fazla bilgiyi burada bulabilirsiniz .


25
Bunun tam olarak @ChrisJohnsen'in yorumlarda bıraktığı öneri olduğunu unutmayın. Yararlı buldum ve gerçek bir cevap haline getirmek istedim. Chris, bir cevap verirsen, bunu memnuniyetle silerim.
amicitas

2
Teşekkürler! Buna rağmen "git checkout -." Gibi bir adım eksik. tüm dosyaların silindiğini düşündüğü için, değil mi?
mrooney

2
Hayır, git cloneilk komut olarak kullandığınız sürece başka bir çıkış komutu gerekmez. Bunun yerine git clone --no-checkoutilk adımda olduğu gibi bir şey kullanırsanız , .git dizini taşındıktan git reset HEADsonra dosyaların silinmediğini söylemek için kullanılması gerekir.
amicitas

3
Bunu üçüncü adım olarak eklerdim: mv temp / .gitignore kodu / .gitignore
Daniel Aranda

1
@KalpeshSoni, evet git değiştirilen dosyalar hakkında bilgi sahibi olacak ve normal git komutlarını kullanarak değişiklikleri görmek mümkün olacak git status.
amicitas

284

Klonlama, yerine getir. Depoda:

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

Ardından istediğiniz taahhüdü almak için ağacı sıfırlayabilirsiniz:

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

ve sen klonlanmış gibisin.

Buradaki ilginç soru (ve cevapsız olanı): Çıplak ağacınızın hangi taahhüdüne, dolayısıyla hangi konuma sıfırlanacağına nasıl karar verilir.


7
Bunun hayranı değilim - github kurulumu başına "İpucu: Kimlik bilgisi yardımcısı yalnızca bir HTTPS depo URL'sini klonladığınızda çalışır." Kimlik bilgisi yardımcısı kullanıyordum ve bu bana oldukça uzun, meyvesiz bir tavşan deliği gönderdi.
Andrew

5
'git checkout --track origin / master' yerine 'git checkout -b master --track origin / master' yerine iyi çalışır. Sıfırlamaya gerek yoktur.
felipecrp

1
"Git hatası: Aşağıdaki izlenmeyen çalışma ağacı dosyalarının kasasıyla üzerine yazılır" hatası alıyordum, bu yüzden bu komutu ekledim: git clean -d -fx ""
shakaran

1
kesinlikle her durumda tavsiye edilmez, ama tam da ihtiyacım olan şey bu.
Chaim Eliyah

1
@AndreasKrey Orijinal cevabınız (görmek için düzenleme geçmişine girdim) soru (ve ben) için tam olarak gerekli olanı yapar. Yerel değişiklikleri atar ve ben tam olarak ne -f, kullanmadan kasada değiştirilen cevap Barfs yok istiyorum. Ben olsaydım, orijinal cevabınıza geri dönmeyi düşünürdüm.
Ajean

77

Varolan bir dizinde ana dal ödeme için aşağıdakileri yaptım:

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

2
Bu harika bir cevaptır ve herhangi bir dosya sisteminin çarpışmasını önler.
user151841

1
Bu bir hack olmadığı için kabul edilen cevap olmalı.
php_nub_qq

5
Aslında bu OP'nin (ve benim) istemediği şeyi yapıyor , ki bu da yerel değişikliklerin üzerine yazmak.
Ajean

Benim oyum, bunun bana yardımcı olduğunu gösteriyor, OP'nin sorusuna en iyi cevap bu değil.
TecBrat

2
-tBurada bayrağın neden kullanıldığını açıklayabilir misiniz?
jfowkes

38

Ben isterdim git cloneyeni bir dizine ve yeni klon mevcut dizinin içeriğini kopyalayın.


4
bunu yaparsanız, çok dikkatli bir şekilde taahhütte bulunmadan önce farkı gözden geçirdiğinizden emin olun - bu, çalışma kopyanızı aldığınızda beri kaynak deposunda yapılan değişiklikleri yanlışlıkla geri alabileceğiniz mutlak bir klasik durumdur - çünkü yeterli bilgi yok çalışma kopyasında, değişiklik yapmaya başlamadan önce ne gibi değişiklikler yaptığınızı, depoda yapılan diğer değişikliklerle birleştirmek için. Bu durumda kendimi ve birlikte çalıştığım insanları "kesinlikle cesaretlendirdiğim" noktaya kadar bu durumda tekrar tekrar gördüm.
Ben Clifford

72
git clone wherever tmp && git mv tmp/.git . && rm -rf tmpBaşka bir deyişle, .gitdizini geçici bir klondan çıkarmak, klonun çalışma ağacını temizlemek ve mevcut dosyaları oraya kopyalamaktan daha basit görünüyor.
Chris Johnsen

1
@ChrisJohnsen: Bir cevap vermeliydiniz, bu kesinlikle bunu yapmanın en iyi yolu imho
Stefano

2
@ChrisJohnsen benim için git mv tmp/.git .geri dönüyor fatal: cannot move directory over file, source=tmp/.git, destination=.git. Sorunun ne olduğunu bilen var mı?
Dennis

6
@Dennis, Bir yazım hatası: bu komut düz olmalı mv, değil git mv; ancak bu, neden .gitorada zaten bir dosyanız olduğunu açıklamıyorsa ( gitdir: some/path/to/a/git-dirbir “gitfile” içeren ; orada olmasaydı, fatal: Not a git repository (or any of the parent directories): .gitbunun yerine onu görürdünüz ).
Chris Johnsen

34

Temp dizini kullanmak iyidir, ancak bu adımdan kaçınmak istiyorsanız bu işe yarar. Çalışma dizininizin kökünden:

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

20
git reset --hard origin/masteryerel dosyaları kaldıracaktır.
Mouad Debbar

1
Yukarıda işaret ne için arasındaki farkı eklemek hardve mixedkarışık yerel değişiklikleri tutacak olmasıdır (daha sonra sizi örn göstereceğiz çekmeye çalışmayın eğer öyleyse : Sen unstaged değişiklikler var işlemeye veya bunları saklamak Lütfen rebase ile çekin olamaz. ) , zor bu yerel değişiklikleri
atacak

Yanlış hecelediniz.
Glenn Dayton

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

7
Kullanarak git reset --hardyerel dosya değişiklikleri, özellikle bu OP talep ne nuke. --mixedyerine kullanılmalıdır.
Caleb

4

Git deposunu boş bir dizine kopyalamak için aşağıdakileri yapın:

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

Komutunuzun .sonunda olduğuna dikkat edin git clone. Bu, repo'yu geçerli çalışma dizinine indirir.


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

Dizin boş olmalıdır.
okTalk

4
OP, mevcut bir projeye nasıl klonlanacağını sorarak git klonunun şikayet ettiğini belirtiyor. Kötü cevap.
mix3d

Bu yalnızca yeni dizin oluşturduğunuzda, "git init" kullanmadan yukarıdaki komutları çalıştırdığınızda çalışır
Bilal Ahmed

3

OP'nin istediği şekilde yapmak için zaten birçok cevap var. Ancak bunun tersini yapmanın çok daha basit olduğunu belirtmek gerekir:

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

Artık istenen hedef duruma sahipsiniz - yeni klon + yerel değişiklikler.


2

Buna iki yaklaşım var. Mümkün olduğunda, yeni git çalışma dizininiz için temiz bir klasörle başlayıp daha sonra şeylerin sürümünüzü kopyalarım. Bu şuna benzeyebilir *:

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

Bu noktada, geçerli çalışma dizini olarak önceki çalışma klasörünüzle oldukça temiz bir çalışma kopyasına sahip olmalısınız, böylece herhangi bir değişiklik dosya silme işlemlerini çalıştırırsanız radarda görünecektir git status.

Öte yandan, bunu gerçekten başka bir şekilde yapmanız gerekiyorsa, aynı sonucu şu şekilde alabilirsiniz:

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

Her iki durumda da, yapacağım ilk şey git stash, tüm yerel değişikliklerinizin bir kopyasını bir kenara koymak gibi bir şey çalıştırmaktır , daha sonra bunları yeniden uygulayabilir ve hangilerini taahhüt etmek istediğinizi çalışabilirsiniz.

* Her iki örnek de projenizin üst dizinindeki kabukta başladığınızı varsayar.


2

Bu, karşılaştığım tüm yöntemlerin en iyisi

Yalnızca deponun .git klasörünü (zaten var olan dosyalar hariç existing-dir) boş bir geçici dizine kopyalayın

  1. git clone --no-checkout repo-path-to-clone existing-dir/existing-dir.tmp // isteyebilir - yerel repoyu kopyalamak için hiçbir bağlantı yok

.Git klasörünü dosyaların bulunduğu dizine taşıyın. Bu existing-dirbir git repo yapar .

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

Geçici dizini silme

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

  2. cd existing-dir

Git tüm dosyaların silindiğini düşünür, bu da repo durumunu HEAD'e döndürür.

UYARI: dosyalarda yapılan yerel değişiklikler kaybolacaktır.

  1. git reset --mixed HEAD

1
Bunu yapmanız gereken vakaların% 99'unda donanımdan sıfırlama istenmeyen görünüyor.
Stefan Fabian

0

Eğer (öğretti en azından budala 1.7.7 kullanıyorsanız seçeneği), bir çalışma kopyası haline geçerli dizini açmak için:clone--config

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

Bu şu şekilde çalışır:

  • Depoyu yeni bir .gitklasöre kopyalama
  • --mirroryeni klonu .gitgerektiği gibi tamamen meta veri klasörüne dönüştürür
  • --config core.bare=falseseçeneğin örtükünü bare=trueortadan kaldırır --mirror, böylece havuzun ilişkili bir çalışma dizinine sahip olmasına ve normal bir klon gibi davranmasına izin verir

Çalışmakta .gitolan bir kopyaya dönüştürmek istediğiniz dizinde zaten bir meta veri dizini varsa, bu kesinlikle işe yaramaz .


1
Bu tekniğin, ve[core] dahil olmak üzere yerel yapılandırma bölümünde sonuçlanacağını unutmayın . Daha sorunlu, uzaktan kumanda için yanlış değerlere sahip olması, bölüm dahil ve çalışan bir kopyayla düzgün çalışmayan bir getirme özelliğiyle olmasıdır. Bu sorunları çözdükten sonra, normal olarak klonlama ve yeni çalışan kopyaların taşınması daha verimli olacaktır. bare = true bare = falseorigin[remote "origin"]mirror = true.git
Araxia

0

Genellikle ilk depoyu klonlayacağım ve sonra varolan klasördeki her şeyi ilk depoya taşıyacağım. Her seferinde çalışır.

Bu yöntemin avantajı, README veya .gitignore dahil ilk depodan hiçbir şeyi kaçırmamanızdır.

Adımları tamamlamak için aşağıdaki komutu da kullanabilirsiniz:

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

0

Aşağıdaki komut satırlarını özyinelemeli olarak yazarak yapabilirsiniz:

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

Sadece. git clonekomutun sonunda (bu dizinde olmak) şöyle:

cd your_dir_to_clone_in/
git clone git@github.com/somerepo/ .
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.