Bagaimana cara saya mengkloning ke direktori yang tidak kosong?

573

Saya memiliki direktori A dengan file direktori yang cocok B. Direktori A mungkin memiliki file lain yang diperlukan. Direktori B adalah repo git.

Saya ingin mengkloning direktori B ke direktori A tetapi git-clone tidak mengizinkan saya karena direktori tersebut tidak kosong.

Saya berharap itu hanya akan mengkloning. Git dan karena semua file yang cocok saya bisa pergi dari sana?

Saya tidak bisa mengkloning ke direktori kosong karena saya punya file di direktori A yang tidak ada di direktori B dan saya ingin menyimpannya.

Menyalin .git bukanlah suatu pilihan karena saya ingin referensi mendorong / menarik dan saya tidak ingin mengaturnya secara manual.

Apakah ada cara untuk melakukan ini?

Pembaruan: Saya pikir ini berfungsi, adakah yang bisa melihat masalah? ->

cd a
git clone --no-hardlinks --no-checkout ../b a.tmp 
mv a.tmp/.git .
rm -rf a.tmp
git unstage # apparently git thinks all the files are deleted if you don't do this
Dale Forester
sumber
5
mungkin Anda bisa mengubah jawaban yang diterima?
Bastiaan Quast

Jawaban:

724

Ini bekerja untuk saya:

git init
git remote add origin PATH/TO/REPO
git fetch
git reset origin/master  # Required when the versioned files existed in path before "git init" of this repo.
git checkout -t origin/master

CATATAN: -t akan mengatur cabang hulu untuk Anda, jika itu yang Anda inginkan, dan biasanya itu.

cmcginty
sumber
70
Ini tidak berfungsi di direktori yang tidak kosong ketika file yang masuk sudah ada (seperti yang dijelaskan pertanyaan awal). Tetapi jika Anda git reset origin/mastersetelah git fetch, itu akan berhasil (juga menjaga setiap perubahan lokal).
Araxia
8
fatal: Tidak dapat memperbarui jalur dan beralih ke cabang 'master' secara bersamaan.
Arnold Roa
7
Jawaban ini tidak cocok untuk saya. Ketika saya melakukan git checkout ...git mengeluh bahwa semua file saya akan ditimpa dan saya harus memindahkannya terlebih dahulu. Ketika saya melakukan `git reset asal / master /` pertama, perintah checkout mengeluh bahwa cabang bernama master sudah ada.
Saskia
4
git checkout masteradalah langkah terakhir yang cukup bagi saya.
yoyo
16
Semua langkah-langkah bekerja dengan sempurna tetapi yang terakhir membuat saya: fatal: A branch named 'master' already exists. Saya pikir saya tidak benar-benar membutuhkannya.
Shadi
164

Dalam perintah shell berikut existing-diradalah direktori yang isinya cocok dengan file yang dilacak dalam repo-to-clonerepositori git.

# Clone just the repository's .git folder (excluding files as they are already in
# `existing-dir`) into an empty temporary directory
git clone --no-checkout repo-to-clone existing-dir/existing-dir.tmp # might want --no-hardlinks for cloning local repo

# Move the .git folder to the directory with the files.
# This makes `existing-dir` a git repo.
mv existing-dir/existing-dir.tmp/.git existing-dir/

# Delete the temporary directory
rmdir existing-dir/existing-dir.tmp
cd existing-dir

# git thinks all files are deleted, this reverts the state of the repo to HEAD.
# WARNING: any local changes to the files will be lost.
git reset --hard HEAD
Dale Forester
sumber
5
Saya perlu melakukan git reset --hard HEADatau itu tidak akan menyerah pada file "dihapus".
Dimitar
18
git reset HEADbekerja dengan baik untuk saya. git reset --hard HEADmenghancurkan semua perubahan pada file Anda, jadi jika mereka tidak persis sama dengan file dalam repositori, Anda tidak boleh melakukan itu.
Tgr
1
git reset HEADtampaknya tidak berpengaruh bagi saya. git reset --hard HEADtidak - tetapi kehilangan semua perubahan yang Anda buat pada file. Apakah ada solusi yang lebih baik?
Jacob Dorman
1
@ Casey menjawab - git init / remote add / fetch / checkout - lebih bersih dan sederhana dan tidak memerlukan folder sementara.
yoyo
1
@ Casey menjawab tidak bekerja untuk saya ketika sudah ada file di folder yang perlu tetap tetapi itu tidak ada di git repo. Ini berguna untuk memperbarui konfigurasi setelah menjalankan skrip instalasi tempat file dan direktori dibuat tetapi Anda perlu memperbarui / menambahkan file di atas item yang diinstal.
soulston
104

Sedikit modifikasi pada salah satu jawaban yang berhasil bagi saya:

git init
git remote add origin PATH/TO/REPO
git pull origin master

untuk mulai bekerja pada cabang master langsung.

mohsaied
sumber
1
harus melakukan reset KEPALA - sulit untuk membersihkan direktori kotor yang ada, tanpa menghapus file yang tidak relevan yang ditentukan dalam gitignore
Ray Foss
1
Ini adalah salah satu yang benar-benar bekerja untuk saya, berbeda dengan jawaban @ cmcginty.
tentu saja
4
Ini tidak cukup setara dengan git-clone - yang hilang adalah informasi hulu untuk cabang master. Ini dapat diperbaiki dengan menambahkan git branch --set-upstream-to=origin/master master.
Slaven Rezic
Versi ini bekerja untuk saya, hanya perlu melakukan git reset --hard HEAD
Frédéric Klee
29

Peringatan - ini berpotensi menimpa file.

git init     
git remote add origin PATH/TO/REPO     
git fetch     
git checkout -t origin/master -f

Dimodifikasi dari jawaban @ cmcginty - tanpa -f itu tidak berfungsi untuk saya

JohnFF
sumber
Tentunya Anda perlu checkout semua file setelah ini dengan git checkout .?
Chris Stryczynski
25

Inilah yang akhirnya saya lakukan ketika saya memiliki masalah yang sama (setidaknya saya pikir itu masalah yang sama). Saya pergi ke direktori A dan berlarigit init .

Karena saya tidak ingin file dalam direktori A diikuti oleh git, saya mengedit .gitignore dan menambahkan file yang ada ke dalamnya. Setelah ini saya menjalankan git remote add origin '<url>' && git pull origin masteret voíla, B "dikloning" menjadi A tanpa cegukan tunggal.

BjornSnoen
sumber
2
Teknik ini tidak berfungsi di direktori tidak kosong ketika file yang masuk sudah ada (seperti yang dijelaskan pertanyaan asli).
Araxia
11

Saya telah menggunakan ini beberapa saat yang lalu, membutuhkan perintah yang paling tidak berpotensi merusak:

cd existing-dir
git clone --bare repo-to-clone .git
git config --unset core.bare
git remote rm origin
git remote add origin repo-to-clone
git reset

Dan voila!

KuttKatrea
sumber
10

Resep sederhana lain sepertinya bekerja dengan baik untuk saya:

git clone --bare $URL .git
git config core.bare false

Kasus penggunaan utama saya untuk memeriksa ke direktori dengan file yang ada adalah untuk mengontrol dotfiles Unix saya dengan Git. Pada akun baru, direktori home sudah memiliki beberapa file di dalamnya, bahkan mungkin yang ingin saya dapatkan dari Git.

Ken Williams
sumber
1
Repositori telanjang diatur sedikit berbeda dan sementara ini berfungsi saya tidak akan merekomendasikan hal ini. :)
ThorSummoner
1
Bisakah Anda lebih spesifik? Apa perbedaannya?
Ken Williams
1
Hanya dua perbedaan: 1.) .git/configFile menunjukkan bahwa repo kosong. 2.) File yang biasanya disimpan .gitdisimpan di root (yang Anda panggil .git)
mozey
4
Mereka adalah persis perubahan yang kloning untuk .gitdan pengaturan core.bareuntuk falseakan mengurus, jadi saya masih merasa baik tentang metode ini.
Ken Williams
10

Ini bekerja untuk saya:

cd existing_folder
git init
git remote add origin path_to_your_repo.git
git add .
git commit
git push -u origin master
Mike6679
sumber
6

Saya memiliki masalah yang sama dengan direktori web Apache baru (akun dibuat dengan WHM) yang saya rencanakan untuk digunakan sebagai server web pementasan. Saya awalnya perlu mengkloning proyek baru saya dengan basis kode di sana dan secara berkala menyebarkan perubahan dengan menarik dari repositori.

Masalahnya adalah bahwa akun tersebut sudah berisi file server web seperti:

.bash_history
.bash_logout
.bash_profile
.bashrc
.contactemail
.cpanel/
...

... yang saya tidak ingin hapus atau komit ke repositori saya. Saya membutuhkan mereka untuk tinggal di sana tanpa panggung dan tidak terlacak.

Apa yang saya lakukan:

Saya pergi ke folder web saya (existing_folder):

cd /home/existing_folder

lalu:

git init
git remote add origin PATH/TO/REPO
git pull origin master
git status

Ini ditampilkan (seperti yang diharapkan) daftar banyak file tidak dipentaskan - yang sudah ada pada awalnya dari akun web cPanel saya.

Kemudian, berkat artikel ini , saya baru saja menambahkan daftar file-file itu ke:

**.git/info/exclude**

File ini, hampir seperti .gitignorefile itu, memungkinkan Anda untuk mengabaikan file yang dipentaskan. Setelah ini, saya tidak punya komitmen di direktori .git / - ini berfungsi seperti pribadi.gitignore yang tidak dapat dilihat orang lain.

Sekarang memeriksa git statuspengembalian:

On branch master
nothing to commit, working tree clean

Sekarang saya dapat menyebarkan perubahan ke server web ini hanya dengan menarik dari repositori git saya. Semoga ini membantu beberapa pengembang web untuk dengan mudah membuat server pementasan.

Vlado
sumber
5

Inilah yang saya lakukan:

git clone repo /tmp/folder
cp -rf /tmp/folder/.git /dest/folder/
cd /dest/folder
git checkout -f master
Philip Kirkbride
sumber
4

Mungkin saya salah mengerti pertanyaan Anda, tetapi tidakkah akan lebih mudah jika Anda menyalin / memindahkan file dari A ke git repo B dan menambahkan yang diperlukan dengan git add ?

PEMBARUAN: Dari git doc:

Kloning ke direktori yang ada hanya diperbolehkan jika direktori kosong.

SUMBER: http://git-scm.com/docs/git-clone

Roberto Aloi
sumber
2
Tidak, pemilik dan file dapat berubah-ubah. Ini untuk situasi dengan beberapa pengembang. Kita semua memiliki direktori yang ada dan saat ini hanya satu yang memiliki checkout git. Kita semua sebagian besar memiliki subset file yang sama sehingga kami ingin agar pengembang lain dapat mengkloning sambil mempertahankan file mereka. Dan itu harus elegan dan senyaman mungkin.
Dale Forester
Jujur, saya tidak melihat titik berkembang dalam kondisi seperti itu. Tidak bisakah Anda menggunakan cabang dan menggabungkan operasi? Atau memiliki sub-repositori dengan dependensi eksternal? Mengapa Anda ingin mengandalkan satu "checkout git"?
Roberto Aloi
5
"Checkout git tunggal" bukan inti dari seluruh cobaan. Hanya saja begitulah adanya dan kita perlu cara untuk maju. Saya memperbarui pertanyaan awal dengan solusi yang tampaknya berfungsi. Saya menghargai umpan baliknya.
Dale Forester
3
Ada banyak kasus yang sah untuk ini - Saya memiliki pohon folder kompleks yang harus disetel SEBELUM sumber proyek saya dapat diatur, dan folder pohon itu berisi karya berlisensi yang tidak dapat disimpan di GitHub misalnya.
BrainSlugs83
3

Saya mencari sesuatu yang serupa, dan inilah yang saya pikirkan:

Situasi saya adalah di mana saya memiliki pohon web aktif dan saya mencoba membuat repositori jarak jauh tanpa memindahkan salah satu file di pohon web saat ini. Inilah yang saya lakukan:

  1. Pergi ke pohon web dan jalankan git init
  2. Pergi ke lokasi repositori yang dimaksud dan jalankan: git clone --bare /path/to/web/repo
  3. Edit file konfigurasi di repo jarak jauh saya dan hapus file [remote "origin"] bagian tersebut.
  4. Tambahkan [remote "origin"]bagian ke .git / config di pohon web yang menunjuk ke repo jarak jauh yang baru.
Lendrick
sumber
Saya suka resep ini.
dland
Di git clone --baresini berlebihan dan berputar-putar. Mengapa tidak hanya git remote add origin <URL>di tempat pertama?
Araxia
3

ini berfungsi untuk saya, tetapi Anda harus menggabungkan file repositori jarak jauh ke file lokal:

git init
git remote add origin url-to-git
git branch --set-upstream-to=origin/master master
git fetch
git status
RODNEY ZHANG
sumber
1

Saya menyukai jawaban Dale , dan saya juga menambahkan

git clone --depth 2 --no-checkout repo-to-clone existing-dir/existing-dir.tmp
git branch dev_new214
git checkout dev_new214
git add .
git commit
git checkout dev
git merge dev_new214

Kedalaman dangkal menghindari banyak komitmen dev awal ekstra. Cabang baru memberi kami sejarah visual yang baik bahwa ada beberapa kode baru dari server ini yang ditempatkan. Itulah cabang penggunaan yang sempurna menurut saya. Terima kasih banyak untuk semua orang yang memposting di sini.

Dmitri R117
sumber
0

Saya mendapat masalah yang sama ketika mencoba mengkloning ke c / kode

Tetapi folder ini berisi sejumlah besar proyek.

Saya membuat folder baru di c / code / newproject dan memetakan klon saya ke folder ini.

git untuk desktop kemudian meminta pengguna saya dan kemudian dikloning dengan baik.

Tom
sumber