我想遍歷所有目錄并找出所有 git 存盤庫(裸機和非裸機)。但是,我需要確定哪個是裸機,哪個是非裸機,以便我可以對它們運行不同的操作。
我檢查了檢查當前目錄是否是 Git 存盤庫以及如何檢查存盤庫是否是裸露的?.
我想出的腳本是:
#!/bin/bash
for d in $(find /media/ismail/8TBRaid0/ABC -path '*/.git*' -prune -o -print -type d); do
if git --git-dir=$d rev-parse --is-inside-work-tree > /dev/null 2>&1; then
echo ${d} is a non-Bare Repository
elif git --git-dir=$d rev-parse --is-bare-repository > /dev/null 2>&1; then
echo ${d} is a is a Bare Repository
fi
done
我得到的輸出是:
/media/ismail/8TBRaid0/ABC/d is a non-Bare Repository
/media/ismail/8TBRaid0/ABC/e is a non-Bare Repository
問題是:
ABC 有 5 個目錄。
ABC% ls -la
total 28
drwxrwxr-x 7 ismail ismail 4096 Jun 9 16:44 .
drwxr--r-- 16 ismail ismail 4096 Jun 9 16:44 ..
drwxrwxr-x 3 ismail ismail 4096 Jun 9 16:44 a
drwxrwxr-x 3 ismail ismail 4096 Jun 9 16:44 b
drwxrwxr-x 3 ismail ismail 4096 Jun 9 16:44 c
drwxrwxr-x 7 ismail ismail 4096 Jun 9 16:44 d
drwxrwxr-x 7 ismail ismail 4096 Jun 9 16:44 e
這里 a,b,c 是帶有 .git 目錄的非裸倉庫。d,e 是沒有 .git 目錄的裸倉庫。
所以,我得到的輸出肯定是錯誤的。我的情況需要的是:
a is a non-Bare Repository
b is a non-Bare Repository
c is a non-Bare Repository
d is a Bare Repository
e is a Bare Repository
我怎樣才能得到預期的結果?
更新1:
我的目錄結構其實更深更分散。我上面給出的結構是一個例子。例如:結構可以是:
.
├── 1
│ └── a
├── 2
│ └── 3
│ ├── b
│ └── e
│ ├── branches
│ ├── config
│ ├── description
│ ├── HEAD
│ ├── hooks
│ │ ├── applypatch-msg.sample
│ │ ├── commit-msg.sample
│ │ ├── fsmonitor-watchman.sample
│ │ ├── post-update.sample
│ │ ├── pre-applypatch.sample
│ │ ├── pre-commit.sample
│ │ ├── pre-merge-commit.sample
│ │ ├── prepare-commit-msg.sample
│ │ ├── pre-push.sample
│ │ ├── pre-rebase.sample
│ │ ├── pre-receive.sample
│ │ └── update.sample
│ ├── info
│ │ └── exclude
│ ├── objects
│ │ ├── info
│ │ └── pack
│ └── refs
│ ├── heads
│ └── tags
├── c
├── d
│ ├── branches
│ ├── config
│ ├── description
│ ├── HEAD
│ ├── hooks
│ │ ├── applypatch-msg.sample
│ │ ├── commit-msg.sample
│ │ ├── fsmonitor-watchman.sample
│ │ ├── post-update.sample
│ │ ├── pre-applypatch.sample
│ │ ├── pre-commit.sample
│ │ ├── pre-merge-commit.sample
│ │ ├── prepare-commit-msg.sample
│ │ ├── pre-push.sample
│ │ ├── pre-rebase.sample
│ │ ├── pre-receive.sample
│ │ └── update.sample
│ ├── info
│ │ └── exclude
│ ├── objects
│ │ ├── info
│ │ └── pack
│ └── refs
│ ├── heads
│ └── tags
└── f
└── ADOC Document.adoc
uj5u.com熱心網友回復:
對于初學者,請查看find命令的輸出:
$ find ABC -path '*/.git*' -prune -o -print -type d
ABC
ABC/a
ABC/b
ABC/c
ABC/d
ABC/d/branches
ABC/d/hooks
ABC/d/hooks/applypatch-msg.sample
ABC/d/hooks/commit-msg.sample
ABC/d/hooks/post-update.sample
[...]
這根本沒用。如果其中包含的所有內容.../ABC都是 git 存盤庫,則您只需獲取目錄串列:
$ find ABC/* -maxdepth 0 -type d
ABC/a
ABC/b
ABC/c
ABC/d
ABC/e
這將更容易使用。然后我們可以像這樣迭代這些結果:
find ABC/* -maxdepth 0 -type d |
while read dir; do
# note that --is-bare-repository returns results as a string
# not an exit code
is_bare=$(git -C $dir rev-parse --is-bare-repository 2> /dev/null)
if [ "$is_bare" = true ]; then
echo "$dir is a bare repository"
else
echo "$dir is not a bare repository"
fi
done
運行該代碼會產生:
ABC/a is not a bare repository
ABC/b is not a bare repository
ABC/c is not a bare repository
ABC/d is a bare repository
ABC/e is a bare repository
如果某些東西ABC可能不是存盤庫,我們可以在回圈git中添加一個附加子句:while
...
is_bare=$(git -C $dir rev-parse --is-bare-repository 2> /dev/null)
if [ $? -ne 0 ]; then
echo "$dir is not a git repository"
continue
fi
...
更新
如果您的目錄結構更加多樣化,我們可以通過查找名為 的檔案來找到 git 存盤庫HEAD:
$ find ABC -name HEAD -printf "%h\n"
ABC/c/.git
ABC/1/a/.git
ABC/1/d
ABC/2/b/.git
ABC/2/e
這意味著我們可以將腳本重寫為:
find ABC -name HEAD -printf "%h\n" |
while read dir; do
if [[ $dir =~ /\.git/ ]]; then
dir=${dir%/.*}
fi
# note that --is-bare-repository returns results as a string
# not an exit code
is_bare=$(git -C "$dir" rev-parse --is-bare-repository 2> /dev/null)
if [[ $is_bare = true ]]; then
echo "$dir is a bare repository"
else
echo "$dir is not a bare repository"
fi
done
請注意,我在這里使用了一些特定于 bash 的語法來使我們的生活更輕松,但這在大多數環境中應該不是問題。
鑒于此目錄樹:
ABC/
├── 1
│ ├── a # non-bare repository
│ └── d # bare repository
├── 2
│ ├── b # non-bare repository
│ └── e # bare repository
├── c # non-bare repository
└── z # not a repository
上面的腳本產生:
ABC/c is not a bare repository
ABC/1/a is not a bare repository
ABC/1/d is a bare repository
ABC/2/b is not a bare repository
ABC/2/e is a bare repository
uj5u.com熱心網友回復:
您可能可以通過一些find bash機器來完成所有這些操作:
$ cat myScript
#!/usr/bin/env bash
iiwt() {
[[ $(git -C "$1" rev-parse --is-inside-work-tree 2> /dev/null) == "true" ]] &&
echo "$1 is a non-Bare Repository"
}
ibr() {
[[ $(git -C "$1" rev-parse --is-bare-repository 2> /dev/null) == "true" ]] &&
echo "$1 is a Bare Repository"
}
export -f iiwt ibr
find . -type d -exec bash -c 'iiwt "$1" || ibr "$1"' _ {} \; -prune
說明:
輔助函式測驗其
iiwt引數是否在作業樹內。如果是,它會列印一條訊息并且其退出狀態為真。否則其退出狀態為假。輔助函式測驗其
ibr引數是否在裸存盤庫中。如果是,它會列印一條訊息并且其退出狀態為真。否則其退出狀態為假。find 命令搜索所有目錄并在每個目錄上執行 bash 腳本
iiwt "$1" || ibr "$1"。如果退出狀態為真,則 find 將在此處停止遞回(這就是-prune目的)。否則它會在內部遞回。
演示:
$ mkdir -p foobar/bar foobar/a/b/c; cd foobar
$ git init --bare foo.git
$ git clone foo.git
$ git init --bare bar/foo.git
$ git clone bar/foo.git bar/foo
$ find . -type d
.
./a
./a/b
./a/b/c
./foo.git
./foo.git/refs
./foo.git/refs/heads
...
./foo/.git/refs/heads
./foo/.git/refs/tags
./foo/.git/branches
$ myScript .
./foo is a non-Bare Repository
./foo.git is a Bare Repository
./bar/foo.git is a Bare Repository
./bar/foo is a non-Bare Repository
請注意,我們也可以使用一個輔助函式:
$ cat myScript
#!/usr/bin/env bash
hlp() {
if [[ $(git -C "$1" rev-parse --is-inside-work-tree 2> /dev/null) == "true" ]]; then
echo "$1 is a non-Bare Repository"
elif [[ $(git -C "$1" rev-parse --is-bare-repository 2> /dev/null) == "true" ]]; then
echo "$1 is a Bare Repository"
else
return 1
fi
}
export -f hlp
find . -type d -exec bash -c 'hlp "$1"' _ {} \; -prune
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/488182.html
