Mercurial, (.hg içeren) kök dizini üzerinden
hg root
Git'de .git dizinini içeren dizini almak için eşdeğer bir şey var mı?
bzr root
Bazaar'da çok kullanıldı
Mercurial, (.hg içeren) kök dizini üzerinden
hg root
Git'de .git dizinini içeren dizini almak için eşdeğer bir şey var mı?
bzr root
Bazaar'da çok kullanıldı
Yanıtlar:
Evet:
git rev-parse --show-toplevel
Git komutunu daha doğrudan çoğaltmak istiyorsanız, bir takma ad oluşturabilirsiniz :
git config --global alias.root 'rev-parse --show-toplevel'
ve şimdi git root
olduğu gibi çalışacak hg root
.
Not : Bir altmodülün bu kök dizinini görüntüler altmodülün ve değil ana deposu. Git> = 2.13 veya üstünü kullanıyorsanız, alt modüllerin süper projenin kök dizinini gösterebilmesinin bir yolu vardır . Gitiniz bundan daha eskiyse, diğer cevaba bakınız.
git config --global alias.exec '!exec '
ki böyle şeyler yapabilirim git exec make
. Kabuk diğer adları her zaman üst düzey dizinde yürütüldüğünden bu çalışır.
hg root
böyle. Teslim alınmış deponuzun üst düzey dizinini yazdırır. Sizi buna geçirmez (ve aslında, geçerli dizinin ve kabuğunuzun tüm kavramının nasıl etkileştiği nedeniyle bunu yapamazdı).
~/my.proj/foo/bar
ve ~/my.proj
simgesine bağlanmışsanız ~/src/my.proj
, yukarıdaki komut sizi konumuna götürecektir ~/src/my.proj
. Bir sorun olabilir, eğer bundan sonra ne yapmak isterseniz ağaç agnostik değilse.
.git
dizininde olduğunuzda çalışmaz .
man
Sayfa git-config
(altında Alias'ın ) diyor ki:
Takma ad genişletmesinin önüne bir ünlem işareti gelirse, kabuk komutu olarak değerlendirilir. [...] Kabuk komutlarının, geçerli dizinin olması gerekmeyen bir deponun üst düzey dizininden yürütüleceğini unutmayın.
Böylece, UNIX'te şunları yapabilirsiniz:
git config --global --add alias.root '!pwd'
.zshrc
ve `alias cg =" cd $ (git root) "tanımlıyorsam, $ () kısmı kaynak zamanında değerlendirilir ve her zaman ~ / dotfiles'a işaret eder, zshrc'm olduğu yerde .
Has --show-toplevel
ancak son zamanlarda eklenmiş git rev-parse
ya da neden kimse bunu söz edilir?
Gönderen git rev-parse
adam sayfası:
--show-toplevel
Show the absolute path of the top-level directory.
git-rev-parse
- çünkü adı revizyon spesifikasyonlarını işlemeyle ilgili olduğunu gösteriyor. BTW, şuna git --work-tree
benzer bir iş gördüğüme sevinirim git --exec-path[=<path>]
: "Eğer yol belirtilmemişse git geçerli ayarı yazdıracaktır"; en azından IMO, böyle bir özelliği aramak mantıklı bir yer olurdu.
root = rev-parse --show-toplevel
gitconfig'nizde takma ad kullanabilirsiniz.
git config --global alias.root "rev-parse --show-toplevel"
ve daha sonra git root
işi yapabilirsiniz
git rev-parse --show-toplevel
bir alt modülde denediğimde çalışır. Git alt modülünün kök dizinini yazdırır. Sizin için ne yazdırıyor?
--show-cdup
etmek --show-top-level
(Bu cevap sunuldu sonra) Şubat 2011 yılında.
Peki ya " git rev-parse --git-dir
"?
F:\prog\git\test\copyMerge\dirWithConflicts>git rev-parse --git-dir
F:/prog/git/test/copyMerge/.git
--git-dir
Opsiyon çalışmaları gibi görünüyor.
Gönderen git rev-ayrıştırma manuel sayfa :
--git-dir
Show $GIT_DIR if defined else show the path to the .git directory.
Bu git setup-sh
komut dosyasında çalışırken görebilirsiniz .
Bir alt modül klasöründeyseniz Git> = 2.13 ile şunları kullanın :
git rev-parse --show-superproject-working-tree
Kullanıyorsanız git rev-parse --show-toplevel
, Git 2.25+ (Q1 2020) ile olduğundan emin olun .
.git
zaten kök dizinde iseniz için göreceli bir yol veriyor gibi görünüyor . (En azından msysgit için geçerli.)
Burada basit bir cevap yazmak için,
git root
işi yapmak için git tuşunu kullanarak
git config --global alias.root "rev-parse --show-toplevel"
ve ardından aşağıdakileri eklemek isteyebilirsiniz ~/.bashrc
:
alias cdroot='cd $(git root)'
böylece cdroot
deponuzun en üstüne gitmek için kullanabilirsiniz .
Zaten üst düzeydeyseniz veya git deposunda cd $(git rev-parse --show-cdup)
değilseniz, sizi eve götürecektir (sadece cd). cd ./$(git rev-parse --show-cdup)
bunu düzeltmenin bir yoludur.
cd "$(git rev-parse --show-cdup)"
. Bu işe yarar çünkü cd ""
sizi geri değil, hiçbir yere götürmez $HOME
. Ve yine de boşluklarla bir şeyler çıkarmaları durumunda $ () çağrılarını alıntılamak en iyi uygulamadır (bu durumda bu komutun değil).
$PWD
. Bu örnek git $PWD
yerine ' nin kökünü çözecektir realpath $PWD
.
Geçerli git kök dizininin mutlak yolunu hesaplamak için, bir kabuk komut dosyasında kullanmayı diyelim, şu readlink ve git rev-parse birleşimini kullanın:
gitroot=$(readlink -f ./$(git rev-parse --show-cdup))
git-rev-parse --show-cdup
cwd'nizden köke ulaşmak için doğru sayıda ".." s veya kökteyseniz boş dize verir. Ardından, boş dize durumuyla başa çıkmak için "./" başlığını kullanın readlink -f
ve tam yola çevirmek için kullanın
.
git-root
Bu tekniği uygulamak için PATH'nizde kabuk komut dosyası olarak da bir komut oluşturabilirsiniz :
cat > ~/bin/git-root << EOF
#!/bin/sh -e
cdup=$(git rev-parse --show-cdup)
exec readlink -f ./$cdup
EOF
chmod 755 ~/bin/git-root
(Yukarıda, git-root oluşturmak ve yürütme bitlerini ayarlamak için bir terminale yapıştırılabilir; gerçek komut dosyası 2, 3 ve 4. satırlardadır.)
Ve sonra git root
mevcut ağacınızın kökünü almak için koşabilirsiniz . Kabuk betiğinde, rev-ayrıştırma başarısız olursa kabuğun çıkmasına neden olmak için "-e" komutunu kullanın, böylece bir git dizininde değilseniz çıkış durumunu ve hata iletisini düzgün bir şekilde alabilirsiniz.
"$(git rev-parse ...)"
Gibi kesmek yerine her zaman kullanın ./$(git rev-parse ...)
.
Diğerlerinin belirttiği gibi, çözümün çekirdeği kullanmaktır git rev-parse --show-cdup
. Ancak, ele alınması gereken birkaç önemli durum vardır:
Cwd zaten çalışma ağacının kökü olduğunda, komut boş bir dize verir.
Aslında boş bir satır oluşturur, ancak komut ikamesi sondaki satır sonunu kaldırır. Nihai sonuç boş bir dizedir.
Çoğu yanıt, ./
boş bir çıktının "./"
beslenmeden önce olması için çıktının önceden eklenmesini önerir cd
.
GIT_WORK_TREE, cwd'nin üst öğesi olmayan bir konuma ayarlandığında, çıktı mutlak bir yol adı olabilir.
./
Bu durumda hazırlık yapmak yanlıştır. A ./
mutlak bir yola eklenirse, göreli bir yol olur (ve yalnızca cwd sistemin kök dizini ise aynı konuma başvurur).
Çıktıda boşluk olabilir.
Bu gerçekten sadece ikinci durumda geçerlidir, ancak kolay bir düzeltmeye sahiptir: komut ikamesi (ve değerin sonraki kullanımları) etrafında çift tırnak kullanın.
Diğer cevapların belirttiği gibi, yapabiliriz cd "./$(git rev-parse --show-cdup)"
, ancak bu ikinci kenar durumunda (ve çift tırnaklardan ayrılırsak üçüncü kenar durumunda) kırılır.
Birçok mermi hareketsiz cd ""
olarak kabul edilir, bu yüzden yapabileceğimiz mermiler için cd "$(git rev-parse --show-cdup)"
(çift tırnak boş dizeyi birinci kenar durumunda bir argüman olarak korur ve üçüncü kenar durumunda boşlukları korur). POSIX, sonucunun cd ""
belirsiz olduğunu söylüyor , bu nedenle bu varsayımı yapmaktan kaçınmak en iyisi olabilir.
Yukarıdaki tüm durumlarda çalışan bir çözüm, bir tür test gerektirir. Açıkça yapıldı, şöyle görünebilir:
cdup="$(git rev-parse --show-cdup)" && test -n "$cdup" && cd "$cdup"
cd
İlk kenar kasası için hayır yapılır.
cd .
İlk kenar durumu için çalışmak kabul edilebilirse , koşul parametrenin genişletilmesinde yapılabilir:
cdup="$(git rev-parse --show-cdup)" && cd "${cdup:-.}"
git root
' kullanmıyorsunuz?
Bu yolu Git'in kendisine doğru besliyorsanız, :/
# this adds the whole working tree from any directory in the repo
git add :/
# and is equal to
git add $(git rev-parse --show-toplevel)
Alt modüllerle, kancalarda ve .git
dizinin içinde çalışan kısa çözümler
İşte çoğunun isteyeceği kısa cevap:
r=$(git rev-parse --git-dir) && r=$(cd "$r" && pwd)/ && echo "${r%%/.git/*}"
Bu, git çalışma ağacında ( .git
dizinin içi dahil ) herhangi bir yerde çalışır , ancak havuz dizinlerinin çağrıldığını varsayar .git
(varsayılan değerdir). Alt modüller ile, bu en dıştaki deponun köküne gider.
Geçerli alt modülün köküne ulaşmak istiyorsanız:
echo $(r=$(git rev-parse --show-toplevel) && ([[ -n $r ]] && echo "$r" || (cd $(git rev-parse --git-dir)/.. && pwd) ))
Alt modül kökünüzde, altında [alias]
bulunan bir komutu kolayca yürütmek için şunu .gitconfig
ekleyin:
sh = "!f() { root=$(pwd)/ && cd ${root%%/.git/*} && git rev-parse && exec \"$@\"; }; f"
Bu, aşağıdakileri kolayca yapmanızı sağlar: git sh ag <string>
Farklı adlandırılmış veya harici .git
veya $GIT_DIR
dizinleri destekleyen sağlam çözüm .
Not $GIT_DIR
yerde dış işaret edebilir (ve çağrılacak .git
kez daha gözden dolayısıyla ihtiyaç).
Bunu şuna ekle .bashrc
:
# Print the name of the git working tree's root directory
function git_root() {
local root first_commit
# git displays its own error if not in a repository
root=$(git rev-parse --show-toplevel) || return
if [[ -n $root ]]; then
echo $root
return
elif [[ $(git rev-parse --is-inside-git-dir) = true ]]; then
# We're inside the .git directory
# Store the commit id of the first commit to compare later
# It's possible that $GIT_DIR points somewhere not inside the repo
first_commit=$(git rev-list --parents HEAD | tail -1) ||
echo "$0: Can't get initial commit" 2>&1 && false && return
root=$(git rev-parse --git-dir)/.. &&
# subshell so we don't change the user's working directory
( cd "$root" &&
if [[ $(git rev-list --parents HEAD | tail -1) = $first_commit ]]; then
pwd
else
echo "$FUNCNAME: git directory is not inside its repository" 2>&1
false
fi
)
else
echo "$FUNCNAME: Can't determine repository root" 2>&1
false
fi
}
# Change working directory to git repository root
function cd_git_root() {
local root
root=$(git_root) || return 1 # git_root will print any errors
cd "$root"
}
Yazarak bunu yürütün git_root
(kabuğun yeniden başlattıktan sonra: exec bash
)
(root=$(git rev-parse --git-dir)/ && cd ${root%%/.git/*} && git rev-parse && pwd)
ancak bu, $GIT_DIR
aşağıdakiler dışında adlandırılan harici s'yi kapsamaz.git
Bunu yapmak için iyi bir takma ad arıyorsanız, cd
git dir'de değilseniz havaya uçmazsanız:
alias ..g='git rev-parse && cd "$(git rev-parse --show-cdup)"'
git-extras
ekler $ git root
bkz. https://github.com/tj/git-extras/blob/master/Commands.md#git-root
$ pwd
.../very-deep-from-root-directory
$ cd `git root`
$ git add . && git commit
$ brew install git-extras
$ apt-get install git-extras
Bu kabuk diğer adı, git alt dizininde veya en üst düzeyde olsanız da çalışır:
alias gr='[ ! -z `git rev-parse --show-toplevel` ] && cd `git rev-parse --show-toplevel || pwd`'
backticks yerine modern sözdizimini kullanacak şekilde güncellendi:
alias gr='[ ! -z $(git rev-parse --show-toplevel) ] && cd $(git rev-parse --show-toplevel || pwd)'
alias git-root='cd \`git rev-parse --git-dir\`; cd ..'
Diğer her şey bir noktada ya ana dizine gidiyor ya da sadece sefil başarısız oluyor. Bu, GIT_DIR'e geri dönmenin en hızlı ve en kısa yoludur.
$GIT_DIR
kullanılarak çalışma .git
ağacından ayrıldığında bu başarısız olur gitdir: SOMEPATH
. Sonuç olarak bu, alt modüller için de başarısız olur.$GIT_DIR
içerdiği.git/modules/SUBMODULEPATH
.
İşte her iki durumu da işleyen bir senaryo: 1) bir çalışma alanı ile depo, 2) çıplak depo.
https://gist.github.com/jdsumsion/6282953
git-root
(yolunuzdaki yürütülebilir dosya):
#!/bin/bash
GIT_DIR=`git rev-parse --git-dir` &&
(
if [ `basename $GIT_DIR` = ".git" ]; then
# handle normal git repos (with a .git dir)
cd $GIT_DIR/..
else
# handle bare git repos (the repo IS a xxx.git dir)
cd $GIT_DIR
fi
pwd
)
Umarım bu yardımcı olur.
git exec
fikrin çıplak olmayan depolarda daha yararlı olduğunu fark ettim . Ancak, cevabımdaki bu komut dosyası, çıplak veya çıplak olmayan bir davayı doğru bir şekilde işliyor, bu da birine faydalı olabilir, bu yüzden bu yanıtı burada bırakıyorum.
git submodule
s içinde başarısız . Ayrıca, dizinin çıplak olmayan durumda çalışma ağacının bir parçası olduğunu varsayarsınız . $GIT_DIR
/.git/modules/SUBMODULE
.git
$ git config alias.root '!pwd'
# then you have:
$ git root
[alias] findroot = "!f () { [[ -d ".git" ]] && echo "Found git in [
pwd ]" && exit 0; cd .. && echo "IN
pwd" && f;}; f"
git config --global alias.root '!pwd'
çalışıyor. Küresel olmayan varyanttan farklı davrandığı hiçbir vakayı tespit edemedim. (Unix, git 1.7.10.4) BTW: Sonsuz findroot
bir tekrardan /.git
kaçınmak için a'ya ihtiyacınız var .
Git 2.13.0'dan bu yana , bir alt modülün içinden kullanıldığında bile çalışan kök projesinin yolunu göstermek için yeni bir seçeneği destekler:
git rev-parse --show-superproject-working-tree
Kabuk çerçevesi kullanıyorsanız, zaten bir kabuk takma adı olabilir:
$ grt
içinde oh-my-zsh (68k) ( cd $(git rev-parse --show-toplevel || echo ".")
)$ git-root
içinde prezto (8.8k) (görüntüler çalışma ağaç köküne yolu)$ g..
zimfw (1k) (geçerli dizini çalışma ağacının en üst düzeyine değiştirir.)Daniel Brockman'ın mükemmel yorumunu genişletmek istedim.
Tanımlama git config --global alias.exec '!exec '
, aşağıdaki gibi şeyler yapmanızı sağlar git exec make
, çünkü man git-config
durumlar:
Takma ad genişletmesinin önüne bir ünlem işareti gelirse, kabuk komutu olarak değerlendirilir. [...] Kabuk komutlarının, geçerli dizinin olması gerekmeyen bir deponun üst düzey dizininden yürütüleceğini unutmayın.
Ayrıca $GIT_PREFIX
, bir deponun en üst düzey dizinine göre geçerli dizinin yolu olacağını bilmek de kullanışlıdır . Ancak, bunun savaşın sadece yarısı olduğunu bilmek ™. Kabuk değişken genişletmesi kullanımı oldukça zorlaştırır. Bu yüzden bash -c
böyle kullanmanızı öneririz :
git exec bash -c 'ls -l $GIT_PREFIX'
diğer komutlar şunları içerir:
git exec pwd
git exec make
Herkesin bunu yapmak için POSIX uyumlu bir yola ihtiyaç duyması durumunda, git
yürütülebilir dosya gerekmez:
#$1: Path to child directory
git_root_recurse_parent() {
# Check if cwd is a git root directory
if [ -d .git/objects -a -d .git/refs -a -f .git/HEAD ] ; then
pwd
return 0
fi
# Check if recursion should end (typically if cwd is /)
if [ "${1}" = "$(pwd)" ] ; then
return 1
fi
# Check parent directory in the same way
local cwd=$(pwd)
cd ..
git_root_recurse_parent "${cwd}"
}
git_root_recurse_parent
Sadece bir komut dosyasının parçası olarak işlevselliği istiyorsanız, shebang'ı kaldırın ve son git_root_recurse_parent
satırı aşağıdakiyle değiştirin :
git_root() {
(git_root_recurse_parent)
}
if
ifadenin özyinelemede dizini değiştirip değiştirmediğinizi kontrol etmesi gerekiyordu. Aynı dizinde kalırsa, bir yere yapıştığınızı varsayar (örn. /
) Ve frenlerin tekrarını sağlar. Hata düzeltildi ve şimdi beklendiği gibi çalışmalı. Gösterdiğiniz için teşekkürler.
Bunu bugün kendim çözmek zorunda kaldım. Bir program için ihtiyaç duyduğum gibi C # 'da çözüldü, ama sanırım esily yeniden yazılabilir. Bu Kamusal Alan'ı düşünün.
public static string GetGitRoot (string file_path) {
file_path = System.IO.Path.GetDirectoryName (file_path);
while (file_path != null) {
if (Directory.Exists (System.IO.Path.Combine (file_path, ".git")))
return file_path;
file_path = Directory.GetParent (file_path).FullName;
}
return null;
}