跳转至内容

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.cn/Commit/ || commit
  • Forge Sparks — 简单的通知应用程序,支持 Github、GitLab、Gitea 和 Forgejo。
https://apps.gnome.org.cn/ForgeSparks/ || forge-sparks
  • Giggle — Git 的 GTK 前端。
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 — 用于查看 Git 仓库的 GNOME GUI 客户端。属于 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 编写的快速的 Git 终端 UI。
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"

请参阅 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)

请参阅 Git Branching - 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 - Searching

重写历史

请参阅 Git Tools - Rewriting History

Reset 详解

请参阅 Git Tools - Reset Demystified

高级合并

请参阅 Git Tools - Advanced Merging

Rerere

请参阅 Git Tools - Rerere

使用 Git 进行调试

请参阅 Git Tools - Debugging with Git

子模块 (Submodules)

请参阅 Git Tools - Submodules

打包 (Bundling)

请参阅 Git Tools - Bundling

替换 (Replace)

请参阅 Git Tools - 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}

将默认编辑器从 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 Configuration

包含单独的配置文件

2012 年的 v1.7.10 起,Git 可以使用 gitconfig 文件中的 include 关键字来构建一个包含多个配置文件的配置文件。

提示 使用 --local--global 标志时,加载包含的配置文件默认是禁用的。要启用它,请在 git config getgit config list 命令中使用 --includes 标志。

遵循良好的礼仪

  • 在考虑为现有项目贡献时,请阅读并理解其许可证,因为它可能过度限制您修改代码的能力。某些许可证可能导致关于代码所有权的争议。
  • 考虑项目的社区以及您如何能够很好地融入其中。要了解项目的方向,请阅读任何文档,甚至查看仓库的 日志
  • 请求拉取提交或提交补丁时,请保持其简洁且有充分的文档;这将有助于维护者理解您的更改并决定是否合并它们或要求您进行一些修改。
  • 如果贡献被拒绝,请不要灰心,毕竟这是他们的项目。如果很重要,请尽可能清晰、耐心地讨论贡献的原因:通过这种方法,最终可能达成解决方案。

加快身份验证速度

您可能希望避免每次向 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 上的任何仓库的 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/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-promptAURgittifyAUR

可视化表示

要了解已完成的工作量

$ 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

注意 要使用 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: Sending the Patches via Emailgit-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/'"
注意 在此上下文中,转义 sed 表达式中的特殊字符可能是一项棘手的任务。请记住,git 会将两个反斜杠转换为一个,而 git 调用来运行命令的 shell 也会再次将两个反斜杠转换为一个。有关更多详细信息,请参阅 Git filter and sed fight over `\$`

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 插件
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

参见