git git dizininde değilken çekme


308

Diyelim ki /X/Ybir git depomuz olan bir dizinim var. Bir şekilde git pulliçeriden olduğu gibi bir dizini /Xhedeflemek ama /X/Ydizini hedeflemek mümkün mü ?

EDIT: Sanırım özellikle merak ediyordum: bunu git komutunu kullanarak yapmak mümkün, ama dizinleri değiştirmek zorunda kalmadan?

NOT: VonC'nin cevabını , önceki seçeneklerden çok daha zarif olduğu için kabul ettim . Git'i 1.8.5'ten daha yaşlı çalışanlar için lütfen aşağıdaki bstpierre'nin cevabına bakın .


2
GIT_DIR ayarını kaldırmadıkça bir kanca içinde git-pull kullanırken işe yaramayacağını eklemek istiyorum. İlgili.
zpmorgan

Git 1.8.5 (Q4 2013) 'den başlayarak "git komutunu kullanabilirsiniz, ancak dizinleri değiştirmek zorunda kalmadan". Aşağıdaki cevabımı
VonC

Yanıtlar:


453

Git 1.8.5 (Q4 2013) 'den başlayarak "Git komutunu kullanabilirsiniz, ancak dizinleri değiştirmek zorunda kalmadan".

Tıpkı " make -C <directory>", " git -C <directory> ..." Başka bir şey yapmadan önce oraya gitmek Git söyler .

Bkz 44e1e4 taahhüt tarafından Nazri Ramliy :

Geçerli dizinden ayrılmadan Git komutunu farklı bir dizinde çağırmak için daha fazla tuşa basmak gerekir:

  1. (cd ~/foo && git status)
    git --git-dir=~/foo/.git --work-tree=~/foo status
    GIT_DIR=~/foo/.git GIT_WORK_TREE=~/foo git status
  2. (cd ../..; git grep foo)
  3. for d in d1 d2 d3; do (cd $d && git svn rebase); done

Yukarıda gösterilen yöntemler komut dosyası oluşturma için kabul edilebilir, ancak hızlı komut satırı çağrıları için çok kullanışsızdır.

Bu yeni seçenekle yukarıdakiler daha az tuşa basarak yapılabilir:

  1. git -C ~/foo status
  2. git -C ../.. grep foo
  3. for d in d1 d2 d3; do git -C $d svn rebase; done

Git 2.3.4'ten (Mart 2015) beri ve Karthik Nayak ( KarthikNayak) tarafından 6a536e2 taahhüdünden beri , git" git -C '<path>'" boş olduğunda " hayır " olarak değerlendirilecektir .<path>

' git -C ""' yararsız bir şekilde " Cannot change to ''" hatasıyla ölürken , kabuk "" "cd'sini işlem yok olarak kabul eder.
Kabuğun davranışını emsal olarak alarak, git-C "" 'yi de op-olmayan olarak tedavi etmeyi öğretin .


4 yıl sonra Git 2.23 (3Ç 2019) ' git -C ""' çalışan ve dizini değiştirmeyen belgeler

6a536e2'den beri davranıyor ( git: " git -C '<path>'" <path>boş olduğunda hiç işlem yapma, 2015-03-06, Git v2.3.4).

Bu şu anda (nihayet) belgelerin şunları içerdiği anlamına gelir :

' <path>' Mevcut ancak boşsa, örneğin -C "", geçerli çalışma dizini değişmeden kalır.


Bu görebilirsiniz git -Cbir örnek olarak, Git 2.26 (Q1 2020 yılında) ile birlikte kullanılabilir.

Bkz. Taahhüt b441717 , taahhüt 9291e63 , taahhüt 5236fce , taahhüt 10812c2 , taahhüt 62d58cd , taahhüt b87b02c , taahhüt 9b92070 , taahhüt 3595d10 , taahhüt f511bc0 , taahhüt f6041ab , taahhüt f46c243 , taahhüt 99c049b , taahhüt f511bc0 , taahhüt f6041ab , taahhüt 7717242 , taahhüt: 208bb ) tarafından Denton Liu ( Denton-L) .
(Göre Birleştirilmiş - Junio Cı Hamano gitster- içinde 381e8e9 tamamlama 2020 05 Şubat)

t1507: Çizgide full_name()

İmzalayan: Denton Liu

Daha önce koşuyorduk test_must_fail full_name. Ancak, test_must_failyalnızca git komutlarında kullanılmalıdır. Doğrudan komut üzerinde kullanabilmemiz için
satır içi .full_name()test_must_failgit

Ne zaman full_name()kullanılmaya başlanan 28fb84382b ( "tanıtın <branch>@{upstream}notasyonu", Git v1.7.0-rc0 2009-09-10 - birleştirme ), git -Co gelmesinden itibaren seçeneği (mevcut değildi henüz 44e1e4d67d (" git: Verilen bir dizinde çalıştırın -C seçeneği ile ", 2013-09-09, Git v1.8.5-rc0 - toplu iş # 5'de listelenen birleştirme )). Sonuç olarak, yardımcı işlev her seferinde manuel olarak yapılması gereğini ortadan kaldırdı . Ancak, şu anda mevcut olduğundan , bunun yerine ve satır içi kullanabilirsiniz .
cdgit -Cfull_name()


6
Vay güzel! Bu çok daha zarif, bu yüzden gelecekteki izleyiciler için kabul edildiğini işaretleyeceğim.
Gavin Anderegg

1
Benim için çalışmıyor: # git --version && git -C ~ / .m2 / checkout master git sürüm 1.8.3.4 (Apple Git-47) Bilinmeyen seçenek: -C kullanımı: git [--version] [--help ] [-c ad = değer] [--exec-yol [= <yol>]] [--html-yol] [--man-yol] [--info-yol] [-p | --paginat | --no-pager] [--no-replace-objects] [- çıplak] [--git-dir = <yol>] [- iş ağacı = <yol>] [- ad alanı = <ad> ] <komut> [<args>]
Jan Galinski

7
@ JanGalinski Ama "Git 1.8.5'i başlatmaktan" bahsettim. Yani git 1.8.3.x bu seçenek hakkında henüz bir şey bilmiyordu.
VonC

2
Ubuntu 12.04'te daha yeni bir git sürümü kurmak zorunda kaldım. Ben böyle yaptım: apt-get install software-properties-common python-software-propertiessonra git repo ekleyin add-apt-repository ppa:git-core/ppa. Son adım git: 'i güncellemektir apt-get update && apt-get upgrade.
ph3nx


54

Düzenle :

Ya bir hata var ya git pullda bu komutla yapmaya çalıştığınız şeyi yapamazsınız. Sen olabilir ancak alıp birleştirme ile yapmak:

cd /X
git --git-dir=/X/Y/.git fetch
git --git-dir=/X/Y/.git --work-tree=/X/Y merge origin/master

Orijinal cevap :

Eğer bash veya benzeri koştuğunuz varsayalım (cd /X/Y; git pull).

Git adam sayfası bazı değişkenler yardımcı olmalıdır gibi görünebilir ( "Git depo" bölümüne bakınız) belirtir, ama onları (benim depo içinde / tmp / ggg2 ile) hemen işe yapamaz:

GIT_WORK_TREE=/tmp/ggg2 GIT_DIR=/tmp/ggg2/.git git pull
fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.

Cwd'm / tmp repo'yu güncellerken aşağıdaki komutu çalıştırmak, ancak güncellenen dosya / tmp / çalışma alanı / tmp / ggg2 yerine / tmp içinde görünür:

GIT_DIR=/tmp/ggg2/.git git pull

Ayrıca ve işaretlerini gösteren benzer bir sorunun bu cevabına da bakınız .--git-dir--work-tree


Yalnızca GIT_WORK_TREE ürününü kullanmayı denediniz mi?
Arrowmaster

@Arrowmaster: evet, bunu yaparsanız git .gitdizini bulamıyor .
bstpierre

Tamam, man sayfası, GIT_DIR ayarlanmamışsa GIT_WORK_TREE'nin kullanılmadığını söylüyor. Her ikisi de kullanıldığında o zaman çalışmıyor olması tuhaf görünüyor.
Arrowmaster

@Arrowmaster: Burada bir yerde bir hata olup olmadığını merak etmeliyim. Eğer yaparsam git --git-dir=/tmp/ggg2/.git --work-tree=/tmp/ggg2 pull, bir hata mesajı alıyorum. Ama eğer git --git-dir=/tmp/ggg2/.git --work-tree=. pull/ tmp'deyken yaparsam, güncellenmiş dosyaları / tmp içine olması gerektiği gibi koyar.
bstpierre

@bstpierre: Şu an yüklü git ile bir sisteme erişim yok ama ben ile diğer alternatifleri çalışıyor olurdu yaptıysam --work-treegibi hemen --work-tree=/tmp/ggg2/ve --work-tree=/tmp/ggg2/.beri onun yolunu ayrıştırma nasıl bir sorun olabilir.
Arrowmaster

32

Bir bash betiğine veya git takma adına sarabilirsiniz:

cd /X/Y && git pull && cd -

1
Bu kesinlikle hile yapar, ama git komutunu dizinleri değiştirmeden kullanmanın bir yolu olup olmadığını merak ediyorum. Ben olmadığını düşünmeye başlıyorum.
Gavin Anderegg

1
ve pushd/popdçifti yerine kullanıncd/cd-
axd

Veya cd'yi geri almak zorunda kalmamak için bir alt kabuk kullanabilirsiniz:(cd xyz && git pull)
jarmod

30

Bu yazı biraz eski yani olabilir bir hata vardı ve düzeltildi, ama ben sadece bunu yaptım:

git --work-tree=/X/Y --git-dir=/X/Y/.git pull origin branch

Ve işe yaradı. Dotfile ve üst dizini istediğini anlamak için bir dakikamı aldı (standart bir kurulumda her zaman üst / alt olan ancak TÜM kurulumlarda olmayanlar), bu yüzden açıkça belirtilmelidirler.


Bu çözümü beğendim çünkü \\ remotemachine \ C $ \ folder \ etc gibi dizinlerle çalışıyor
twasbrillig

7

Bazı sunucularım eski bir Ubuntu LTS versiyonunda olduğundan, git'i en son sürüme kolayca yükseltemiyorum (bazı cevaplarda açıklandığı gibi -C seçeneğini destekler).

Bu hile benim için iyi çalışıyor, özellikle sizi başladığınız yerden farklı bir dizinde bırakan diğer cevapların yan etkisi olmadığından.

pushd /X/Y
git pull
popd

Veya tek astar olarak yapmak:

pushd /X/Y; git pull; popd

Hem Linux hem de Windows'ta push ve popd komutları vardır.


5

Kombinasyonunu kullanarak pushd, git pullve popdbiz bu işlevselliği elde edebilirsiniz:

pushd <path-to-git-repo> && git pull && popd

Örneğin:

pushd "E:\Fake Directory\gitrepo" && git pull && popd

bu harika. Mükemmel çalışıyor
Stretch0

4

Bunun gibi bir komut dosyası yazabilirsiniz:

cd /X/Y
git pull

Buna benzer bir ad verebilirsiniz gitpull.
İsterseniz bunun yerine rastgele dizinler yapmasını tercih ederseniz /X/Y:

cd $1
git pull

Sonra gitpull /X/Z
son olarak, depoları bulmayı deneyebilirsiniz. ~/gitDepoları içeren bir klasör var ve hepsini çekmek için kullanabilirsiniz.

g=`find /X -name .git`
for repo in ${g[@]}
do
    cd ${repo}
    cd ..
    git pull
done

2
Komut satırından yapmak istiyorum, sadece bir kabuktaki bunu: (cd /X/Y && git pull).
Cascabel

2

Benim gibi uzak bir sunucuda drush (Drupal shell) komutuyla bunu yapmaya çalışan herkes için, çalışma dizinine CD yapmanızı gerektiren çözümü kullanamazsınız:

Bunun yerine, çekmeyi bir getirme ve birleştirme işlemine ayıran çözümü kullanmanız gerekir:

drush @remote exec git --git-dir=/REPO/PATH --work-tree=/REPO/WORKDIR-PATH fetch origin
drush @remote exec git --git-dir=/REPO/PATH --work-tree=/REPO/WORKDIR-PATH merge origin/branch

1

Bu benzer bir sorun olabilir, ancak komutlarınızı zincirleyebilirsiniz. Örneğin

Bir satırda

cd ~/Sites/yourdir/web;git pull origin master

Veya SSH ile.

ssh username@atyourserver.com -t "cd ~/Sites/thedir/web;git pull origin master"
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.