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 — Git 的 GTK 前端。
- GitAhead — 图形化 Git 客户端,包括内置的合并工具。
- GitButler — 由 Git 提供支持、Tauri/Rust/Svelte 驱动的版本控制客户端。
- Git Cola — 使用 Python 编写的、简洁而强大的 Git 图形用户界面。
- Git Extensions — Git 的图形用户界面,允许您在不使用命令行的情况下控制 Git。
- gitg — 用于查看 Git 仓库的 GNOME GUI 客户端。属于 gnome-extra。
- git-gui — 基于 Tcl/Tk 的可移植 Git 图形界面。
- GitHub Desktop — 由 GitHub 团队开发的基于 Electron 的图形用户界面。
- gitk — 基于 Tcl/Tk 的 Git 仓库浏览器。
- Gittyup — 基于 Qt 的 Git 客户端。
- Guitar — Git GUI 客户端。
- gitui — 使用 Rust 编写的快速的 Git 终端 UI。
- 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"
请参阅 Getting Started - First-Time Git Setup。
请参阅 #技巧与窍门 以获取更多设置。
用法
Git 仓库包含在一个 .git 目录中,该目录保存着修订历史和其他元数据。默认由仓库跟踪的目录(通常是父目录)称为工作目录。工作树中的更改在记录(提交)到仓库之前需要先暂存。Git 还允许您恢复以前提交的工作树文件。
请参阅 Getting Started。
获取 Git 仓库
请参阅 Git Basics - Getting a Git Repository
记录更改
请参阅 Git Basics - Recording Changes to the Repository
查看更改历史
请参阅 Git Basics - Viewing the Commit History
撤销操作
请参阅 Git Basics - Undoing Things
使用远程仓库
请参阅 Git Basics - Working with Remotes
分支
请参阅 Git Branching - Branches in a Nutshell
基本分支和合并
请参阅 Git Branching - Basic Branching and Merging
分支管理
请参阅 Git Branching - Branch Management
分支工作流
请参阅 Git Branching - Branching Workflows
远程分支
请参阅 Git Branching - Remote Branches
变基 (Rebasing)
协作
分布式工作流
请参阅 Distributed Git - Distributed Workflows
为项目贡献
请参阅 Distributed Git - Contributing to a Project
维护项目
请参阅 Distributed Git - Maintaining a Project
Git 工具
版本选择
请参阅 Git Tools - Revision Selection
交互式暂存
请参阅 Git Tools - Interactive Staging
暂存和清理
请参阅 Git Tools - Stashing and Cleaning
签名您的工作
请参阅 Git Tools - Signing Your Work
搜索
重写历史
请参阅 Git Tools - Rewriting History
Reset 详解
请参阅 Git Tools - Reset Demystified
高级合并
请参阅 Git Tools - Advanced Merging
Rerere
使用 Git 进行调试
请参阅 Git Tools - Debugging with Git
子模块 (Submodules)
打包 (Bundling)
替换 (Replace)
凭据存储
请参阅 Git Tools - Credential Storage
技巧与提示
使用 git-config
Git 从四个 INI 类型配置文件读取其配置
/etc/gitconfig用于系统范围的默认设置~/.gitconfig和~/.config/git/config(自 1.7.12 起) 用于用户特定的配置.git/config用于仓库特定的配置
这些文件可以直接编辑,但通常方法是使用 git config,如下面的示例所示。
列出当前设置的变量
$ git config list {--local,--global,--system}
$ 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 Configuration。
包含单独的配置文件
自 2012 年的 v1.7.10 起,Git 可以使用 gitconfig 文件中的 include 关键字来构建一个包含多个配置文件的配置文件。
--local 或 --global 标志时,加载包含的配置文件默认是禁用的。要启用它,请在 git config get 和 git config list 命令中使用 --includes 标志。遵循良好的礼仪
- 在考虑为现有项目贡献时,请阅读并理解其许可证,因为它可能过度限制您修改代码的能力。某些许可证可能导致关于代码所有权的争议。
- 考虑项目的社区以及您如何能够很好地融入其中。要了解项目的方向,请阅读任何文档,甚至查看仓库的 日志。
- 请求拉取提交或提交补丁时,请保持其简洁且有充分的文档;这将有助于维护者理解您的更改并决定是否合并它们或要求您进行一些修改。
- 如果贡献被拒绝,请不要灰心,毕竟这是他们的项目。如果很重要,请尽可能清晰、耐心地讨论贡献的原因:通过这种方法,最终可能达成解决方案。
加快身份验证速度
您可能希望避免每次向 Git 服务器推送时都要进行交互式身份验证的麻烦。
- 如果您使用 SSH 密钥进行身份验证,请使用 SSH 代理。另请参阅 OpenSSH#Speeding up SSH 和 OpenSSH#Keep alive。
- 如果您使用用户名和密码进行身份验证,请切换到 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 上的任何仓库的 Git 设置为通过 SSH 进行。
~/.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 启动文件中 sourcing /usr/share/git/completion/git-completion.bash。或者,安装 bash-completion。
Git 提示符
Git 包自带一个提示符脚本。要启用它,请 sourcing /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) § GATHERING INFORMATION FROM VERSION CONTROL SYSTEMS。
请注意,命令替换必须进行转义,有关详细信息,请参阅 Bash/Prompt customization#Embedding commands。有关持久化配置,请参阅 Command-line shell#Configuration files。
当切换到 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 图形别名 (例如,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 签名提交和标签,请参阅 Signing Your Work。
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: Sending the Patches via Email 和 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 之后进行 bug 二分查找,请使用浅克隆:
$ 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-configuration 文件中定义,例如:
.git/config
[filter "remove-pass"] clean = "sed -e 's/^password=.*/#password=TODO/'"
HTML 帮助文件
通过安装 git-htmldocsAUR,还可以以 HTML 形式访问 git help 文档。安装后,可以通过传递 -w 标志来访问 HTML 文档。例如:
$ git help -w merge
通过设置 git config 选项可以默认加载 HTML 文档:
$ git config --global help.format html
扩展
助手和实用工具
- git-extras — Git 的实用工具集合(仓库摘要、repl、changelog、作者提交等)
- 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 仓库。
参见
- Git man pages,参见 git(1)
- Pro Git book
- GitHub 的 Git Reference
- Git 工作流程:Fork、远程仓库和 Pull Request
- VideoLAN wiki 文章
- Git Protocols - Git on the Server
- How to GitHub