.Git klasörünü izlenmesini istediğim dosyaların dışında saklayabilir miyim?


148

Git'i bir yedekleme sistemi olarak kullanmak için alışılmadık bir fikrim var. Diyelim ki bir dizinim var ./backup/myfiles ve bunu git kullanarak yedeklemek istiyorum. İşleri temiz tutmak için myfiles klasöründe bir .git dizini olmasını istemiyorum, bu yüzden ./backup/git_repos/myfiles oluşturabileceğimi düşündüm. Git belgelerine bakarak şunu yapmayı denedim:

$ cd backup/myfiles
$ mkdir ../git_repos/myfiles
$ git --git-dir=../git_repos/myfiles init
Initialized empty Git repository in backup/git_repos/myfiles/
$ git --git-dir="../git_repos/myfiles/" add foo
fatal: pathspec 'foo' did not match any files

Oraya aldığım hata mesajını görebilirsiniz. Neyi yanlış yapıyorum?


9
Yedekleme fikrinizin yanı sıra, bu, .git klasörünü başka bir yerde tutarken "dotfiles" dosyalarınızı (.bashrc, .vimrc, vb.) Ana dizinde tutmak için de kullanılabilir.
Philip

6
En doğru yanıt: stackoverflow.com/a/19548676/170352 (eski olumlu oylar nedeniyle gömülü)
Brandon Bertelsen

1
Hiçbir yazma erişimi olan veya olmayan (vb / .git ekleme gibi) çalışma dizini herhangi bir değişiklik yapmak istiyorsunuz Bu durumda, bu Leo aşağıda cevap (aynı zamanda eski upvotes tarafından toprağa) en iyisidir.
KobeJohn

1
@Philip, dotfiles deponuz da Git alt modülleri içermediği sürece. Git, harici bir çalışma ağacı ile birlikte alt modülleri desteklemez.
maxschlepzig

Yanıtlar:


100
git --git-dir=../repo --work-tree=. add foo

Bu, istediğinizi yapacak, ancak kullandığınız her git komutuyla bunu belirtmeniz gerektiğinde kesinlikle berbat olacaktır.

Dışa aktarabilirsiniz GIT_WORK_TREE=.ve GIT_DIR=../backupGit bunları her komutta alır. Yine de bu, kabuk başına tek bir depoda rahatça çalışmanıza izin verecektir.

.Git dizinini başka bir yere sembolik bağlamayı veya ana yedekleme dizininizden .git dizinine bir sembolik bağlantı oluşturmayı tercih ederim.


1
Her komutta git-dir ve çalışma ağacını belirtmeden ve herhangi bir sembolik bağlantı olmadan aynısını arşivleyebilirsiniz. Cevabımı gör.
niks

Bir sembolik bağın dezavantajı, çalışma ağacında var olmasıdır ve eğer başka bir süreç çalışma ağacını silerse, o zaman sembolik bağı kaybettiniz
Jeff

Ayrıca, OP çalışma ağacında bir .git alt dizini istemiyorsa, neden bir sembolik bağlantı istesin?
Jeff

@Jeff: bir değiş tokuş için. (Yedek durumunda, çalışma ağacını silmek onun için muhtemelen başka herhangi bir dizini (deponun kendisi gibi) silmekten daha büyük bir endişe kaynağı değildir.)
Sz.

1
Bunu notlarım için direnv ile birlikte kullanıyorum . Çalışma ağacım Dropbox'ta bir klasörde ve git klasörüm dışarıda bir yerde. Bu şekilde, değişikliklerimi tüm bilgisayarlarda kolayca yapabilirim, ancak yine de neyin değiştiğini kontrol edebilir ve yalnızca önemli bir şey değiştiğinde taahhüt edebilirim. Teşekkürler
Paulo Phagula

170

Sadece deponun çalışma ağacının nerede olduğunu bildiğinden emin olmanız gerekir ve bunun tersi de geçerlidir.

Deponun çalışma ağacının nerede olduğunu bilmesini sağlamak için konfigürasyon değerini ayarlayın core.worktree. Çalışma ağacının git dizininin nerede olduğunu bilmesini sağlamak için .git adlı bir dosya ekleyin (klasör değil!) Ve şöyle bir satır ekleyin:

gitdir: /path/to/repo.git

Git 1.7.5'ten beri init komutu bunun için ekstra bir seçenek öğrendi.

Yeni bir ayrı depoyu şu şekilde başlatabilirsiniz:

git init --separate-git-dir /path/to/repo.git

Bu, git deposunu ayrı dizinde başlatacak ve .git dosyasını yeni deponun çalışma dizini olan geçerli dizine ekleyecektir.

1.7.5 sürümünden önce, biraz farklı parametreler kullanmanız ve .git dosyasını kendiniz eklemeniz gerekiyordu.

Ayrı bir depoyu başlatmak için aşağıdaki komut çalışma ağacını havuza bağlar:

git --git-dir=/path/to/repo.git --work-tree=. init && echo "gitdir: /path/to/repo.git" > .git

Geçerli dizininiz çalışma ağacı olacak ve git adresindeki depoyu kullanacak /path/to/repo.git. İnit komutu, core.worktreedeğeri --git-dirparametre ile belirtildiği gibi otomatik olarak ayarlayacaktır .

Bunun için bir takma ad bile ekleyebilirsiniz:

[alias]
    initexternal = !"f() { git --work-tree=. --git-dir=\"$1\" init && echo \"gitdir: $1\" >> .git; }; f"

Git sürüm denetimini salt okunur bir çalışma dizininde kullanın

Yukarıdaki bilgilerle, yazma izinlerine sahip olmadan bir çalışma dizini için git sürüm kontrolünü bile kurabilirsiniz. Her iki kullanım Eğer varsa --git-dirher git komutu veya (yerine çalışma dizininin) depo içinde her komutu çalıştırmak, sen .git dosyayı bırakabilir ve bu nedenle çalışma dizinindeki herhangi dosyaları oluşturmak gerekmez. Leos cevabına da bakın


7
Bunu mevcut bir depoya da yapabilirsiniz: .git klasörünü istediğiniz yere taşıyın, .git dosyasını işaret edecek şekilde ekleyin ve sonra
depoyu

Git komutlarını yalnızca deponuzun kökünden verebileceğinizi unutmayın. Alt klasörlere gitmek kafayı karıştırır! (Bu, gitdir için verilen değerin göreceli veya mutlak olup olmadığına bakılmaksızın gerçekleşir.)
joachim

2
Bunun düzeltmesi, gerçek git yapılandırma dosyasında, yani .git olarak gösterdiğiniz klasördeki 'core.worktree'yi belirlemektir.
joachim

2
Evet, cevabımın ikinci cümlesinde anlattığım buydu. Yapılandırma değeri core.worktreeelbette .git klasörünün yapılandırma dosyasında saklanır, burada .git dosyası gösterilir.
niks

1
Bu talimatları kullandığımda yapılan deponun çıplak bir depo haline geldiğini ve hata verdiğini görüyorum fatal: core.worktree and core.bare do not make sense. Görünüşe göre sadece yapılandırmayı değiştirmek, bu yüzden bunu çözer.
Steven Lu

63

--separate-git-dirSeçeneği git init(ve git clone) Git benim sürümü (bu başarmak için kullanılabilir 1.7.11.3). Bu seçenek, git deposunu çalışma ağacından ayırır ve çalışma ağacının .gitkökünde bir dosya sistemi agnostik git sembolik bağlantısı (adlı bir dosya biçiminde ) oluşturur. Bence sonuç niks'in cevabı ile aynı .

git init --separate-git-dir path/to/repo.git path/to/worktree

3
+1 initKendisi için bir komut satırı seçeneği kullanmak daha net ve daha temiz görünüyor
goncalopp

pencerelerde, repo.githiden öznitelik kümesiyle oluşturulur. Daha sonra manuel olarak değiştiriyorum. Bunun güvenli olup olmadığını biliyor musun?
PA.

+1 Evet git bu komut satırı seçeneğini 1.7.5 sürümünde kullandı, o zamanlar mevcut değildi (doğru hatırlıyorsam). Bu parametreyi kullanmayı önermek için cevabımı güncelledim.
niks

25

Niks'in cevabında kullanılan --work-treeve --git-dirdizinleri tersine çevirmeyi daha kolay buluyorum :

$ cd read_only_repos
$ git --work-tree=/some/readonly/location/foo/ --git-dir=foo init
$ cd foo
$ git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        .file_foo
        bar
        ...

Bu yaklaşımın iki avantajı vardır:

  • Herhangi bir komut satırı seçeneğine veya .gitdosyaya sahip olma ihtiyacını ortadan kaldırır . Yalnızca deponun kök dizininden normal şekilde çalışırsınız.
  • Sahibi olmasanız bile bir dosya sistemini versiyonlamanıza izin verir. Git yalnızca depo konumuna yazacaktır.

Karşılaştığım tek uyarı, bir .gitignoredosya kullanmak yerine düzenlemeniz info/exclude.

Ardından read_only_repos/foo, orijinal dosyalar sürüm kontrolü altında olmasa bile depoyu kendi havuzlarınızda bir uzaktan kumanda olarak kullanabilirsiniz .


Peki bu tam olarak aynı komut. Gördüğüm tek fark, --work-tree ve --git-dir argümanlarının sırasını değiştirmiş olmanız. Ve elbette, yazma erişiminiz olmadığı için çalışma dizininde .git dosyasını oluşturmazsınız. Yine de, yazma erişimi olmayan bir dizin için sürüm kontrolü kullanmak güzel bir kullanım durumudur. :-)
niks

3
Anladın. Anahtar, depoyu çalışma dizininin dışında oluşturmaktır.
Leo

4
Bunu beğendim - Dropbox ile paylaştığım dizinlerde git kullanmama izin veriyor, diğer katılımcılar git'in kullanımda olduğunu bile bilmeden.
Quentin Stafford-Fraser

19

Git deposu olan ve çalışma ağacını alışılmadık bir yerde '.git' uzantısıyla, tıpkı çıplak depo gibi adlandırmak gelenekseldir.

mkdir ../git_repos/myfiles.git

Eğer --work-treeseçeneği init zamanında sağlamış olsaydınız, bu core.worktreeyapılandırma değişkenini otomatik olarak ayarlamış olurdu, bu da git'in git dizinini belirlediğinizde çalışma ağacını nerede bulacağını bileceği anlamına gelir.

git --git-dir=../git_repos/myfiles.git --work-tree=. init

Ama bu değişkeni olaydan sonra da ayarlayabilirsiniz.

git --git-dir=../git_repos/myfiles.git config core.worktree "$(pwd)"

Bunu yaptıktan sonra, add komutu beklendiği gibi çalışmalıdır.

git --git-dir=../git_repos/myfiles.git add foo

Gerçek çalışma ağacında olmak yerine önce ../git_repos/myfiles.git'e cd yaparsanız, 'git add foo' sadece çalışacaktır ve --git-dir all belirtmenize gerek yoktur zaman.
Steve Folly

1
Bu doğru, ancak bence çoğu insan depolarından ziyade çalışma ağacında çalışma eğiliminde. Elbette, bağımsız bir çalışma ağacı kullanıyorsanız, muhtemelen 'özel' bir şey yapıyorsunuzdur ve yardımcı olması için bazı makrolar kullanıyor olabilirsiniz.
CB Bailey

6

Depo gitiçinde kullanın :

cd ./backup/git_repos/myfiles
git init --bare
git config core.worktree ../myfiles
git config core.bare false

Bundan böyle, herhangi bir ortam değişkeni veya ek parametre ayarlamadan dizinin gitiçini kullanabilirsiniz ./backup/git_repos/myfiles.


Bu en iyi cevap gibi görünüyor, ancak mesajı alıyorum warning: core.bare and core.worktree do not make sensebu işe yaramadığı anlamına mı geliyor?
hazrpg

1
Hala işe yaradığını düşünüyorum, ancak çalışma ağacını kurarken çıplak olmaktan şikayet ediyor. Ben ayarlıyorum yüzden core.bareetmek falsesonra.
To1ne

Ah! Bu şimdi daha mantıklı. Bunun için teşekkürler.
hazrpg

1

Bir "nodgit" komut dosyası (No Dot GIT) oluşturabilirsiniz.

#!/bin/sh
gits=/usr/local/gits
    x=`pwd`
    testdir() {( cd $1; pwd; )}
    while [ "$x" != "/" ]; do
      y=`echo $x|sed -e "s/\//__/g"`
      if ([ -d "$gits/$y" ]); then
        export GIT_DIR="$gits/$y"
        export GIT_WORK_TREE="$x"
        if ([ "$1" = "nodinit" ]); then
          mkdir -p "$GIT_DIR"
          git init --bare; exit $?
        elif ([ "$1" = "shell" ]); then
          bash; exit $?
        else
          exec git "$@"
        fi
      fi
      x=`testdir "$x/.."`
    done

Git yerine nodgit çağırabilirsiniz ve bir git deposu arayarak değişkenleri gerektiği gibi ayarlayacaktır. Örneğin / usr / local / gits / __ home__foo_wibbles içinde bir (çıplak) deponuz olduğunu ve / home / foo / wibbles / one içinde olduğunuzu ve ardından doğru çalışma dizinini (/ home / foo / wibbles) ve repo'yu bulacağını varsayalım. .

Oh, "nodgit shell" komutunu da doğru değişken setine sahip bir kabuk elde etmek için kullanabilirsiniz, böylece düz eski git komutlarını kullanabilirsiniz.


0

myfilesDizinlerinizin zaten var olduğunu ve bazı içeriğe sahip olduğunu varsayarsak, bununla yaşayabilir misiniz:

cd ~/backup
git init
git add myfiles

.gitDizin olacak backupdeğil, myfiles.


Bu istediğimi düzeltmek olsa da, myfiles klasörünü git altında saklamayı tercih ederim, başka hiçbir şey yapmam.
Rory

Dosyayı gitkullanarak izlemek istediğiniz dosyaların bir bölümünü saklayabilirsiniz .gitignore. Eklemek isterseniz *ve !myfilesbuna, sadece bu dizin izlenir. Ancak başka bir dizin için ayrı bir depo istiyorsanız, bir sorunla karşılaşırsınız ...
To1ne

0

Gibi görünen komut dosyaları oluşturuyorum

~ / bin / git-slash:

#!/usr/bin/sh

export GIT_DIR=/home/Version-Control/cygwin-root.git/
export GIT_WORK_TREE=/

git --git-dir=$GIT_DIR --work-tree=$GIT_WORK_TREE "$@"

exit $?

--Git_dir = $ GIT_DIR kullanmak gereksizdir, ancak betiğin dışındaki ortam değişkenlerini de ayarlayabileceğimi hatırlatır.

Yukarıdaki örnek, cygwin sistem dosyalarındaki yerel değişiklikleri izlemek içindir.

Buna ihtiyaç duyan herhangi bir büyük proje için böyle bir komut dosyası yapabilir - ancak /.git olmadan /.git ana kullanımımdır.

Yukarıdakiler, fazlalığı ortadan kaldırırsanız, bir kabuk diğer adı veya işlevi oluşturacak kadar küçüktür.

Bunu yeterince sık yaparsam, çalışma alanını depo eşlemesi için yeniden canlandırırım.

"Boxes, Links, and Parallel Trees: Elements of a Configuration Management System", 
in Workshop Proceedings of the Software Management Conference. 1989.

en yakın modern muadili Perforce eşlemeleri veya görünümleri olan , kısmi kontrollerin yanı sıra çalışma alanı ve deponun birlikte yerleştirilmemesini destekleyen.

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.