Apakah ada cara untuk mendapatkan direktori git root dalam satu perintah?

670

Mercurial memiliki cara mencetak direktori root (yang berisi .hg) via

hg root

Apakah ada sesuatu yang setara di git untuk mendapatkan direktori yang berisi direktori .git?

Wojo
sumber
Skrip Emil yang bagus. Saya membuat skrip tersedia secara online, dan memungkinkan kemungkinan untuk menambahkan file / direktori sebagai argumen. github.com/Dieterbe/git-scripts/commit/…
Dieter_be
Juga bagi siapa pun yang ingin tahu atau mencari bzr rootbanyak digunakan di Bazaar
Kristopher Ives
Harap perhatikan 'gcd': Git-Aware 'cd' Relatif terhadap Repositori Root dengan Auto-Completion di jeetworks.org/node/52 .
Micha Wiedenmann
1
Pertimbangkan jawaban saya di bawah inigit rev-parse --git-dir , seperti yang dijelaskan dalam komentar ini
VonC
1
@MichaWiedenmann: tautannya sudah mati.
d33tah

Jawaban:

1114

Iya:

git rev-parse --show-toplevel

Jika Anda ingin meniru perintah Git secara lebih langsung, Anda dapat membuat alias :

git config --global alias.root 'rev-parse --show-toplevel'

dan sekarang git rootakan berfungsi sama hg root.


Catatan : Dalam submodule ini akan menampilkan direktori root dari submodule dan bukan repositori induk. Jika Anda menggunakan Git> = 2.13 atau di atas, ada cara agar submodula dapat menampilkan direktori root superproject. Jika git Anda lebih tua dari itu, lihat jawaban lain ini.

baudtack
sumber
148
Saya selalu mendefinisikan git config --global alias.exec '!exec 'sehingga saya bisa melakukan hal-hal seperti git exec make. Ini berfungsi karena alias shell selalu dijalankan di direktori tingkat atas.
Daniel Brockman
8
Inilah yang hg rootdilakukan. Mencetak direktori tingkat atas dari repositori Anda yang sudah diperiksa. Itu tidak mengalihkan Anda ke sana (dan itu tidak bisa, pada kenyataannya, melakukannya karena bagaimana seluruh konsep direktori saat ini dan shell Anda berinteraksi).
Mahakuasa
14
Peringatan kecil dengan solusi ini - itu akan menindaklanjuti tautan simbolik. Jadi, jika Anda berada di ~/my.proj/foo/bar, dan ~/my.projterhubung ke ~/src/my.proj, perintah di atas akan memindahkan Anda ke ~/src/my.proj. Bisa jadi masalah, jika apa pun yang ingin Anda lakukan setelah itu bukan pohon agnostik.
Franci Penov
3
Bagaimana saya bisa menggunakan ini dari dalam git hook? Secara khusus, saya sedang melakukan post-merge hook dan saya perlu mendapatkan direktori root aktual dari git repo lokal.
Derek
12
Solusi ini (dan banyak lainnya di halaman ini yang telah saya coba) tidak berfungsi di dalam git hook. Untuk lebih tepatnya, itu tidak berfungsi ketika Anda berada di dalam .gitdirektori proyek .
Dennis
97

The manhalaman untuk git-config(di bawah Alias ) mengatakan:

Jika ekspansi alias diawali dengan tanda seru, itu akan diperlakukan sebagai perintah shell. [...] Perhatikan bahwa perintah shell akan dieksekusi dari direktori tingkat atas dari repositori, yang mungkin bukan direktori saat ini.

Jadi, pada UNIX Anda dapat melakukan:

git config --global --add alias.root '!pwd'
Scott Lindsay
sumber
2
Jadi, jika Anda memiliki perintah "git root", bagaimana Anda bisa memasukkannya ke dalam alias? Jika saya letakkan di my .zshrc, dan saya mendefinisikan `alias cg =" cd $ (git root) ", bagian $ () akan dievaluasi pada waktu sumber, dan selalu menunjuk ke ~ / dotfiles, karena di situlah zshrc saya berada .
zelk
2
@cormacrelf Anda tidak memasukkannya ke dalam shell alias. Anda bisa meletakkannya di fungsi shell atau skrip.
Conrad Meyer
4
@cormacrelf Masukkan dalam tanda kutip tunggal, bukan tanda kutip ganda, maka itu tidak akan diperluas pada waktu definisi, tetapi pada saat runtime.
clacke
3
@ Gambar Mekanik Sungguh? Jadi apa yang Anda harapkan dari repo di luar?
Alois Mahdal
1
@AloisMahdal sebenarnya bagi saya itu tidak gagal di luar repo, itu hanya melaporkan cwd.
justinpitts
91

Telah --show-toplevelhanya baru-baru telah ditambahkan kegit rev-parse atau mengapa tidak ada yang menyebutkan itu?

Dari git rev-parsehalaman manual:

   --show-toplevel
       Show the absolute path of the top-level directory.
marc.guenther
sumber
1
Terima kasih telah menunjukkan ini; tanpa bantuan Anda, sulit bagi saya untuk menebak git-rev-parse- karena namanya menyarankan untuk memproses spesifikasi revisi. BTW, saya akan senang melihat git --work-treekarya yang mirip dengan git --exec-path[=<path>]: "Jika tidak ada jalur yang diberikan, git akan mencetak pengaturan saat ini"; setidaknya, IMO, itu akan menjadi tempat yang logis untuk mencari fitur seperti itu.
imz - Ivan Zakharyaschev
4
Khususnya, Anda dapat alias root = rev-parse --show-topleveldi gitconfig Anda.
Siput mekanik
2
dengan kata lain, Anda bisa melakukannya git config --global alias.root "rev-parse --show-toplevel" dan kemudian git rootakan dapat melakukan pekerjaan
nonopolaritas
@RyanTheLeach git rev-parse --show-toplevelbekerja ketika saya mencobanya dalam sebuah submodule. Ini mencetak direktori root dari submitule git. Apa yang tercetak untuk Anda?
wisbucky
2
Saya bingung mengapa jawaban ini menggandakan jawaban teratas. Ternyata jawaban teratas telah diedit dari --show-cdupke--show-top-level Februari 2011 (setelah jawaban ini diajukan).
wisbucky
54

Bagaimana dengan " git rev-parse --git-dir"?

F:\prog\git\test\copyMerge\dirWithConflicts>git rev-parse --git-dir
F:/prog/git/test/copyMerge/.git

Itu --git-dir pilihan tampaknya bekerja.

Dari halaman manual git rev-parse :

--git-dir

    Show $GIT_DIR if defined else show the path to the .git directory.

Anda dapat melihatnya beraksi di skrip inigit setup-sh .

Jika Anda berada di folder submodule, dengan Git> = 2.13 , gunakan :

git rev-parse --show-superproject-working-tree

Jika Anda menggunakan git rev-parse --show-toplevel , pastikan dengan Git 2.25+ (Q1 2020) .

VONC
sumber
3
Oh, tunggu, ini sudah dekat tetapi mendapatkan dir .git yang sebenarnya, bukan basis dari repo git. Juga, direktori .git bisa berada di tempat lain, jadi ini bukan yang tepatnya saya cari.
Wojo
2
Benar, saya mengerti sekarang apa yang sebenarnya Anda cari. --show-cdup lebih tepat. Saya meninggalkan jawaban saya untuk menggambarkan perbedaan antara dua opsi.
VonC
2
Tampaknya juga perintah ini memberikan jalur relatif untuk .gitjika Anda sudah berada di direktori root. (Setidaknya, itu pada msysgit.)
Blair Holloway
2
+1, ini adalah satu-satunya jawaban yang menjawab pertanyaan awal "dapatkan direktori yang berisi direktori .git?", Lucu melihat bahwa OP sendiri menyebutkan "direktori .git mungkin ada di tempat lain".
FabienAndre
1
Ini adalah satu-satunya solusi yang bekerja pada windows AND memberikan hasil yang dapat diuraikan ketika menggunakan submitula git (mis. C: \ repositori \ myrepo \ .git \ modules \ mysubmodule). Itu membuatnya menjadi solusi paling kuat terutama dalam skrip yang dapat digunakan kembali.
chriskelly
36

Untuk menulis jawaban sederhana di sini, sehingga bisa kita gunakan

git root

untuk melakukan pekerjaan itu, cukup konfigurasikan git Anda dengan menggunakan

git config --global alias.root "rev-parse --show-toplevel"

dan kemudian Anda mungkin ingin menambahkan yang berikut ke ~/.bashrc:

alias cdroot='cd $(git root)'

sehingga Anda bisa menggunakan cdrootuntuk pergi ke atas repo Anda.

nonopolaritas
sumber
Sangat bagus! Akhirnya nyaman!
scravy
Jawaban yang bagus, terima kasih!
AVarf
26

Jika Anda sudah berada di level atas atau tidak dalam repositori git cd $(git rev-parse --show-cdup)akan membawa Anda pulang (hanya cd). cd ./$(git rev-parse --show-cdup)adalah salah satu cara untuk memperbaikinya.

Karl
sumber
7
Pilihan lain adalah untuk mengutipnya: cd "$(git rev-parse --show-cdup)". Ini bekerja karena cd ""membawa Anda ke mana-mana, daripada kembali $HOME. Dan itu praktik terbaik untuk mengutip doa $ (), kalau-kalau mereka mengeluarkan sesuatu dengan spasi (meskipun perintah ini tidak akan dalam kasus ini).
ctrueden
Jawaban ini berfungsi dengan baik bahkan jika Anda mengubah direktori ke repo git Anda melalui symlink . Beberapa contoh lain tidak berfungsi seperti yang diharapkan ketika repo git Anda berada di bawah symlink karena mereka tidak menyelesaikan direktori root git relatif terhadap bash's $PWD. Contoh ini akan menyelesaikan root relatif git $PWDdaripada realpath $PWD.
Damien Ó Ceallaigh
16

Untuk menghitung path absolut dari direktori root git saat ini, katakan untuk digunakan dalam skrip shell, gunakan kombinasi readlink dan git rev-parse:

gitroot=$(readlink -f ./$(git rev-parse --show-cdup))

git-rev-parse --show-cdupmemberi Anda jumlah yang tepat ".." untuk sampai ke root dari cwd Anda, atau string kosong jika Anda berada di root. Kemudian tambahkan "./" untuk menangani case string kosong dan gunakan readlink -f untuk menerjemahkan ke path lengkap.

Anda juga bisa membuat git-rootperintah di PATH Anda sebagai skrip shell untuk menerapkan teknik ini:

cat > ~/bin/git-root << EOF
#!/bin/sh -e
cdup=$(git rev-parse --show-cdup)
exec readlink -f ./$cdup
EOF
chmod 755 ~/bin/git-root

(Di atas dapat disisipkan ke terminal untuk membuat git-root dan mengatur bit eksekusi; skrip yang sebenarnya ada di baris 2, 3 dan 4.)

Dan kemudian Anda bisa berlari git rootuntuk mendapatkan root dari pohon Anda saat ini. Perhatikan bahwa dalam skrip shell, gunakan "-e" untuk menyebabkan shell keluar jika rev-parse gagal sehingga Anda bisa mendapatkan status keluar dan pesan kesalahan dengan benar jika Anda tidak berada di direktori git.

Emil Sit
sumber
2
Contoh Anda akan rusak jika jalur direktori git "root" berisi spasi. Selalu gunakan "$(git rev-parse ...)"bukan seperti peretasan ./$(git rev-parse ...).
Mikko Rantalainen
readlink -ftidak berfungsi sama pada BSD. Lihat SO ini untuk penyelesaiannya. Python Jawabannya mungkin akan bekerja tanpa harus memasang apapun: python -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$(git rev-parse --show-cdup)".
Bluu
16

Seperti yang telah dicatat oleh orang lain, inti dari solusi adalah menggunakan git rev-parse --show-cdup. Namun, ada beberapa kasus tepi yang harus diatasi:

  1. Ketika cwd sudah menjadi root dari pohon yang bekerja, perintah menghasilkan string kosong.
    Sebenarnya itu menghasilkan baris kosong, tetapi perintah strip pengganti dari istirahat garis trailing. Hasil akhir adalah string kosong.

    Sebagian besar jawaban menyarankan untuk mengawali output dengan ./sehingga output kosong menjadi "./"sebelum diumpankan ke cd.

  2. Ketika GIT_WORK_TREE diatur ke lokasi yang bukan induk dari cwd, output mungkin merupakan nama path absolut.

    Ketergantungan ./adalah salah dalam situasi ini. Jika a ./adalah prepended ke path absolut, itu menjadi path relatif (dan mereka hanya merujuk ke lokasi yang sama jika cwd adalah direktori root sistem).

  3. Output mungkin berisi spasi.

    Ini benar-benar hanya berlaku dalam kasus kedua, tetapi memiliki perbaikan yang mudah: gunakan tanda kutip ganda di sekitar substitusi perintah (dan setiap penggunaan selanjutnya dari nilai).

Seperti yang dicatat oleh jawaban lain, kita bisa melakukannya cd "./$(git rev-parse --show-cdup)" , tetapi hal ini pecah pada case tepi kedua (dan case edge ketiga jika kita mengabaikan tanda kutip ganda).

Banyak shell memperlakukan cd ""sebagai no-op, jadi untuk shell yang bisa kita lakukan cd "$(git rev-parse --show-cdup)"(tanda kutip ganda melindungi string kosong sebagai argumen dalam case tepi pertama, dan mempertahankan spasi putih di case tepi ketiga). POSIX mengatakan hasil dari cd ""tidak ditentukan, jadi mungkin yang terbaik adalah menghindari membuat asumsi ini.

Sebuah solusi yang bekerja dalam semua kasus di atas memerlukan semacam tes. Dilakukan secara eksplisit, mungkin terlihat seperti ini:

cdup="$(git rev-parse --show-cdup)" && test -n "$cdup" && cd "$cdup"

Tidak cddilakukan untuk kasing tepi pertama.

Jika dapat dijalankan cd .untuk case tepi pertama, maka kondisional dapat dilakukan dalam perluasan parameter:

cdup="$(git rev-parse --show-cdup)" && cd "${cdup:-.}"
Chris Johnsen
sumber
Mengapa Anda tidak menggunakan "git config --global --add alias.root '! Pwd'" dan shell alias gitroot = 'cd git root' yang jawaban di atas Anda gunakan?
Jason Axelson
1
Menggunakan alias mungkin tidak memungkinkan, misalnya jika Anda ingin membuat skrip dan tidak dapat mengandalkan alias khusus.
blueyed
1
Sub Modul adalah jenis sudut lainnya.
Ryan The Leach
14

Untuk berjaga-jaga jika Anda memberi makan jalur ini ke Git itu sendiri, gunakan :/

# 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)
Nick Volynkin
sumber
12

Solusi singkat yang bekerja dengan submodula, di kait, dan di dalam .git direktori

Inilah jawaban singkat yang paling diinginkan:

r=$(git rev-parse --git-dir) && r=$(cd "$r" && pwd)/ && echo "${r%%/.git/*}"

Ini akan bekerja di mana saja di pohon kerja git (termasuk di dalam .gitdirektori), tetapi mengasumsikan bahwa direktori repositori dipanggil .git(yang merupakan default). Dengan submodula, ini akan menuju ke akar repositori yang mengandung paling luar.

Jika Anda ingin mendapatkan root dari submodule saat ini:

echo $(r=$(git rev-parse --show-toplevel) && ([[ -n $r ]] && echo "$r" || (cd $(git rev-parse --git-dir)/.. && pwd) ))

Untuk dengan mudah menjalankan perintah di root submodule Anda, [alias]di bawah di Anda .gitconfig, tambahkan:

sh = "!f() { root=$(pwd)/ && cd ${root%%/.git/*} && git rev-parse && exec \"$@\"; }; f"

Ini memungkinkan Anda untuk dengan mudah melakukan hal-hal seperti git sh ag <string>

Solusi yang kuat yang mendukung nama yang berbeda atau eksternal .gitatau $GIT_DIRdirektori.

Perhatikan bahwa $GIT_DIRmungkin menunjuk suatu tempat eksternal (dan tidak bisa disebut.git ), maka kebutuhan untuk pemeriksaan lebih lanjut.

Letakkan ini di .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"
}

Jalankan dengan mengetik git_root(setelah restart shell Anda: exec bash)

Tom Hale
sumber
Kode ini sedang ditinjau kode pada fungsi Robust bash untuk menemukan root dari repositori git . Lihat di sana untuk pembaruan.
Tom Hale
Bagus. Lebih kompleks dari apa yang saya usulkan 7 tahun lalu ( stackoverflow.com/a/958125/6309 ), tetapi masih +1
VonC
1
Solusi yang lebih pendek di sepanjang garis itu adalah: (root=$(git rev-parse --git-dir)/ && cd ${root%%/.git/*} && git rev-parse && pwd)tetapi ini tidak mencakup eksternal $GIT_DIRyang dinamai selain.git
Tom Hale
Saya ingin tahu apakah ini memperhitungkan beberapa worktrees yang sekarang mungkin di git 2.5+ ( stackoverflow.com/a/30185564/6309 )
VonC
Tautan komentar Anda ke "Fungsi bash yang kuat untuk menemukan root ..." sekarang menghasilkan 404.
ErikE
8

Untuk sedikit mengubah jawaban "git config":

git config --global --add alias.root '!pwd -P'

dan membersihkan jalan. Sangat bagus.

Bruce K.
sumber
7

Jika Anda mencari alias yang baik untuk melakukan ini dan tidak meledak cdjika Anda tidak berada di direktori git:

alias ..g='git rev-parse && cd "$(git rev-parse --show-cdup)"'
Dan Heberden
sumber
6

Alias ​​shell ini berfungsi baik Anda berada di subdit git, atau di tingkat atas:

alias gr='[ ! -z `git rev-parse --show-toplevel` ] && cd `git rev-parse --show-toplevel || pwd`'

diperbarui untuk menggunakan sintaksis modern alih-alih backticks:

alias gr='[ ! -z $(git rev-parse --show-toplevel) ] && cd $(git rev-parse --show-toplevel || pwd)'
MERM
sumber
5
alias git-root='cd \`git rev-parse --git-dir\`; cd ..'

Segala sesuatu yang lain gagal pada beberapa titik, entah menuju ke direktori home atau gagal total. Ini adalah cara tercepat dan terpendek untuk kembali ke GIT_DIR.

tocororo
sumber
Sepertinya 'git rev-parse - git-dir' adalah solusi paling bersih.
Stabledog
3
Ini gagal, ketika $GIT_DIRterlepas dari pohon kerja menggunakan .git-Files dan gitdir: SOMEPATH. Akibatnya ini gagal untuk submodules, juga, di mana $GIT_DIRmengandung .git/modules/SUBMODULEPATH.
Tino
5

Berikut ini adalah skrip yang saya tulis yang menangani kedua kasus: 1) repositori dengan ruang kerja, 2) repositori kosong.

https://gist.github.com/jdsumsion/6282953

git-root (file yang dapat dieksekusi di jalur Anda):

#!/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
)

Semoga ini bermanfaat.

jdsumsion
sumber
1
Keith, terima kasih atas sarannya, saya sudah memasukkan naskahnya.
jdsumsion
Saya benar-benar memilih jawaban teratas karena saya menyadari git execidenya lebih membantu dalam repositori non-telanjang. Namun, skrip ini dalam jawaban saya menangani bare vs non-bare case dengan benar, yang dapat bermanfaat bagi seseorang, jadi saya meninggalkan jawaban ini di sini.
jdsumsion
1
Namun ini gagal git submoduledi mana $GIT_DIRberisi sesuatu seperti /.git/modules/SUBMODULE. Anda juga berasumsi, bahwa .gitdirektori adalah bagian dari worktree dalam case non-bare.
Tino
4
$ git config alias.root '!pwd'
# then you have:
$ git root
FractalSpace
sumber
Alias ​​ini akan gagal sebagai global. Gunakan ini sebagai gantinya (dalam ~ / .gitconfig): [alias] findroot = "!f () { [[ -d ".git" ]] && echo "Found git in [pwd ]" && exit 0; cd .. && echo "IN pwd" && f;}; f"
FractalSpace
mengapa downvote? Harap sorot kesalahan apa pun atau sarankan perbaikan.
FractalSpace
1
Bagi saya git config --global alias.root '!pwd'bekerja. Saya tidak dapat menemukan kasus mana pun yang berfungsi secara berbeda terhadap varian non-global. (Unix, git 1.7.10.4) BTW: Anda findrootmembutuhkan /.gituntuk menghindari rekursi yang tak berkesudahan.
Tino
4

Sejak Git 2.13.0 , ia mendukung opsi baru untuk menunjukkan jalur proyek root, yang bekerja bahkan ketika digunakan dari dalam submodule:

git rev-parse --show-superproject-working-tree
Jordi Vilalta Prat
sumber
git-scm.com/docs/… . Menarik. Saya pasti melewatkan yang itu. +1
VonC
3
Peringatan: "Tidak menghasilkan apa-apa jika repositori saat ini tidak digunakan sebagai submodule oleh proyek apa pun."
VonC
Terima kasih atas komentarnya! Saya tidak memperhatikan itu.
Jordi Vilalta Prat
2

Alias ​​Shell Pra-Konfigurasi dalam Kerangka Shell

Jika Anda menggunakan kerangka shell, mungkin sudah ada alias shell yang tersedia:

  • $ grtdalam oh-my-zsh (68k) ( cd $(git rev-parse --show-toplevel || echo "."))
  • $ git-rootdi prezto (8.8k) (menampilkan path ke root tree yang berfungsi)
  • $ g.. zimfw (1k) (mengubah direktori saat ini ke tingkat teratas pohon yang berfungsi.)
Hotschke
sumber
1

Saya ingin memperluas komentar luar biasa Daniel Brockman.

Mendefinisikan git config --global alias.exec '!exec 'memungkinkan Anda untuk melakukan hal-hal seperti git exec makekarena, seperti yang man git-configdinyatakan:

Jika ekspansi alias diawali dengan tanda seru, itu akan diperlakukan sebagai perintah shell. [...] Perhatikan bahwa perintah shell akan dieksekusi dari direktori tingkat atas dari repositori, yang mungkin bukan direktori saat ini.

Juga berguna untuk mengetahui bahwa itu $GIT_PREFIXakan menjadi jalur ke direktori saat ini relatif ke direktori tingkat atas dari repositori. Tapi, mengetahui itu hanya setengah dari pertempuran ™. Ekspansi variabel Shell membuatnya agak sulit digunakan. Jadi saya sarankan menggunakan bash -cseperti:

git exec bash -c 'ls -l $GIT_PREFIX'

perintah lain termasuk:

git exec pwd
git exec make
Bruno Bronosky
sumber
1

Jika ada yang membutuhkan cara yang sesuai dengan POSIX untuk melakukan ini, tanpa perlu gitdieksekusi:

git-root:

#$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

Jika Anda hanya ingin fungsionalitas sebagai bagian dari skrip, hapus shebang, dan ganti git_root_recurse_parentbaris terakhir dengan:

git_root() {
    (git_root_recurse_parent)
}
swalog
sumber
Peringatan: Jika ini TIDAK disebut dalam git repo maka rekursi tidak berakhir sama sekali.
AH
@ YA ifPernyataan kedua seharusnya memeriksa apakah Anda telah mengubah direktori dalam rekursi. Jika tetap di direktori yang sama, itu mengasumsikan Anda terjebak di suatu tempat (misalnya /), dan rekursi rem. Bug diperbaiki, dan sekarang seharusnya berfungsi seperti yang diharapkan. Terima kasih telah menunjukkannya.
swalog
0

Harus menyelesaikan ini sendiri hari ini. Memecahkannya dalam C # karena saya membutuhkannya untuk sebuah program, tapi saya kira itu bisa ditulis ulang. Pertimbangkan Domain Publik ini.

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;

}
Hylke Bons
sumber