Git

来自 Arch Linux 中文维基
"I've met people who thought git is a front-end to GitHub. They were wrong, git is a front-end to the AUR." — Linus T.

Git 是由 Linux 内核作者 Linus Torvalds 设计并开发的版本控制系统(VCS),现在被用来维护 AUR 软件包以及数以千计的其他项目,其中包括 Linux 内核。

安装[编辑 | 编辑源代码]

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

图形化前端[编辑 | 编辑源代码]

参考 git GUI Clients

  • Bonsai — Git 版本控制管理器。maui包组
https://mauikit.org/apps/ || bonsai 的一部分
  • Giggle — 用于 git 的 GTK+ 前端。
https://wiki.gnome.org/Apps/giggle/ || giggle
  • GitAhead — 一个包含内置合并工具的 git 前端。
https://gitahead.github.io/gitahead.com/ || gitaheadAUR
  • Git Cola — 用 Python 编写的丝滑而强大的 git 图形前端。
https://git-cola.github.io/ || git-colaAUR
  • Git Extensions — 允许用户不使用命令行就可以完成 git 各项操作的图形前端。
https://gitextensions.github.io/ || gitextensionsAUR
  • gitg — 用于查看 git 仓库的 GNOME GUI 客户端。
https://wiki.gnome.org/Apps/Gitg || gitg
  • git-gui — Tcl/Tk 库编写的可移植 git 图形前端。
https://git-scm.com/docs/git-gui || git + tk
注意: 要打开 git-gui 的拼写检查功能,请安装 aspell,同时还需要与 LC_MESSAGES 环境变量 相对应的字典文件。参阅 FS#28181aspell
  • GitHub Desktop — 由 GitHub 开发的一个基于 Electron 的 GitHub 客户端。
https://github.com/desktop/desktop || github-desktopAUR github-desktop-binAUR
  • gitk — Tcl/Tk 库编写的 Git 仓库查看器。
https://git-scm.com/docs/gitk || git + tk
  • Gittyup — 基于 Qt 的 Git 客户端。
https://github.com/Murmele/Gttyup || gittyupAUR
  • Guitar — 一个 Git 的图形化前端。
https://github.com/soramimi/Guitar || guitarAUR
  • gitui — 用 Rust 编写的快速的 Git 终端用户界面。
https://github.com/extrawurst/gitui || gitui
  • Kommit — KDE 的 Git GUI 客户端。
https://apps.kde.org/kommit/ || kommit
  • lazygit — 一个简洁的 Git TUI 工具。
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://www.sublimemerge.com/ || sublime-mergeAUR
  • Tig — 基于 ncurses 的 git 字符模式前端。
https://jonas.github.io/tig/ || tig
  • ungit — 在不牺牲 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 的目录内,该目录包含了修订历史以及其他元数据。版本库所跟踪的目录(默认为父目录)称为工作目录。在工作树进行的更改在被提交 (commit) 前需要先暂存 (stage) 起来。Git 还可以让你恢复以前提交的工作树文件。

参见起步

获取 Git 仓库[编辑 | 编辑源代码]

参见获取 Git 仓库 - Git 基础

记录更改[编辑 | 编辑源代码]

参见记录每次更新到仓库 - Git 基础

查看提交记录[编辑 | 编辑源代码]

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

撤销修改[编辑 | 编辑源代码]

参见撤消操作 - Git 基础

分支 (branch)[编辑 | 编辑源代码]

参见分支简介 - Git 分支

分支与合并基础[编辑 | 编辑源代码]

参见分支的新建与合并 - Git 分支

分支管理[编辑 | 编辑源代码]

参见分支管理 - Git 分支

分支开发工作流[编辑 | 编辑源代码]

参见分支开发工作流 - Git 分支

远程分支[编辑 | 编辑源代码]

参见远程分支 - Git 分支

变基[编辑 | 编辑源代码]

参见变基 - Git 分支

多人合作[编辑 | 编辑源代码]

分布式工作流[编辑 | 编辑源代码]

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

为已有项目贡献[编辑 | 编辑源代码]

参见向一个项目贡献 - 分布式 Git

维护自己的项目[编辑 | 编辑源代码]

参见维护项目 - 分布式 Git

Git 工具[编辑 | 编辑源代码]

选择修订版本[编辑 | 编辑源代码]

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

交互式暂存[编辑 | 编辑源代码]

参见交互式暂存 - Git 工具

贮藏与清理[编辑 | 编辑源代码]

参见贮藏与清理 - Git 工具

签署工作[编辑 | 编辑源代码]

参见签署工作 - Git 工具

搜索[编辑 | 编辑源代码]

参见搜索 - Git 工具

重写历史[编辑 | 编辑源代码]

参见重写历史 - Git 工具

重置揭密[编辑 | 编辑源代码]

参见重置揭密 - Git 工具

高级合并[编辑 | 编辑源代码]

参见高级合并 - Git 工具

Rerere[编辑 | 编辑源代码]

参见Rerere - Git 工具

使用 Git 调试[编辑 | 编辑源代码]

参见使用 Git 调试 - Git 工具

子模块[编辑 | 编辑源代码]

参见子模块 - Git 工具

打包[编辑 | 编辑源代码]

参见打包 - Git 工具

替换[编辑 | 编辑源代码]

参见替换 - Git 工具

凭证存储[编辑 | 编辑源代码]

参见凭证存储 - Git 工具

提示与技巧[编辑 | 编辑源代码]

使用 git-config[编辑 | 编辑源代码]

Git 从 4 个 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"

设置默认的推送 (push) 行为:

$ git config --global push.default simple

设置不同的 git difftool 工具(默认是 meld):

$ git config --global diff.tool vimdiff

更多信息请参阅 git-config(1)配置 Git

保持良好的礼仪[编辑 | 编辑源代码]

  • 当你想为一个现有的项目贡献时,请先阅读并理解这个项目的许可,因为它可能会过度限制你更改代码的权力。有些许可会在代码的所有权方面引起争议。
  • 理解这个项目的社区,以及你可以融入其中的程度。要了解项目的主要方向,可以阅读所有文档甚至是代码库的 log
  • 当发起一个合并请求,或者提交一个补丁时,保证它是小改动并且有完善的文档;这将有助于项目维护者理解你的改动,并决定是否合并这些改动或是让你再改一下。
  • 如果贡献被拒绝,不要气馁,毕竟这是他们的项目。如果它很重要,请尽可能清楚和耐心地讨论这次贡献的理由,最终可能通过这种方法解决问题。

加快身份验证[编辑 | 编辑源代码]

每次向 Git 服务器推送时都要认证身份,你可能会想要避免这种麻烦。

使用 git-credential-libsecret 作为凭证帮助程序[编辑 | 编辑源代码]

Git 可能会从 org.freedesktop.secrets 兼容密钥环(如 GNOME KeyringKeePassXC英语KeePass#Secret ServiceKDE 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 使用 SSH 可能比使用 HTTPS 更快。同时,一些服务器(比如 AUR)只允许通过 SSH 推送更改。例如,像下面这样配置可以使得 Git 通过 SSH 访问 AUR 上的任何仓库。

~/.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 参数设置一个自定义 shell 提示符:

  • Bash 用户: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
  • zsh 用户: setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '

要自动完成这项工作,请参阅命令行解释器#配置文件

当切换至一个 Git 仓库所在目录时,shell 提示符会变成所在分支名称。也可以配置提示符来显示其他信息:

Shell 变量 信息
GIT_PS1_SHOWDIRTYSTATE 已暂存 (staged) 显示 +,未暂存 (unstaged) 显示 *
GIT_PS1_SHOWSTASHSTATE 已储藏 (stashed) 显示 $
GIT_PS1_SHOWUNTRACKEDFILES 有未跟踪文件时显示 %
GIT_PS1_SHOWUPSTREAM <, >, <> 分别表示落后、领先或偏离上游。
GIT_PS1_STATESEPARATOR 分支名称和状态符号之间的分隔符
GIT_PS1_DESCRIBE_STYLE 分离 HEAD 时,相对于标签/分支显示提交
GIT_PS1_SHOWCOLORHINTS 显示颜色

环境变量的完整文档可在脚本的注释中找到。

注意:
  • 如果发生了 $(__git_ps1) 返回 ((unknown)) 的情况,是因为有一个 .git 文件夹在你当前的文件夹里面,但却不包含任何存储库,因此 Git 不认识它。例如,将 Git 在~/.gitconfig 的配置文件误认为在 ~/.git/config 就会发生这种情况。
  • 如果提示符在遇到非常大的存储库时延迟,很可能是由于 GIT_PS1_SHOWUNTRACKEDFILES 选项,该选项每次都会触发完整的目录树扫描以检测新文件,从而导致明显的性能影响。要为这些存储库本地禁用此选项,您可以使用命令 git config --local bash.showUntrackedFiles false

你也可以使用来自 AUR 的自定义 git shell 提示符软件包,例如 bash-git-promptAURgittifyAUR

可视化显示[编辑 | 编辑源代码]

要了解已经完成了多少工作:

$ git diff --stat

带有 fork 显示的 git log

$ git log --graph --oneline --decorate

给图形化的 git log 做一个别名(使用 git graph 即可显示经过修饰的 log):

$ git config --global alias.graph 'log --graph --oneline --decorate'

关于提交 (commit) 的小提示[编辑 | 编辑源代码]

重置为以前的提交(非常危险,这将会擦除所有内容并改写为特定提交):

$ git reset --hard HEAD^

如果远程仓库的地址发生变化,可以这样更新它的位置:

$ git remote set-url origin git@address:user/repo.git

自动附加签名行到提交(将某个 姓名-电邮 签名添加到提交中,某些项目会要求这样做):

$ git commit -s

自动附加签名到补丁(使用 git format-patch commit 时生效):

$ git config --local format.signoff true

提交已更改文件的特定部分。如果有大量更改时,最好拆分成多个提交,这种情况下这个命令通常很有用:

$ git add -p

对提交 (commit) 签名[编辑 | 编辑源代码]

Git 允许使用 GnuPG 对提交和标签进行签名,请参见签署工作

注意: 如果是借助 pinentry 来进行 GPG 签名,请确保 export GPG_TTY=$(tty)(或者使用 pinentry-tty),否则当 GPG 处于锁定状态时签名这一步会失败(因为它无法在 shell 提示符里询问 pin 码)。

配置 Git 使它自动对提交进行签名:

$ git config --global commit.gpgSign true

在非主分支上工作[编辑 | 编辑源代码]

偶尔项目维护人员会要求你在其他分支上完成工作。这些分支通常被称为 develtesting。首先要克隆存储库。

要进入不是主分支的分支(git clone 只会显示主分支,但其他分支其实也是存在的,用 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 587
$ git config --global sendemail.smtpencryption tls
$ git config --global sendemail.smtpuser foobar@example.com

现在你应该可以将补丁发送至某个邮件列表了(可参阅OpenEmbedded:How to submit a patch to OpenEmbedded#Sending patches):

$ git add filename
$ git commit -s
$ git send-email --to=openembedded-core@lists.openembedded.org --confirm=always -M -1

远程库很大时的注意事项[编辑 | 编辑源代码]

使用大型远程存储库时,必须获取大量数据。以下示例使用 Linux 内核来说明如何使用此类代码库。

接收整个仓库[编辑 | 编辑源代码]

最简单的解决方案是获取整个存储库:

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
注意: git clone 不支持断点续传。

可以通过 git pull 更新存储库。

部分接收[编辑 | 编辑源代码]

为了将本地存储库限制为原存储库的较小子集,例如在 v4.14 之后分离出错误,请使用浅克隆 (shallow clone):

$ 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,就不会获取标签。

获取其他分支[编辑 | 编辑源代码]

在上面的示例中,本地的仓库仅跟踪主线内核,即“最新开发”的内核。假设你想获取最近的 LTS 内核,比如最新的 4.14 分支,可以这么做:

$ git remote set-branches --add origin linux-4.17.y
$ git fetch
$ git branch --track linux-4.17.y origin/linux-4.17.y

最后一行不是必须的,但你应该需要执行它。 (要获取需要的那个分支的具体名称,没有什么通用的方法,或许可以靠 Gitweb 页面的“ref”链接来猜测)

如果需要 linux-4.17.y 的快照,这样做:

$ git checkout -b linux-4.17.y

或者将它解压到其他目录里:

$ mkdir /foo/bar/src-4.17; cd /foo/bar/src-4.17
$ git clone --no-local --depth 1 -b linux-4.17.y  ../linux-stable

然后像平常一样,执行 git pull 来更新你的快照。

未来可能出现的其他方案[编辑 | 编辑源代码]

Git 虚拟文件系统 (Git Virtual Filesystem, GVFS) 由微软开发,允许在不克隆仓库至本地的情况下使用 git 仓库。(参阅 Microsoft 的这篇博客Wikipedia 文章。)

它已经有了一个后继版本:Scalar,可在 git-vfsAUR[损坏的链接:找不到软件包] 中找到,这是 Microsoft 的 git 分支,包括 gvfs 和 scalar。

过滤机密信息[编辑 | 编辑源代码]

有时,软件可能会将纯文本密码保存在配置文件中,而不是挂接到密钥环中。在这些情况下,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 过滤器和 sed 争夺 `\$`(英文)

HTML 帮助文件[编辑 | 编辑源代码]

通过安装 git-htmldocsAUR,可以以 HTML 形式获取 git help 文档。安装后,可以通过传递 -w 标志来访问 HTML 文档。例如:

$ git help -w merge

可以通过设置 git config 选项默认加载 HTML 文档:

$ git config --global help.format html

扩展[编辑 | 编辑源代码]

https://github.com/petervanderdoes/gitflow || gitflow-avhAUR
  • git-extras — 一些 git 实用程序[存储库概览、交互式命令行环境 (repl)、变更日志填充、作者提交百分比等]
https://github.com/tj/git-extras || git-extrasAUR⸺如果使用 oh-my-zsh,还可以启用 git-extras 插件
  • gitmoji-cli — 一个 gitmoji 交互式 NodeJS 客户端,用于在提交消息中使用 gitmojis。
https://github.com/carloscuesta/gitmoji-cli || nodejs-gitmoji-cliAUR

参见[编辑 | 编辑源代码]