Git简单知识
工作目录(Working Directory):在计算机文件系统中实际编辑和修改代码的地方(本机文件目录及文件)。在工作目录中,您可以对代码进行更改、新增文件或删除文件,但这些变更并不会立即被 Git 跟踪。
暂存区(Staging Area):也称为“索引(Index)”,是介于工作目录和版本库之间的中间区域。当您修改了工作目录中的文件后,您可以使用 git add
命令将这些更改添加到暂存区。暂存区中存储了您要在下一次提交中包含的更改快照。
版本库(Repository):也称为“Git 版本库”,它是保存所有项目历史记录的地方。版本库包含了您提交的快照,以及用于跟踪这些快照如何相互关联的元数据。每次使用 git commit
命令提交更改时,会在版本库中创建一个新的提交对象。
除了上面的常用词汇外,可能您还听过远程库(Git 仓库)、上游仓库(upstream),其中远程库泛指代码托管平台(可以自行搭建):Github、Gitee 等代码托管平台,而上游仓库特指 fork 的仓库。
常用命令
简单常用
1 | # 将当前目录中所有文件文件改动添加到git暂存区,也可以一次提交多个指定文件,使用空格分开 |
clone
1 | # 克隆远程库到本地 |
–depth
有时候,我们可能会见到这样的命令:
1 | # 可以简写为 -d |
--depth
是 clone 命令的一个选项,用于指定克隆的历史记录的深度。num 是一个参数,由自己指定,表示只克隆最近的 num 次提交的历史记录,而不是整个仓库的完整历史记录。这可以节省时间和空间,尤其是在克隆大型仓库时会更加有用。
如果我们是为了学习和使用可以使用该选项 clone 最近的一次就可以,没有必要全部 clone,下载的速度会加快;而如果我们想要为项目添砖加瓦做贡献则推荐全部 clone。
upstream
1 | # 关联上游仓库 |
remote
1 | # 关联远程仓库 |
branch
1 | # 新建分支 |
log
1 | # 提交历史 |
reset
1 | # 撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到指定版本 |
stash
git stash 命令将当前未提交的修改(即,工作区的修改和暂存区的修改)先暂时储藏起来,这样当前的工作区就干净了。然后可以直接切换到其它分支进行修改。修改完成后重新切换到当前分支下通过 git stash pop
命令将之前储藏的修改取出来,继续进行新功能的开发工作。
1 | # 贮藏当前的工作区文件的修改 |
上面的只是简单的使用,此选项是支持多次使用的,并且可以查看列表。
1 | # 第一次修改文件 |
submodule
1 | # clone 时直接 clone 子模块 |
–recursive 为可选项,如果存在,会同时对嵌套的子模块进行相应的操作。
更新 submodule 为最新版本
1 | $ git submodule update --remote |
删除 submodule
1 | $ cd [repo] |
重置 submodule 地址
打开仓库下的 .gitmodules 文件,修改对应的 url 地址并保存,然后执行以下命令:
1 | $ git submodule sync |
此时,submodule 的信息已经更新,可以删除旧的子模块再使用 git submodule update --init --recursive 进行子模块初始化。
同时对所有子模块进行操作
1 | $ git submodule foreach [git-cmd] |
常见问题
合并不相关的历史
有时候我们可能不会直接 clone 远程仓库,而是直接在本地创建新的 git 目录,然后在此目录中添加新的文件,最后再关联远程仓库。在这个前提下,如果远程仓库中 已经存在文件,直接 pull 的时候会报错:拒绝合并不相关的历史。
1 | fatal: refusing to merge unrelated histories |
这时我们可以使用 --allow-unrelated-histories
选项进行强制合并(也可以按照 Git 的提示去做,应该有设置分支关联的方式。Git 的报错提示还是很不错的)。
1 | git pull origin [remote-branch] --allow-unrelated-histories |
22 端口被占用
如果你配置了 C:\Users\youruser\.ssh\config
文件,一般是如下配置:
1 | Host github.com |
但是,如果使用本地代理或者 tun 代理,例如使用 Watt Toolkit 工具加速 Github 的访问。那么你们惊奇的发现使用 SSH 协议的 Git 仓库就都推不上去了(还包括 pull、clone 等),必须关闭代理工具才可以,这是相当麻烦的。使用的时候显示以下错误:
1 | $ git pull |
然后网上查了查资料,有这样说的:
说法之一
这是 GitHub 为了应对网络限制,默认的 SSH 端口 22 可能会被一些机构或地区的防火墙封锁。因此,GitHub 提供了通过 HTTPS 端口 443 访问 Git 仓库的替代方案,这个端口通常用于 HTTPS 协议,大多数网络环境不会对它进行限制。
因此我们可以在 SSH 配置中,将端口设置为 443,实际上是让 SSH 连接通过 HTTPS 端口与 GitHub 的服务器建立连接。这样即使在默认的 22 端口被阻塞的情况下,您依然可以通过 443 端口进行正常的 Git 操作。
浪子不知,那么就把 Git 改为 443 端口代理转发试试看啦!结果还真可以!
就是 hostname
需要 修改 一下,下面两种方式任选一种配置即可。
方式一:
1 | Host github.com |
方式二:
1 | Host github.com |
这样配置之后可以 ssh -T git@github.com
测试一下,需要输入的话输入 yes
即可。
如果还是不行,就尝试一下网络上的普遍方式,设置代理,让 Git 直接走代理,Windows 的话可能较为麻烦,浪子未使用。
HTTP/HTTPS 代理设置
将 <proxy-url>
替换为您的代理服务器地址及端口
1 | git config --global http.proxy http://<proxy-user>:<proxy-password>@<proxy-url> |
如果不需要身份验证,则直接使用代理服务器地址:
1 | git config --global http.proxy http://<proxy-url>:<proxy-port> |
取消代理:
1 | git config --global --unset http.proxy |
SSH 代理设置
对于 SSH,Git 不直接支持 HTTP(S) 代理,但可以通过系统级的 SOCKS 代理转发。假设您有一个 SOCKS 代理运行在本地 1080 端口,可以在终端中启动 SSH 的动态端口转发:
1 | ssh -D 1080 <your-socks-proxy-server> |
1080 是 SOCKS 服务的默认端口。
Windows 系统中没有 nc
命令,可以去 Nmap 官网下载适用于 Windows 的版本安装。然后使用以下命令设置:
1 | git config --global core.sshCommand 'ssh -o ProxyCommand="ncat --proxy-type socks5 --proxy localhost:1080 %h %p"' |
另外,Windows 系统下也可以尝试使用 PuTTY 的 plink.exe
工具代替 ssh 实现类似功能:
1 | git config --global core.sshCommand '"C:/Program Files (x86)/PuTTY/plink.exe" -agent -proxycmd "ncat --proxy-type socks5 --proxy localhost:1080 %host %port"' |
plink 的路径需要修改为少侠本地的路径
SSL 验证 sslverify
http.sslverify
:通过 HTTP/HTTPS 访问 Git 远程仓库时,如果没有配置或是服务器上的 SSL 证书未经过第三方机构认证,Git就会报错。未知的证书意味着可能存在很大的风险。
以下报错在使用 HTTP 地址时比较常见,所以更加推荐使用 SSH 或者远程托管平台生成的 Token 等认证方式。当然,有时候我们不得不使用 HTTP,那么也是有解决办法的。
1 | SSL certificate problem: unable to get local issuer certificate |
如果对该仓库足够信任,我们可以在当前报错的 Git 仓库中使用以下命令关闭 SSL 验证(极不推荐 --global
全局配置选项):
1 | git config http.sslverify false |
上面这种方式对于 clone 时报错时是无效的,但是还有一种可能(这种可能性较小),因为 Windows 的 Git 默认使用 Linux 的后端加密方式,这种方式在 Windows 中可能有问题导致命令无法完成,在 Git 2.14 之后的版本中,可以使用以下命令使用内置的 Windows 网络安全层。
1 | git config --global http.sslbackend schannel |