跳转至

Git 速查备忘

Git 是一个分布式的版本控制系统,满足版本控制和多人协作的需求,并支持完全离线操作。本文档收录在实际使用中遇到的 Git 技巧和问题的解答,方便日后查阅。本文档同时也收录了一些有关 GitHub 的问题和解答。

重命名或删除被跟踪的文件

当需要重命名或删除被跟踪的文件时,使用 git mvgit rm,而不是直接使用 mvrm

递归地移动或删除(以移动为例)一个目录下的所有文件:git mv old_dir/* new_dir/

设置代理

有时 git 不会使用系统代理,这时可以手动指定 git 使用 ${protocol}://localhost:${port} 作为代理服务器。

如果使用的是 Clash,可以在设置中找到 Clash 提供的 socks5 与 http 端口。

使用下面的命令设置全局 git 的代理。

git config --global http.proxy ${protocol}://localhost:${port}

git 的配置有三个级别:system,global与local,分别对应系统,当前用户与当前仓库。

也可以指定只对某些地址使用代理(例如https://github.com)。

git config --global http.https://github.com.proxy ${protocol}://localhost:${port}

需要注意的是,实际上 git 的代理配置并不存在 https.proxy 选项,可以从 git 的文档中查看更多与此相关的内容:https://git-scm.com/docs/git-config#Documentation/git-config.txt-httpproxy

如果 git 的代理设置并没有按预期运行,可以使用下面的命令查询 git 的所有配置,查看是否有冲突的配置,使用 git config --global --unset xxx 取消冲突配置。

git config --global --list

另外可以使用下面的命令查询某一项配置(例如http.proxy)。

git config --global --get http.proxy

使用正则表达式匹配所有包含 proxy 字段的配置(如果代理设置是针对某一个地址的,直接使用上面的查询命令将会查询不到对应的结果):

git config --global --get-regexp ^.*proxy.*$

只提交部分修改

使用 git add 将想要提交更改的文件添加到暂存区,然后再用 git commit 提交即可。在 vscode 中,可以通过直接点击文件后面的「暂存更改」按钮来将文件的修改添加到暂存区。这两个方式是等价的。

如果只想提交某个文件的部分修改,可以使用 git add -p,可以在随后唤起的交互模式中选择要添加到暂存区的修改。

修改 commit 记录的描述

使用 git commit --amend 即可修改上一次 commit 记录的描述。

如果需要修改倒数第 n 个 commit 记录的描述,则需要通过 git rebase -i 先变基到 HEAD~(n+1),然后在打开的文本编辑器内找到你想要修改的 commit,将行首的 pick 改为 reword,这将再次打开一个文本编辑器对选定的 commit 描述进行修改。最后,通过 git rebase --continue 回到 HEAD,这可能会造成远程仓库的历史记录与本地不一致。

手动指定仓库域名的 DNS 解析

碰到以下问题:

$ git push
fatal: unable to access 'https://git.xxx.edu.cn/yyy/zzz.git/': Could not resolve host: git.xxx.edu.cn

假设没有管理员权限,并且已知域名 git.xxx.edu.cn 的 IP 地址为 10.1.2.3,使用 git 配置的 insteadOf 选项添加 URL 重写规则,使得每当 git 尝试访问 git.xxx.edu.cn 时,它会自动替换为 IP 地址。

git config --local url."http://10.1.2.3/".insteadOf "http://git.xxx.edu.cn/"
git config --local url."https://10.1.2.3/".insteadOf "https://git.xxx.edu.cn/"
git config --local url."ssh://git@10.1.2.3/".insteadOf "ssh://git@git.xxx.edu.cn/"

如果遇到 SSL 证书验证错误,可能是因为服务器的 SSL 证书是颁发给域名的而不是颁发给IP地址的。解决方案是为特定域名添加例外(需要确保该服务器是安全的):

git config --local http.https://10.1.2.3/.sslVerify false

【GitHub】临时对一个私有仓库进行拉取和推送

有时候需要临时对一个自己的私有仓库进行编辑,但又不希望在本地登录自己的 GitHub 账号或是在 git 中暴露自己的 GitHub ID,可以使用下面的方法。

在 GitHub 中,点击自己的头像,选择 Settings > Developer settings > Personal access tokens > Tokens (classic) > Generate new token > Generate new token (classic),手动选择 token 的过期日期,并选中 token 的作用域为 repo。

然后,在 clone 和 push 时,输入自己的 GitHub ID,然后使用该 token 作为密码。

提交 commit 时使用的 user.name 和 user.email 可以填写假名。

如果设置过 git config credential.helper store,linux 系统会将用户名和密码保存在 ~/.git-credentials 文件中;git config credential.helper cache 会临时缓存凭据。Token 过期后,存储的旧凭据无效,导致推送失败,产生以下错误:

ub@ub-VMware-Virtual-Platform:~/Documents/repo$ git push
remote: Invalid username or token. Password authentication is not supported for Git operations.
fatal: 'https://github.com/user/repo.git/' 鉴权失败

一个不算最佳的解决方案是,直接编辑 ~/.git-credentials 文件,删除对应的行(形如 https://username:ghp_xxxxx@github.com),或者直接 rm ~/.git-credentials 删除所有存储的凭据。然后,下一次 push 时,git 会重新要求输入用户名和密码。