Git
- “我遇到过一些人,他们认为 git 是 GitHub 的前端。他们错了,git 是 AUR 的前端。” — Linus T.
Git 是由 Linux 内核的创建者 Linus Torvalds 设计和开发的版本控制系统 (VCS)。Git 现在用于维护 AUR 软件包,以及许多其他项目,包括 Linux 内核的源代码。
安装
安装 git 软件包。对于开发版本,安装 git-gitAUR 软件包。当使用诸如 git svn、git gui 和 gitk 等工具时,请检查可选依赖项。
图形前端
另见 git GUI 客户端。
- Commit — 帮助你编写更好的 Git 和 Mercurial 提交信息的编辑器。
- Forge Sparks — 简单的通知应用,支持 Github、GitLab、Gitea 和 Forgejo。
- Giggle — GTK 的 git 前端。
- GitAhead — 图形化 git 客户端,包含内置的合并工具。
- GitButler — 版本控制客户端,由 Git 支持,由 Tauri/Rust/Svelte 驱动。
- Git Cola — 用 Python 编写的简洁而强大的 Git 图形用户界面。
- Git Extensions — Git 图形用户界面,允许你在不使用命令行的情况下控制 Git。
- gitg — GNOME GUI 客户端,用于查看 git 仓库。是 gnome-extra 的一部分。
- git-gui — 基于 Tcl/Tk 的可移植 Git 图形界面。
- GitHub Desktop — 由 GitHub 团队构建的基于 Electron 的图形用户界面。
- gitk — 基于 Tcl/Tk 的 Git 仓库浏览器。
- Gittyup — 基于 Qt 的 Git 客户端。
- Guitar — Git GUI 客户端。
- gitui — 用 rust 编写的快速终端 UI,用于 git。
- Kommit — KDE 的 Git GUI 客户端。
- lazygit — 用于 git 命令的简单终端 UI。
- QGit — Git GUI 查看器,用于浏览修订历史记录、查看补丁内容和更改的文件,以图形方式跟踪不同的开发分支。
- RabbitVCS — 一组图形工具,旨在为你使用的版本控制系统提供简单直接的访问。
- Sublime Merge — 来自 Sublime Text 制造商的 Git 客户端。
- Tig — 基于 ncurses 的文本模式 Git 界面。
- ungit — 在不牺牲 git 多功能性的前提下,为 git 带来用户友好性。
配置
为了使用 Git,你至少需要设置名称和电子邮件
$ git config --global user.name "John Doe" $ git config --global user.email "johndoe@example.com"
有关更多设置,请参见 #技巧与诀窍。
使用
Git 仓库包含在 .git
目录中,该目录保存了修订历史和其他元数据。仓库跟踪的目录(默认为父目录)称为工作目录。工作树中的更改需要先暂存,然后才能记录(提交)到仓库。Git 还允许你恢复先前提交的工作树文件。
参见 起步。
获取 Git 仓库
记录更改
查看更改历史
撤销操作
使用远程仓库
分支
基本分支和合并
分支管理
分支工作流
远程分支
变基
参见 Git 分支 - 变基
协作
分布式工作流
为项目做贡献
维护项目
Git 工具
版本选择
交互式暂存
储藏与清理
签署你的工作
搜索
参见 Git 工具 - 搜索
重写历史
Reset 解惑
高级合并
Rerere
使用 Git 调试
子模块
参见 Git 工具 - 子模块
打包
参见 Git 工具 - 打包
替换
参见 Git 工具 - 替换
凭据存储
技巧与诀窍
使用 git-config
Git 从四个 INI 类型配置文件中读取其配置
/etc/gitconfig
用于系统范围的默认设置~/.gitconfig
和~/.config/git/config
(自 1.7.12 起) 用于用户特定的配置.git/config
用于仓库特定的配置
这些文件可以直接编辑,但常用的方法是使用 git config,如下例所示。
列出当前设置的变量
$ git config {--local,--global,--system} list
$ git config --global core.editor "nano -w"
设置默认推送操作
$ git config --global push.default simple
为 git difftool 设置不同的工具 (默认为 meld)
$ git config --global diff.tool vimdiff
有关更多信息,请参见 git-config(1) 和 Git 配置。
包含单独的配置文件
自从 2012 年 v1.7.10 版本以来,Git 能够构建一个配置文件,该配置文件使用 gitconfig
文件内的 include
关键字拆分为多个配置文件。
--local
或 --global
标志时,默认禁用加载包含的配置文件。要启用它,请将 --includes
标志与 git config get
和 git config list
命令一起使用。采取良好的礼仪
- 当考虑为现有项目做出贡献时,请阅读并理解其许可证,因为它可能会过度限制你更改代码的能力。某些许可证可能会引起代码所有权方面的争议。
- 考虑项目的社区以及你融入其中的程度。为了了解项目的方向,请阅读任何文档,甚至仓库的 日志。
- 当请求拉取提交或提交补丁时,请保持其小巧且文档齐全;这将有助于维护者理解你的更改并决定是否合并它们,或者要求你进行一些修改。
- 如果贡献被拒绝,请不要气馁,毕竟这是他们的项目。如果它很重要,请尽可能清晰和耐心地讨论贡献的原因:通过这种方法,最终可能会达成解决方案。
加速身份验证
你可能希望避免每次推送到 Git 服务器时都进行交互式身份验证的麻烦。
- 如果你使用 SSH 密钥进行身份验证,请使用 SSH 代理。另请参见 OpenSSH#加速 SSH 和 OpenSSH#保持连接。
- 如果你使用用户名和密码进行身份验证,如果服务器支持 SSH,请切换到 SSH 密钥,否则使用 git-credential-libsecret 凭据助手,或尝试 git-credential-cache 或 git-credential-store。
使用 git-credential-libsecret 作为凭据助手
Git 可能会从 org.freedesktop.secrets 兼容的密钥环(如 GNOME Keyring、KeePassXC 或 KDE Wallet)中获取你的凭据。因此,设置一个兼容的密钥环,并检查是否已将密钥环注册到 dbus,使用
$ dbus-send --session --print-reply --dest=org.freedesktop.DBus / \ org.freedesktop.DBus.GetConnectionUnixProcessID \ string:org.freedesktop.secrets
然后运行
$ git config --global credential.helper /usr/lib/git-core/git-credential-libsecret
来设置 git。
使用 git-credential-netrc 作为凭据助手
Git 可以读取 netrc 文件以访问凭据。首先,指示 Git 使用 netrc 助手脚本
$ git config --global credential.helper /usr/share/git/credential/netrc/git-credential-netrc.perl
然后,创建 .netrc
文件
~/.netrc
machine git-host login username password password
如果你想确保你的秘密安全,凭据助手还支持 gpg 加密文件 (~/.netrc.gpg
)。
协议默认设置
如果你正在运行如上所示的多路复用 SSH 连接,则通过 SSH 的 Git 可能比 HTTPS 更快。此外,某些服务器(如 AUR)仅允许通过 SSH 推送。例如,以下配置将为 AUR 上托管的任何仓库设置通过 SSH 的 Git。
~/.gitconfig
[url "ssh://aur@aur.archlinux.org/"] insteadOf = https://aur.archlinux.org/ insteadOf = http://aur.archlinux.org/ insteadOf = git://aur.archlinux.org/
Bash 补全
为了启用 Bash 补全,在 Bash 启动文件中 source /usr/share/git/completion/git-completion.bash
。或者,安装 bash-completion。
Git 提示符
Git 软件包附带一个提示符脚本。要启用它,source /usr/share/git/completion/git-prompt.sh
并使用 %s
参数设置自定义提示符
- 对于 Bash:
PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
- 对于 Zsh:
setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
提示: Zsh 提供了一个vcs_info
函数,可以用作替代方案。参见 zshcontrib(1) § 从版本控制系统收集信息。
请注意,命令替换必须转义,请参阅 Bash/Prompt customization#嵌入命令 了解详细信息。有关持久配置,请参见 命令行 shell#配置文件。
当更改到 Git 仓库的目录时,提示符将更改为显示分支名称。可以通过设置相应的环境变量来设置要在提示符中显示的额外详细信息
Shell 变量 | 信息 |
---|---|
GIT_PS1_SHOWDIRTYSTATE | + 表示已暂存,* 表示未暂存。 |
GIT_PS1_SHOWSTASHSTATE | $ 表示有储藏。 |
GIT_PS1_SHOWUNTRACKEDFILES | % 表示存在未跟踪的文件。 |
GIT_PS1_SHOWUPSTREAM | < , > , <> 落后于上游,领先于上游或与上游分叉。 |
GIT_PS1_STATESEPARATOR | 分支名称和状态符号之间的分隔符 |
GIT_PS1_DESCRIBE_STYLE | 当 HEAD 分离时,显示相对于标签或分支的提交 |
GIT_PS1_SHOWCOLORHINTS | 以颜色显示 |
有关环境变量的完整文档,请参见脚本的注释。
- 如果你遇到
$(__git_ps1)
返回((unknown))
的情况,则说明你的当前目录中存在.git
文件夹,但该文件夹不包含任何仓库,因此 Git 无法识别它。例如,如果你误将 Git 的配置文件认为是~/.git/config
而不是~/.gitconfig
,则可能会发生这种情况。 - 如果你的提示符在非常大的仓库中遇到延迟,则可能是由于
GIT_PS1_SHOWUNTRACKEDFILES
选项,该选项每次都会触发完整的目录树扫描以检测新文件,从而导致明显的性能影响。要为这些仓库本地禁用此选项,你可以使用命令git config --local bash.showUntrackedFiles false
。
或者,你可以使用来自 AUR 的 git shell 提示符自定义软件包之一,例如 bash-git-promptAUR 或 gittifyAUR。
可视化表示
为了了解已完成的工作量
$ git diff --stat
git log 带有分支表示
$ git log --graph --oneline --decorate
git log graph 别名 (即 git graph 将显示装饰版本)
$ git config --global alias.graph 'log --graph --oneline --decorate'
提交技巧
重置到先前的提交 (非常危险,会将所有跟踪文件擦除到指定的提交)
$ git reset --hard HEAD~
如果仓库地址更改,则需要更新其远程位置
$ git remote set-url origin git@address:user/repo.git
或者,使用新位置编辑 .git/config
。
附加 Signed-off-by 行 (名称-电子邮件签名已添加到提交中,某些项目需要此签名)
$ git commit -s
自动将 Signed-off-by 附加到补丁 (当使用 git format-patch commit
时)
$ git config --local format.signoff true
提交已更改文件的特定部分。如果进行了大量更改,最好将其拆分为多个提交,这将非常有用
$ git add -p
签署提交
Git 允许使用 GnuPG 签署提交和标签,请参见 签署你的工作。
export GPG_TTY=$(tty)
(或者使用 pinentry-tty),否则,如果 GPG 当前处于锁定状态 (因为它无法提示输入 pin),则签名步骤将失败。要配置 Git 以自动签署提交
$ git config --global commit.gpgSign true
在非 master 分支上工作
有时,维护人员会要求在分支上完成工作。这些分支通常称为 devel
或 testing
。首先克隆仓库。
要进入 master 之外的其他分支 (git clone 仅显示 master 分支,但其他分支仍然存在,使用 git branch -a
显示)
$ git checkout -b branch origin/branch
现在像往常一样编辑;但是为了保持仓库树同步,请务必使用以下两种方式
$ git pull --all $ git push --all
直接发送补丁到邮件列表
如果您想直接发送补丁到邮件列表,您必须安装以下软件包:perl-authen-sasl 和 perl-io-socket-ssl。
确保您已配置用户名和电子邮件地址,请参阅 #配置。
配置您的电子邮件设置
$ git config --global sendemail.smtpserver smtp.example.com $ git config --global sendemail.smtpserverport 465 $ git config --global sendemail.smtpencryption ssl $ git config --global sendemail.smtpuser foobar@example.com
现在您应该能够将补丁发送到邮件列表(另请参阅 OpenEmbedded: 通过电子邮件发送补丁 和 git-send-email.io)
$ git add filename $ git commit -s $ git send-email --to=pacman-contrib@lists.archlinux.org --confirm=always -M -1
使用大型 git 仓库
当使用大型远程仓库时,需要获取大量数据。以下示例使用 Linux 内核来说明如何使用此类代码库。
获取整个仓库
最简单的解决方案是获取整个仓库
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
git clone
无法恢复。您可以使用 git pull
更新您的仓库。
部分获取仓库
为了将您的本地仓库限制为源仓库的较小子集,例如在 v4.14 之后 bisect 一个错误,请使用浅克隆
$ git clone --shallow-exclude v4.13 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
您将获得 v4.14 及更高版本,但不包括 v4.13 及更旧版本。
如果您只想获取最新的快照,忽略所有历史记录。(如果 tarball 可用且足够,请选择它。从 git 仓库下载需要更多带宽。)您可以使用以下命令获取它
$ git clone --depth 1 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
您稍后可以获取较旧的提交,如下两个示例所示
$ git fetch --tags --shallow-exclude v4.1 $ git fetch --tags --shallow-since 2016-01-01
--tags
,则不会获取标签。使用 Scalar
Scalar,以前称为 Virtual File System for Git (VFS for Git),允许访问 git 仓库而无需本地实例。
请参阅 scalar(1)。
获取其他分支
在上面的例子中,您的本地仓库仅跟踪主线内核,即最新开发完成的地方。假设您想要最新的 LTS,例如最新的 4.14 分支。您可以通过以下方式获取它
$ git remote set-branches --add origin linux-4.14.y $ git fetch --shallow-exclude v4.14 $ git branch --track linux-4.14.y origin/linux-4.14.y
最后一行不是强制性的,但可能是想要的。(要了解您想要的分支的名称,没有通用的规则。您可以通过查看 gitweb 界面中的“ref”链接来猜测一个。)
对于 linux-4.14.y 的快照,请执行
$ git checkout linux-4.14.y
或者将其提取到另一个目录中,
$ mkdir /path/to/src-4.14; cd /path/to/src-4.14 $ git clone --no-local --depth 1 -b linux-4.14.y ../linux-stable
像往常一样,执行 git pull
以更新您的快照。
过滤机密信息
有时,软件可能会将纯文本密码保存在配置文件中,而不是挂钩到密钥环中。在这些情况下,git clean-filters 可能有助于避免意外提交机密信息。例如,以下文件将过滤器分配给文件“some-dotfile”
.gitattributes
some-dotfile filter=remove-pass
每当文件“some-dotfile”被检入 git 时,git 将在检入之前在文件上调用过滤器“remove-pass”。过滤器必须在 git 配置文件中定义,例如
.git/config
[filter "remove-pass"] clean = "sed -e 's/^password=.*/#password=TODO/'"
HTML 帮助文件
通过安装 git-htmldocsAUR,git help
文档也可以 HTML 形式提供。安装后,可以通过传递 -w
标志来访问 HTML 文档。例如
$ git help -w merge
可以通过设置 git config
选项来默认加载 HTML 文档
$ git config --global help.format html
扩展
助手和实用程序
- git-extras — Git 实用程序集合(仓库摘要、repl、变更日志、作者提交、等等)
- https://github.com/tj/git-extras || git-extrasAUR - 如果您正在使用 oh-my-zsh,您也可以启用 git-extras 插件
- gitflow-cjs — 使用 Vincent Driessen 的分支模型 扩展 Git。CJS 版本是一个积极维护的分支。
- gitmoji-cli — 一个 gitmoji 交互式 NodeJS 客户端,用于在提交消息中使用 gitmojis。
大型文件同步支持
- git-annex — 用 Haskell 编写的分布式文件同步系统,允许使用 Git 管理大型数据。
多个 Git 仓库管理器
- git-bulk — 用 Bash 编写的命令行工具,用于管理多个 Git 仓库。
- mani — 用 Go 编写的命令行工具和 TUI,用于管理多个 Git 仓库。
- gita — 用 Python 编写的命令行工具,用于管理多个 Git 仓库。
- mu-repo — 用 Python 编写的命令行工具,用于管理多个 Git 仓库。
- myrepos (mr) — 用 Perl 编写的命令行工具,用于管理多个 Git 仓库。