使用 ghq 管理您的 git 存储库
你使用git管理你的代码(或其他东西)的次数越多,你的目录结构就越混乱,几年后你可能会得到这样的结果:
├── code
│ ├── blog
│ └── website
├── repos
│ ├── coolproject
│ └── demo
├── repositories
│ └── website
└── src
├── foo
└── project1337
进入全屏模式 退出全屏模式
至少对我来说,这发生了。这些目录中的大多数至少是实际的 git 存储库,但有些不是。显然这是一团糟,如果每个目录都包含几十个存储库,则很难找到合适的存储库。
所以我正在寻找一种更好的方式来组织我的存储库,一位朋友告诉我ghq。 ghq 可以轻松管理所有 git 存储库并同时强制执行有组织的目录结构。如果您使用go您将已经知道目录结构,因为它完全相同。
x-motemen/ghq
远程存储库管理变得简单
ghq(1)
[
](https://coveralls.io/ r/motemen/ghq?branchu003dmaster)
姓名
ghq - 管理远程存储库克隆
说明
'ghq' 提供了一种组织远程存储库克隆的方法,就像 go get 一样。当您通过 ghq get 克隆远程存储库时,ghq 会使用远程存储库 URL 的主机和路径在特定根目录(默认为 ~/ghq)下创建一个目录。
$ ghq 获取 https://github.com/x-motemen/ghq
次运行 `git clone https://github.com/x-motemen/ghq ~/ghq/github.com/x-motemen/ghq`
您还可以列出本地存储库(ghq 列表)。
概要
ghq get [-u] [-p] [--shallow] [--vcs <vcs>] [--look] [--silent] [--branch ] [--no-recursive] <repository URL>|<host>/<user>/<project>|<user>/<project>|<project>
ghq 列表 [-p] [-e] [<查询>]
ghq create [--vcs <vcs>] <repository URL>|<host>/<user>/<project>|<user>/<project>|<project>
ghq 根 [--all]
命令
得到
在 ghq 根目录下克隆一个远程存储库(参见下面的DIRECTORY STRUCTURES)。如果存储库已经克隆到本地,除非提供'-u'('--update')标志,否则不会发生任何事情,在这种情况下,本地存储库被更新(例如'git pull --ff-only')。您使用“-p”选项,存储库是通过...克隆的
在 GitHub 上查看
安装ghq
安装 ghq 是easy。如果你使用 Linux 发行版,你可以检查你的包管理器是否可以使用 ghq。否则,您还有其他一些选择。您可以从GitHub下载当前版本,或者如果您安装了go
,您可以运行go get github.com/motemen/ghq
。如果您使用 macOS,您可以运行brew install ghq
。要验证您的安装,只需运行:
$ ghq root
/home/max/.ghq
进入全屏模式 退出全屏模式
更改ghq根目录
默认情况下,ghq 将所有 git 存储库组织在~/.ghq
中,但这可以在您的~/.gitconfig
文件中进行更改。例如,我不喜欢将所有存储库放在像.ghq
这样的隐藏目录中。相反,我使用~/repos
,因此~/.gitconfig
文件中的配置条目如下所示:
[ghq]
root = ~/repos
root = ~/go/src
进入全屏模式 退出全屏模式
通过多次定义root=...
ghq 使用所有目录来查找存储库。如果您使用 go 这将特别有用,因为它以相同的方式组织存储库,但默认情况下将它们放在~/go/src
中。如果您运行ghq list
来显示所有存储库,ghq 也会在~/repos
和~/go/src
中查找。
克隆一个新的仓库
您现在必须运行ghq get https://github.com/githubtraining/hellogitworld.git
而不是运行git clone https://github.com/githubtraining/hellogitworld.git
来签出新存储库,而 ghq 将使用存储库 URL 来创建正确的目录结构:
repos/
└── github.com
└── githubtraining
└── hellogitworld
├── build.gradle
├── fix.txt
├── pom.xml
├── README.txt
└ ...
进入全屏模式 退出全屏模式
如果您从不同的服务器和不同的用户克隆更多存储库,ghq 将创建目录以保持一切井井有条。例如,我的~/repos
目录的摘录如下所示:
├── aur.archlinux.org
│ └── heluxup
│ └── PKGBUILD
├── git.centralserver.de
│ └── max
│ ├── bachelor-thesis
│ ├── dotfiles
│ ├── fotoallerlei
│ ├── k8s
│ ├── telegram-stickers
│ └── wiki
└ github.com
├── ekeih
│ ├── dwdpollen
│ ├── FrundenBot
│ ├── hello-github-actions
│ ├── heluxup
│ ├── hetzner-deployment
│ ├── i3-renameworkspace
│ ├── icinga2telegram
│ ├── InfiniteWisdomBot
│ ├── tado
│ ├── tado-influxdb
│ ├── taustakuva
│ └── webhook
├── fluxcd
│ └── helm-operator
└── grandchild
└── arch-cleaner
进入全屏模式 退出全屏模式
ghq look
以及它的坏处
就个人而言,我发现这种组织方式已经为 ghq 带来了巨大的好处,但主要优势是 ghq 帮助直接跳转到正确的存储库的方式:
$ pwd
/home/max
$ ghq look hello
$ pwd
/home/max/repos/github.com/githubtraining/hellogitworld
进入全屏模式 退出全屏模式
这样就可以在不同的存储库之间快速切换,而无需知道它们的完整路径。不幸的是,这有一个缺点......进程的当前工作目录是其环境的一部分,并且进程环境不能被其子进程修改。如果您想阅读更多关于此的技术背景,我推荐这个Stack Overflow 答案,它更详细地解释了它。最后,这意味着 ghq 不能真正更改 shell 的当前工作目录......相反,它会在新目录中启动一个新的子 shell。从技术上讲,这是可行的,但我发现每个ghq look ...
添加一个额外的嵌套 shell 进程结束退出 shell 意味着返回到前一个 shell,这很烦人。
回复:从 Go更改父 shell 目录
2018 年 12 月 31 日
[
5
](https://stackoverflow.com/questions/53984853/change-parent-shell-directory-from-go/53984896#53984896)
我如何编写一个像 'cd' 一样的 Go 程序?
这在 POSIX 系统上是_不可能的_(即使使用任何其他编程语言)。
因为每个进程,包括父 shell 进程,都有它的_own_ current工作目录。因此cd
必须是外壳...
打开完整答案
ghq 的开发者在GitHub issue中建议使用 shell 函数来包装 ghq 来解决这个问题。这种方法可能看起来有点奇怪,但实际上效果很好,并且可能是通过运行cd
来真正更改当前工作目录的唯一解决方案,它是一个 shell 内置程序(shell 内置程序直接在 shell 进程中运行,而不是在新进程中,因此他们可以修改shell进程的环境)。
#29 评论
[!
motemen 评论于2014 年 8 月 19 日
我愿意,但我不认为 ghq 可以更改 shell 的工作目录,因为它只是一个命令,而不是 shell 函数。有什么想法可以实现吗?
一种解决方案是提供一个 shell 函数,例如:
ghq () {
如果 [ "$1" \u003d 看 -a -n "$2" ];然后
cd $(命令 ghq list -e -p $2)
返回
菲
命令 ghq "$@"
}
进入全屏模式 退出全屏模式
在 GitHub 上查看
我稍微扩展了功能并将其添加到我的~/.bashrc
中:
ghq () {
if [ "$1" = look -a -n "$2" ]; then
local repos=($(command ghq list -p "$2"))
case ${#repos[@]} in
0)
echo 'No repo found.'
return 1
;;
1)
cd "${repos[0]}"
return
;;
*)
local PS3="Select repo: "
select reponame in ${repos[@]}; do
cd "${reponame}"
return
done
esac
elif [ "$1" = get -a -n "$2" ]; then
command ghq "$@"
cd $(command ghq list -e -p "$2")
return
fi
command ghq "$@"
}
进入全屏模式 退出全屏模式
请记住在修改~/.bashrc
后打开一个新的 shell 或运行source ~/.bashrc
以加载更改。那么它有什么作用呢?每次运行ghq
时,您的 shell 不会直接运行真正的 ghq 二进制文件(例如在/usr/bin/ghq
中),而是运行具有相同名称的ghq
shell 函数。
第 2-19 行包装了ghq look ...
调用,这意味着当您调用ghq look foobar
时,该函数会搜索名称中包含 foobar 的存储库,如果找到恰好一个,则运行cd ...
以切换到它的目录。如果多个存储库匹配_foobar_,它会提供一个选择,然后切换到选定的存储库。
$ ghq look foobar
No repo found.
$ ghq look fotoallerlei
$ pwd
/home/max/repos/git.centralserver.de/max/fotoallerlei
$ ghq look heluxup
1) /home/max/repos/aur.archlinux.org/heluxup
2) /home/max/repos/github.com/ekeih/heluxup
Select repo: 2
$ pwd
/home/max/repos/github.com/ekeih/heluxup
进入全屏模式 退出全屏模式
第 20-25 行包装了ghq get ...
调用以在成功克隆后切换到新存储库。如果 ghq 既没有使用look
也没有使用get
调用,则直接调用原始 ghq 二进制文件。
总结
将我现有的存储库移动到 ghq 的目录结构后,我开始每天都使用它。我花了几天时间才记住使用ghq get ...
而不是git clone ...
和ghq look ...
而不是cd ~/repos/...
,但是我非常喜欢这个新的工作流程,并且可以将它推荐给使用多个 git 存储库的每个人。用于包装 ghq 调用以避免嵌套 shell 进程的 shell 函数使其更易于使用,因此,如果您开始使用 ghq,请花点时间将其添加到您的~/.bashrc
。
更多推荐
所有评论(0)