Git

出自 ArchWiki
“我遇到过一些人,他们认为 git 是 GitHub 的前端。他们错了,git 是 AUR 的前端。” — Linus T.

Git 是由 Linux 内核的创建者 Linus Torvalds 设计和开发的版本控制系统 (VCS)。Git 现在用于维护 AUR 软件包,以及许多其他项目,包括 Linux 内核的源代码。

安装

安装 git 软件包。对于开发版本,安装 git-gitAUR 软件包。当使用诸如 git svngit guigitk 等工具时,请检查可选依赖项。

图形前端

另见 git GUI 客户端

  • Commit — 帮助你编写更好的 Git 和 Mercurial 提交信息的编辑器。
https://apps.gnome.org/Commit/ || commit
  • Forge Sparks — 简单的通知应用,支持 Github、GitLab、Gitea 和 Forgejo。
https://apps.gnome.org/ForgeSparks/ || forge-sparks
  • Giggle — GTK 的 git 前端。
https://wiki.gnome.org/Apps/giggle/ || giggle
  • GitAhead — 图形化 git 客户端,包含内置的合并工具。
https://gitahead.github.io/gitahead.com/ || gitaheadAUR
  • GitButler — 版本控制客户端,由 Git 支持,由 Tauri/Rust/Svelte 驱动。
https://gitbutler.com/ || gitbutlerAUR
  • Git Cola — 用 Python 编写的简洁而强大的 Git 图形用户界面。
https://git-cola.github.io/ || git-colaAUR
  • Git Extensions — Git 图形用户界面,允许你在不使用命令行的情况下控制 Git。
https://gitextensions.github.io/ || gitextensionsAUR
  • gitg — GNOME GUI 客户端,用于查看 git 仓库。是 gnome-extra 的一部分。
https://wiki.gnome.org/Apps/Gitg || gitg
  • git-gui — 基于 Tcl/Tk 的可移植 Git 图形界面。
https://git-scm.cn/docs/git-gui || git + tk
注意: 要在 git-gui 中启用拼写检查,需要 aspell 以及与 LC_MESSAGES 环境变量 对应的词典。参见 FS#28181aspell 文章。
  • GitHub Desktop — 由 GitHub 团队构建的基于 Electron 的图形用户界面。
https://github.com/desktop/desktop || github-desktopAUR github-desktop-binAUR
  • gitk — 基于 Tcl/Tk 的 Git 仓库浏览器。
https://git-scm.cn/docs/gitk || git + tk
  • Gittyup — 基于 Qt 的 Git 客户端。
https://github.com/Murmele/Gittyup || gittyupAUR
  • Guitar — Git GUI 客户端。
https://github.com/soramimi/Guitar || guitarAUR
  • gitui — 用 rust 编写的快速终端 UI,用于 git。
https://github.com/extrawurst/gitui || gitui
  • Kommit — KDE 的 Git GUI 客户端。
https://apps.kde.org/kommit/ || kommit
  • lazygit — 用于 git 命令的简单终端 UI。
https://github.com/jesseduffield/lazygit || lazygit
  • QGit — Git GUI 查看器,用于浏览修订历史记录、查看补丁内容和更改的文件,以图形方式跟踪不同的开发分支。
https://github.com/tibirna/qgit || qgit
  • RabbitVCS — 一组图形工具,旨在为你使用的版本控制系统提供简单直接的访问。
http://rabbitvcs.org/ || rabbitvcsAUR
  • Sublime Merge — 来自 Sublime Text 制造商的 Git 客户端。
https://merge.sublime.net.cn/ || sublime-mergeAUR
  • Tig — 基于 ncurses 的文本模式 Git 界面。
https://jonas.github.io/tig/ || tig
  • ungit — 在不牺牲 git 多功能性的前提下,为 git 带来用户友好性。
https://github.com/FredrikNoren/ungit || nodejs-ungitAUR

配置

为了使用 Git,你至少需要设置名称和电子邮件

$ git config --global user.name  "John Doe"
$ git config --global user.email "johndoe@example.com"

参见 起步 - 初次运行 Git 前的配置

有关更多设置,请参见 #技巧与诀窍

使用

Git 仓库包含在 .git 目录中,该目录保存了修订历史和其他元数据。仓库跟踪的目录(默认为父目录)称为工作目录。工作树中的更改需要先暂存,然后才能记录(提交)到仓库。Git 还允许你恢复先前提交的工作树文件。

参见 起步

获取 Git 仓库

参见 Git 基础 - 获取 Git 仓库


记录更改

参见 Git 基础 - 记录对仓库的更改


查看更改历史

参见 Git 基础 - 查看提交历史


撤销操作

参见 Git 基础 - 撤销操作

使用远程仓库

参见 Git 基础 - 使用远程仓库

分支

参见 Git 分支 - 分支的概述

基本分支和合并

参见 Git 分支 - 基本的分支与合并

分支管理

参见 Git 分支 - 分支管理

分支工作流

参见 Git 分支 - 分支工作流

远程分支

参见 Git 分支 - 远程分支

变基

参见 Git 分支 - 变基

协作

分布式工作流

参见 分布式 Git - 分布式工作流

为项目做贡献

参见 分布式 Git - 为项目做贡献

维护项目

参见 分布式 Git - 维护一个项目

Git 工具

版本选择

参见 Git 工具 - 修订版本选择

交互式暂存

参见 Git 工具 - 交互式的暂存

储藏与清理

参见 Git 工具 - 储藏与清理

签署你的工作

参见 Git 工具 - 签署你的工作

搜索

参见 Git 工具 - 搜索

重写历史

参见 Git 工具 - 重写历史

Reset 解惑

参见 Git 工具 - Reset 解惑

高级合并

参见 Git 工具 - 高级的合并

Rerere

参见 Git 工具 - Rerere

使用 Git 调试

参见 Git 工具 - 使用 Git 调试

子模块

参见 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

将默认编辑器从 vim 设置为 nano

$ 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 getgit config list 命令一起使用。

采取良好的礼仪

  • 当考虑为现有项目做出贡献时,请阅读并理解其许可证,因为它可能会过度限制你更改代码的能力。某些许可证可能会引起代码所有权方面的争议。
  • 考虑项目的社区以及你融入其中的程度。为了了解项目的方向,请阅读任何文档,甚至仓库的 日志
  • 当请求拉取提交或提交补丁时,请保持其小巧且文档齐全;这将有助于维护者理解你的更改并决定是否合并它们,或者要求你进行一些修改。
  • 如果贡献被拒绝,请不要气馁,毕竟这是他们的项目。如果它很重要,请尽可能清晰和耐心地讨论贡献的原因:通过这种方法,最终可能会达成解决方案。

加速身份验证

你可能希望避免每次推送到 Git 服务器时都进行交互式身份验证的麻烦。

使用 git-credential-libsecret 作为凭据助手

Git 可能会从 org.freedesktop.secrets 兼容的密钥环(如 GNOME KeyringKeePassXCKDE 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/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-promptAURgittifyAUR

可视化表示

为了了解已完成的工作量

$ 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 签署提交和标签,请参见 签署你的工作

注意: 要使用 pinentry curses 进行 GPG 签名,请确保 export GPG_TTY=$(tty) (或者使用 pinentry-tty),否则,如果 GPG 当前处于锁定状态 (因为它无法提示输入 pin),则签名步骤将失败。

要配置 Git 以自动签署提交

$ git config --global commit.gpgSign true

在非 master 分支上工作

有时,维护人员会要求在分支上完成工作。这些分支通常称为 develtesting。首先克隆仓库。

要进入 master 之外的其他分支 (git clone 仅显示 master 分支,但其他分支仍然存在,使用 git branch -a 显示)

$ git checkout -b branch origin/branch

现在像往常一样编辑;但是为了保持仓库树同步,请务必使用以下两种方式

$ git pull --all
$ git push --all

直接发送补丁到邮件列表

如果您想直接发送补丁到邮件列表,您必须安装以下软件包:perl-authen-saslperl-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/'"
注意: 在这种情况下,转义 sed 表达式的特殊字符可能是一项 棘手的任务。请记住,git 会将两个反斜杠变成一个,而 git 调用运行命令的 shell 会再次将两个反斜杠变成一个。有关更多详细信息,请参阅 Git filter and sed fight over `\$`

HTML 帮助文件

通过安装 git-htmldocsAURgit 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 插件
https://github.com/CJ-Systems/gitflow-cjs || gitflow-cjsAUR
  • gitmoji-cli — 一个 gitmoji 交互式 NodeJS 客户端,用于在提交消息中使用 gitmojis。
https://github.com/carloscuesta/gitmoji-cli || nodejs-gitmoji-cliAUR

大型文件同步支持

  • git-annex — 用 Haskell 编写的分布式文件同步系统,允许使用 Git 管理大型数据。
https://git-annex.branchable.com || git-annex

多个 Git 仓库管理器

  • git-bulk — 用 Bash 编写的命令行工具,用于管理多个 Git 仓库。
https://github.com/tj/git-extras || git-extrasAUR
  • mani — 用 Go 编写的命令行工具和 TUI,用于管理多个 Git 仓库。
https://github.com/alajmo/mani || maniAUR
  • gita — 用 Python 编写的命令行工具,用于管理多个 Git 仓库。
https://github.com/nosarthur/gita || gitaAUR
  • mu-repo — 用 Python 编写的命令行工具,用于管理多个 Git 仓库。
https://github.com/fabioz/mu-repo || mu-repoAUR
  • myrepos (mr) — 用 Perl 编写的命令行工具,用于管理多个 Git 仓库。
https://myrepos.branchable.com/ || myrepos

另请参阅