Apa praktik terbaik untuk "git klon" ke folder yang ada?

480

Saya memiliki salinan proyek yang berfungsi, tanpa data meta kontrol sumber. Sekarang, saya ingin melakukan yang setara dengan git-clone ke folder ini, dan menyimpan perubahan lokal saya.

git-clone tidak memungkinkan saya untuk mengkloning ke folder yang ada. Apa praktik terbaik di sini?

ripper234
sumber
4
Diskusi yang lebih baik ada di sini .
cdunn2001
1
@MEM Saya suka jawaban ini lebih banyak, tetapi keduanya berfungsi ... stackoverflow.com/a/5377989/11236
ripper234
2
@ ripper234 - Ya. Saya berada di situasi yang sama dan saya hanya melakukan langkah-langkah itu, dan tidak ada masalah. Semuanya bersih dan menyenangkan. Saya kira ini masalah preferensi, intinya adalah, bahwa keduanya berfungsi, seperti yang Anda nyatakan. Bersulang.
MEM
1
Ini sangat gila tidak ada cara yang bersih untuk mencapainya, sangat berguna ketika Anda ingin mengkloning projet ke folder share yang terpasang.
Thomas Decaux
1
Kemungkinan duplikat dari Bagaimana cara saya mengkloning ke direktori yang tidak kosong?
Tobias Kienzler

Jawaban:

559

Ini dapat dilakukan dengan mengkloning ke direktori baru, lalu memindahkan .gitdirektori ke direktori yang ada.

Jika direktori Anda yang ada bernama "kode".

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

Ini juga dapat dilakukan tanpa melakukan checkout selama perintah clone; informasi lebih lanjut dapat ditemukan di sini .

amicitas
sumber
25
Perhatikan bahwa ini persis saran dari @ChrisJohnsen yang dia tinggalkan di komentar. Saya menemukan itu berguna dan ingin membuatnya menjadi jawaban yang sebenarnya. Chris, jika Anda akhirnya memberikan jawaban, saya akan dengan senang hati menghapus yang ini.
amicitas
2
Terima kasih! Meskipun ini tidak ada langkah seperti "git checkout -." karena dianggap semua file dihapus, kan?
mrooney
2
Tidak, selama Anda menggunakan git cloneperintah pertama, tidak ada perintah checkout lebih lanjut diperlukan. Jika Anda menggunakan sesuatu seperti git clone --no-checkoutpada langkah pertama itu, maka setelah direktori .git dipindahkan, Anda perlu menggunakannya git reset HEADuntuk memberi tahu git bahwa file-file tersebut belum dihapus.
amicitas
3
Saya akan menambahkan ini sebagai langkah ketiga: mv temp / .gitignore code / .gitignore
Daniel Aranda
1
@KalpeshSoni, ya git akan tahu tentang file yang dimodifikasi dan akan mungkin untuk melihat perubahan menggunakan perintah normal git seperti git status.
amicitas
284

Jangan mengkloning, ambil saja. Dalam repo:

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

Kemudian Anda dapat mengatur ulang pohon untuk mendapatkan komit yang Anda inginkan:

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

dan Anda seperti Anda dikloning.

Pertanyaan menarik di sini (dan yang tanpa jawaban): Bagaimana mengetahui komit pohon telanjang Anda berdasarkan, maka ke posisi mana untuk mengatur ulang.

Andreas Krey
sumber
7
Saya bukan penggemar ini - per pengaturan github "Kiat: Pembantu kredensial hanya berfungsi ketika Anda mengkloning URL repositori HTTPS." Saya menggunakan pembantu kredensial dan ini mengirim saya ke lubang kelinci yang panjang dan tidak membuahkan hasil.
Andrew
5
'git checkout --track origin / master' juga berfungsi dengan baik alih-alih 'git checkout -b master --track origin / master'. Reset tidak diperlukan.
felipecrp
1
Saya mendapatkan kesalahan "Kesalahan Git: File pohon yang tidak terpecahkan berikut ini akan ditimpa dengan checkout", jadi saya menambahkan perintah ini: git clean -d -fx ""
shakaran
1
jelas tidak disarankan dalam semua situasi, tetapi inilah yang saya butuhkan.
Chaim Eliyah
1
@AndreasKrey Jawaban asli Anda (yang saya lihat dalam edit history untuk melihat) melakukan apa yang dibutuhkan oleh pertanyaan (dan saya). Barf jawaban yang diubah di checkout tanpa menggunakan -f, yang membuang perubahan lokal dan persis apa yang tidak saya inginkan. Jika saya jadi Anda, saya akan mempertimbangkan untuk kembali ke jawaban awal Anda.
Ajean
77

Berikut ini saya lakukan, untuk checkout cabang utama di direktori yang ada:

git init
git remote add origin [my-repo]
git fetch
git checkout origin/master -ft
alexwenzel
sumber
2
Ini adalah jawaban yang bagus dan menghindari segala penyelesaian sistem file.
user151841
1
Ini harus menjadi jawaban yang diterima karena ini bukan peretasan.
php_nub_qq
5
Sebenarnya ini melakukan persis apa yang OP (dan saya) tidak inginkan, yaitu untuk menimpa perubahan lokal.
Ajean
Suara positif saya menunjukkan bahwa ini membantu AKU, bukan itu adalah jawaban terbaik untuk pertanyaan OP.
TecBrat
2
Adakah yang bisa menjelaskan mengapa -tbendera digunakan di sini?
jfowkes
38

Saya akan git cloneke direktori baru dan menyalin konten direktori yang ada ke klon baru.

jhwist
sumber
4
jika Anda melakukannya, pastikan Anda meninjau perbedaan sebelum melakukan dengan sangat hati-hati - ini adalah kasus klasik mutlak di mana Anda dapat secara tidak sengaja mengembalikan perubahan yang dibuat dalam repo sumber karena setiap kali Anda mendapatkan copy pekerjaan Anda - karena tidak ada info yang cukup di copy pekerjaan untuk mencari tahu apa perubahan yang Anda buat vs seperti apa sebelum Anda mulai membuat perubahan, untuk bergabung dengan perubahan lain yang dibuat dalam repo. Saya telah melihat ini terjadi berkali-kali dalam situasi ini, sampai pada titik di mana saya "sangat mengecilkan hati" diri saya dan orang-orang yang pernah bekerja sama dengan saya.
Ben Clifford
72
git clone wherever tmp && git mv tmp/.git . && rm -rf tmpDengan kata lain, memindahkan .gitdir keluar dari klon sementara tampaknya lebih sederhana daripada membersihkan pohon kerja klon dan menyalin file yang ada di sana.
Chris Johnsen
1
@ChrisJohnsen: Anda seharusnya membuatnya menjadi jawaban, itu pasti cara terbaik untuk melakukannya imho
Stefano
2
@ChrisJohnsen git mv tmp/.git .kembali fatal: cannot move directory over file, source=tmp/.git, destination=.gituntuk saya. Adakah yang tahu apa masalahnya?
Dennis
6
@ Dennis, Ini salah ketik: perintah itu harus jelas mv, tidak git mv; meskipun ini tidak menjelaskan mengapa Anda memiliki .gitfile yang sudah ada (berisi gitdir: some/path/to/a/git-dir, "gitfile"; jika tidak ada di sana, maka Anda akan melihatnya fatal: Not a git repository (or any of the parent directories): .gitsebagai gantinya).
Chris Johnsen
34

Menggunakan direktori temp baik-baik saja, tetapi ini akan berhasil jika Anda ingin menghindari langkah itu. Dari akar direktori kerja Anda:

$ rm -fr .git
$ git init
$ git remote add origin your-git-url
$ git fetch
$ git reset --mixed origin/master
pengguna1055643
sumber
20
git reset --hard origin/masterakan menghapus file lokal apa pun.
Mouad Debbar
1
untuk menambah apa yang sudah ditunjukkan di atas, perbedaan antara harddan mixedadalah bahwa campuran akan menyimpan perubahan lokal (jadi jika Anda kemudian mencoba menariknya akan menunjukkan kepada Anda mis. Tidak dapat menarik dengan rebase: Anda memiliki perubahan yang belum dipentaskan. Silakan komit atau sembunyikan ) , sementara hard akan membuang perubahan lokal itu
aexl
Anda salah mengeja jarak jauh.
Glenn Dayton
10
git clone your_repo tmp && mv tmp/.git . && rm -rf tmp && git reset --mixed
return1.at
sumber
7
Menggunakan git reset --hardakan membatalkan perubahan file lokal, khususnya BUKAN apa yang diminta OP ini. --mixedharus digunakan sebagai gantinya.
Caleb
4

Untuk mengkloning git repo ke direktori kosong yang ada lakukan hal berikut:

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

Perhatikan bagian .akhir git cloneperintah Anda . Itu akan mengunduh repo ke direktori kerja saat ini.

okTalk
sumber
4
fatal: destination path '.' already exists and is not an empty directory.
Roland Kofler
Direktori harus kosong.
okTalk
4
OP meminta cara untuk mengkloning ke proyek yang ada, menyatakan bahwa git clone mengeluh. Jawaban yang buruk
mix3d
Ini hanya berfungsi ketika Anda membuat direktori baru, jalankan perintah di atas tanpa menggunakan "git init"
Bilal Ahmed
3

Sudah banyak jawaban untuk melakukannya seperti yang diminta OP. Tetapi perlu dicatat bahwa melakukannya sebaliknya jauh lebih mudah:

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

Anda sekarang memiliki status target yang diinginkan - klon baru + perubahan-lokal.

Andrew
sumber
2

Ada dua pendekatan untuk ini. Jika memungkinkan saya akan mulai dengan folder bersih untuk direktori kerja git baru Anda dan kemudian menyalin versi Anda nanti. Ini mungkin terlihat seperti *:

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

Pada titik ini Anda harus memiliki copy pekerjaan yang cukup bersih dengan folder kerja Anda sebelumnya sebagai direktori kerja saat ini sehingga setiap perubahan termasuk penghapusan file akan muncul di radar jika Anda menjalankan git status.

Di sisi lain jika Anda benar-benar harus melakukannya sebaliknya, Anda bisa mendapatkan hasil yang sama dengan sesuatu seperti ini:

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

Apa pun itu, hal pertama yang akan saya lakukan adalah menjalankan sesuatu seperti git stashmendapatkan salinan dari semua perubahan lokal Anda yang disisihkan, kemudian Anda dapat mendaftar ulang dan bekerja melalui mana yang ingin Anda komit.

* Kedua contoh menganggap Anda mulai pada shell di direktori induk proyek Anda.

Caleb
sumber
2

Ini adalah yang terbaik dari semua metode yang saya temui

Klon hanya folder .git repositori (tidak termasuk file yang sudah ada existing-dir) ke direktori sementara yang kosong

  1. git clone --no-checkout repo-path-to-clone existing-dir/existing-dir.tmp // mungkin ingin --no-hardlinks untuk mengkloning repo lokal

Pindahkan folder .git ke direktori dengan file. Ini membuat existing-dirrepo git.

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

Hapus direktori sementara

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

  2. cd existing-dir

Git berpikir semua file dihapus, ini mengembalikan status repo ke HEAD.

PERINGATAN: perubahan lokal pada file akan hilang.

  1. git reset --mixed HEAD
Amirtha Rajan
sumber
1
Reset keras tampaknya tidak diinginkan dalam 99% kasus di mana Anda harus melakukan ini.
Stefan Fabian
0

Jika Anda menggunakan setidaknya git 1.7.7 (yang diajarkan clonedalam --configpilihan), untuk mengubah direktori saat ini menjadi copy pekerjaan:

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

Ini bekerja dengan:

  • Mengkloning repositori ke .gitfolder baru
  • --mirrormembuat klon baru menjadi folder metadata murni seperti yang .gitseharusnya
  • --config core.bare=falsecountermands implisit bare=truedari --mirrorpilihan, sehingga memungkinkan repositori untuk memiliki direktori kerja terkait dan bertindak seperti clone yang normal

Ini jelas tidak akan berfungsi jika .gitdirektori metadata sudah ada di direktori yang ingin Anda ubah menjadi salinan yang berfungsi.

ThorSummoner
sumber
1
Perhatikan bahwa teknik ini akan menghasilkan [core]bagian dari konfigurasi lokal termasuk keduanya bare = true dan bare = false . Lebih bermasalah adalah bahwa ia akan memiliki nilai yang salah untuk originremote, dengan [remote "origin"]bagian termasuk mirror = truedan mengambil spec yang tidak akan berfungsi dengan baik dengan copy yang berfungsi. Setelah memperbaiki masalah ini, kloning secara normal dan memindahkan copy pekerjaan baru .gitakan lebih efisien.
Araxia
0

Biasanya saya akan mengkloning repositori awal terlebih dahulu, dan kemudian memindahkan semua yang ada di folder yang ada ke repositori awal. Ini bekerja setiap saat.

Keuntungan dari metode ini adalah Anda tidak akan melewatkan repositori awal termasuk README atau .gitignore.

Anda juga dapat menggunakan perintah di bawah ini untuk menyelesaikan langkah-langkah:

$ git clone https://github.com/your_repo.git && mv existing_folder/* your_repo
Mike Chen
sumber
0

Anda bisa melakukannya dengan mengetikkan baris perintah berikut secara rekursif:

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
MUSTAPHA GHLISSI
sumber
0

Cukup gunakan. di akhir git cloneperintah (berada di direktori itu), seperti ini:

cd your_dir_to_clone_in/
git clone [email protected]/somerepo/ .
John F
sumber
Tidak berfungsi: fatal: jalur tujuan '.' sudah ada dan bukan direktori kosong.
Tristan CHARBONNIER