Dua repositori git dalam satu direktori?

89

Apakah mungkin memiliki 2 repositori git dalam satu direktori? Kurasa tidak, tapi kupikir aku akan bertanya. Pada dasarnya, saya ingin memeriksa file konfigurasi direktori home saya (misalnya .emacs) yang seharusnya umum di semua mesin yang saya gunakan, tetapi memiliki repositori kedua untuk file lokal (misalnya .emacs.local), yang berisi konfigurasi khusus mesin. Satu-satunya cara yang dapat saya pikirkan untuk melakukannya adalah dengan memiliki konfigurasi lokal di subdirektori dan mengabaikan subdirektori tersebut dari repositori git utama. Ada ide lain?

Joe Casadonte
sumber
git subtreeakan menyelesaikan pekerjaan.
Syd Pao
Jika Anda tidak berurusan dengan terlalu banyak file, Anda juga dapat membuat symlinks / junctions.
thdoan

Jawaban:

38

Jika saya mengerti apa yang Anda lakukan, Anda dapat menangani semuanya dalam satu repositori, menggunakan cabang terpisah untuk setiap mesin, dan cabang yang berisi file konfigurasi direktori home umum Anda.

Inisialisasi repo dan komit file umum ke sana, mungkin mengganti nama cabang MASTER sebagai Common. Kemudian buat cabang terpisah dari sana untuk setiap mesin yang Anda gunakan, dan komit file khusus mesin ke dalam cabang itu. Setiap kali Anda mengubah file umum, gabungkan cabang umum ke setiap cabang mesin dan dorong ke komputer Anda yang lain (tulis skrip untuk itu jika ada banyak).

Kemudian di setiap mesin, periksa cabang mesin itu, yang juga akan menyertakan file konfigurasi umum.

Paul
sumber
1
Meskipun submodul juga akan berfungsi, menurut saya ini adalah pendekatan terbaik untuk saya. File lokal akan mengikuti templat, dan ketika saya membuat perubahan pada templat di cabang MASTER, saya dapat menggabungkannya ke dalam mesin cabang lokal, secara bertahap memperbarui file konfigurasi lokal. Terima kasih untuk bantuannya!
Joe Casadonte
gunakan Mercurial dan Git keduanya.
Linc
177

Artikel ini mencakup ini dengan relatif baik:

https://github.com/rrrene/gitscm-next/blob/master/app/views/blog/progit/2010-04-11-environment.markdown

Pada dasarnya jika Anda bekerja dari baris perintah, ini lebih sederhana dari yang Anda duga. Misalkan Anda menginginkan 2 git repo:

.gitone
.gittwo

Anda dapat mengaturnya seperti ini:

git init .
mv .git .gitone
git init .
mv .git .gittwo

Anda dapat menambahkan file dan melakukan itu hanya ke satu file seperti ini:

git --git-dir=.gitone add test.txt
git --git-dir=.gitone commit -m "Test"

Jadi opsi untuk git muncul terlebih dahulu, lalu perintahnya, lalu opsi perintah git. Anda dapat dengan mudah menggunakan perintah git alias:

#!/bin/sh
alias gitone='git --git-dir=.gitone'
alias gittwo='git --git-dir=.gittwo'

Jadi, Anda dapat berkomitmen pada salah satunya dengan sedikit mengetik, seperti gitone commit -m "blah" .

Apa yang tampak lebih rumit adalah pengabaian. Karena .gitignore biasanya berada di root proyek, Anda harus menemukan cara untuk mengalihkannya juga tanpa mengalihkan seluruh root. Atau, Anda dapat menggunakan .git / info / exclude, tetapi semua pengabaian yang Anda lakukan tidak akan dilakukan atau didorong - yang dapat mengacaukan pengguna lain. Orang lain yang menggunakan repo mungkin mendorong .gitignore, yang dapat menyebabkan konflik. Tidak jelas bagi saya cara terbaik untuk menyelesaikan masalah ini.

Jika Anda lebih suka alat GUI seperti TortoiseGit, Anda juga akan menghadapi beberapa tantangan. Anda dapat menulis skrip kecil yang mengganti nama .gitone atau .gittwo menjadi .git untuk sementara agar asumsi alat ini terpenuhi.

Chris Moschini
sumber
1
Menyetelnya sebagai alias akan memunculkan kesalahan ini: $ git config --global alias.pub '--git-dir = ~ / Server / www / .gitpublic' $ git pub add. fatal: alias 'pub' mengubah variabel lingkungan Anda dapat menggunakan '! git' dalam alias untuk melakukan ini. Di mana Anda akan menyetel "! Git" dalam kasus ini?
JaredBroad
1
@JaredBroad Menarik - Saya menyarankan Anda menggunakan alias Bash, bukan alias git. Sepertialias gitone='git --git-dir=.gitone'
Chris Moschini
10
Anda dapat mengkonfigurasi repo untuk menggunakan file pengecualian mereka sendiri dan Anda dapat melacaknya, yaitu gitone config core.excludesfile gitone.excludedan gitone add gitone.exclude. Saya membuat skrip yang memperluas solusi ini: github.com/capr/multigit
2
@JaredBroad saya melakukannya seperti ini git config --global alias.youralias '!git --git-dir="/d/MyProject/_git"'maka git youralias status:)
starikovs
1
Jika Anda berasumsi bahwa .gitignorefile biasanya disetel-dan-lupa, Anda dapat membuat salinan berbeda untuk setiap repo, lalu menyalin versi yang relevan ke direktori sebagai bagian dari alias. Ini berlaku untuk file lain di root yang mungkin konflik, seperti README.mddan .gitattributes.
thdoan
15

Lihat submodul git .

Submodul memungkinkan repositori asing untuk disematkan dalam subdirektori khusus dari pohon sumber, selalu menunjuk ke komit tertentu.

Hates_
sumber
8
Tidak bagus untuk file yang harus berada di root direktori Anda. Satu-satunya kesempatan di sana, adalah mengisi root dari symlink ke ini.
WhyNotHugo
6

RichiH menulis alat yang disebut vcsh yang merupakan alat untuk mengelola dotfiles menggunakan repo git palsu untuk meletakkan lebih dari satu direktori kerja ke dalam $ HOME. Tidak ada hubungannya dengan csh AFAIK.

Namun, jika Anda memang memiliki beberapa direktori, alternatif untuk git-submodules (yang merepotkan dalam situasi terbaik dan penggunaan contoh ini bukanlah situasi terbaik) adalah gitslave yang membiarkan repo slave diperiksa di ujung a cabang setiap saat dan tidak memerlukan proses tiga langkah untuk membuat perubahan dalam repo anak perusahaan (checkout ke cabang yang benar, buat & lakukan perubahan, lalu masuk ke superproject dan lakukan komitmen submodul baru).

Seth Robertson
sumber
6

Dimungkinkan dengan menggunakan variabel GIT_DIRtetapi memiliki banyak peringatan jika Anda tidak tahu apa yang Anda lakukan.

tzervo.dll
sumber
4

Ya, submodul mungkin yang Anda inginkan. Pilihan lain adalah memiliki copy pekerjaan Anda di subdirektori dan kemudian mengarahkan symlink dari direktori home Anda ke file yang diinginkan.

Pat Notz
sumber
3

metode pilihan saya adalah menggunakan repo di subdir, dan menggunakan tautan simbolik rekursif:

git clone repo1
cd somerepo
git clone repo2
cd repo2
./build

di mana ' repo / build ' -file terlihat seperti:

#!/bin/bash 
SELF_PATH="$(dirname "$(readlink -f "$0")" )"  # get current dir 
cd .. && git stash && git clean -f -d ''       # remove previous symlinks
cp -sR "$SELF_PATH"/* ../.                     # create recursive symlinks in root

PERHATIAN : jangan gunakan 'git add.'

coderofsalvation
sumber
0

Pilihan lainnya adalah dengan mereka di folder terpisah dan membuat tautan keras simbolis dari satu folder ke folder lainnya.

Misalnya, jika ada repositori:

  1. Repo1 / FolderA
  2. Repo1 / FolderB

Dan:

  1. Repo2 / FolderC

Anda dapat menghubungkan folder FolderAdan FolderBdari Repo1 ke Repo2. Untuk windows, perintah untuk berjalan di Repo1 adalah:

User@Repo1$ mklink /J FullPath/Repo2/FolderA FullPath/Repo1/FolderA
User@Repo1$ mklink /J FullPath/Repo2/FolderB FullPath/Repo1/FolderB
User@Repo1$ printf "/FolderA/*\n/FolderB/*\n" >> .gitignore

Untuk file-file pada repositori utama Anda perlu menghubungkannya dengan symlink masing-masing, juga menambahkannya ke repositori .gitignoreuntuk menghindari gangguan, kecuali Anda menginginkannya.

pengguna
sumber
0

Penafian: Ini bukan iklan. Saya adalah pengembang perpustakaan yang disediakan.

Saya telah membuat ekstensi git untuk menangani kasus di mana Anda ingin menggabungkan banyak repositori ke dalam satu folder. Keuntungan dari lib adalah, untuk melacak repositori dan konflik file. Anda dapat menemukannya di github . Ada juga 2 contoh repositori untuk mencobanya.

pengguna1810087
sumber