跳转至内容

Git

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

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

安装

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

图形前端

另请参阅 Git 图形化客户端

  • 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 图形化客户端。
https://github.com/soramimi/Guitar || guitarAUR
  • gitui — 使用 Rust 编写的快速 Git 终端界面。
https://github.com/extrawurst/gitui || gitui
  • Kommit — 用于 KDE 的 Git 图形化客户端。
https://apps.kde.org/kommit/ || kommit
  • lazygit — 简单的 Git 命令终端界面。
https://github.com/jesseduffield/lazygit || lazygit
  • QGit — 用于浏览修订历史、查看补丁内容和已更改文件的 Git 图形化查看器,可图形化跟踪不同的开发分支。
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 分支 - 远程分支

变基 (Rebasing)

参见 Git 分支 - 变基

协作

分布式工作流

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

向项目贡献代码

参见 分布式 Git - 向项目贡献代码

维护项目

参见 分布式 Git - 维护项目

Git 工具

修订选择

参见 Git 工具 - 修订选择

交互式暂存

参见 Git 工具 - 交互式暂存

储藏 (Stashing) 与清理

参见 Git 工具 - 储藏与清理

签署你的工作

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

搜索

参见 Git 工具 - 搜索

重写历史

参见 Git 工具 - 重写历史

重置 (Reset) 详解

参见 Git 工具 - 重置详解

高级合并

参见 Git 工具 - 高级合并

Rerere

参见 Git 工具 - Rerere

使用 Git 调试

参见 Git 工具 - 使用 Git 调试

子模块 (Submodules)

参见 Git 工具 - 子模块

打包 (Bundling)

参见 Git 工具 - 打包

替换 (Replace)

参见 Git 工具 - 替换

凭据存储

参见 Git 工具 - 凭据存储

技巧与提示

使用 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 配置

包含单独的配置文件

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 连接,Git over SSH 可能比 HTTPS 更快。此外,某些服务器(如 AUR)只允许通过 SSH 进行推送。例如,以下配置将对托管在 AUR 上的任何仓库设置使用 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 启动文件 中 source /usr/share/git/completion/git-completion.bash。或者,安装 bash-completion

Git 提示符 (Prompt)

Git 软件包随附了一个提示符脚本。要启用它,请 source /usr/share/git/completion/git-prompt.sh 并使用 %s 参数设置自定义提示符

请注意,命令替换必须进行转义,详情请参见 Bash/Prompt 自定义#嵌入命令。有关持久化配置,请参阅 命令行 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 图形别名(例如 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 来更新仓库。

部分获取仓库

为了将本地仓库限制为 origin 的较小部分(例如在 v4.14 之后用于二分查找错误),请使用浅克隆:

$ 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 和 sed 在 `\$` 上的冲突

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、更新日志、作者提交等)
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 仓库

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

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.