Git 入门
Git 简单知识
工作目录(Working Directory):在计算机文件系统中实际编辑和修改代码的地方(本机文件目录及文件)。在工作目录中,您可以对代码进行更改、新增文件或删除文件,但这些变更并不会立即被 Git 跟踪。
暂存区(Staging Area):也称为“索引(Index)”,是介于工作目录和版本库之间的中间区域。当您修改了工作目录中的文件后,您可以使用 git add 命令将这些更改添加到暂存区。暂存区中存储了您要在下一次提交中包含的更改快照。
版本库(Repository):也称为“Git 版本库”,它是保存所有项目历史记录的地方。版本库包含了您提交的快照,以及用于跟踪这些快照如何相互关联的元数据。每次使用 git commit 命令提交更改时,会在版本库中创建一个新的提交对象。
除了上面的常用词汇外,可能您还听过远程库(Git 仓库)、上游仓库(upstream),其中远程库泛指代码托管平台(可以自行搭建):Github、Gitee 等代码托管平台,而上游仓库特指 fork 的仓库。
Git 配置基本信息
# 配置全局个人信息
$ git config --global user.name "个人名称或昵称"
$ git config --global user.email "邮箱"
# 列出所有配置信息:
$ git config --list / git config -l
# 取消某一项全局配置
$ git config --global --unset user.name
下面的内容在对 Git 不熟悉时不推荐设置
# git 提交显示中文
$ git config --global core.quotepath false
$ git config --global i18n.commitencoding utf-8
$ git config --global i18n.logoutputencoding utf-8
检入:提交,检出:下载
在 Git 执行配置的时候有一些选项:
--local仅指定当前本地 git 仓库--global指定所有当前用户的 git 仓库--system指定当前系统的所有 git 仓库(很少使用)
常用命令
# 将当前目录中所有文件文件改动添加到git暂存区,也可以一次提交多个指定文件,使用空格分开
$ git add .
# 提交到本地版本库并备注提交信息
$ git commit -m "my first commit"
# 上面两条命令可以合并成一条
$ git commit -am 'commit msg'
# 如果第一次提交(commit但未push)的内容写的不好或者还有新的相关文件未提交,可以使用下面的命令覆盖之前一次的 commit
$ git commit --amend -m "override first commit"
# 将本地分支推送到远程分支并建立映射,如果远程不存在将自动创建
# 推送到远程仓库,如果本地和远程的分支名称相同,可以写一个分支名
# 第一个 master 是本地分支,后面的一个是远程分支
$ git push -u origin [local-branch]:[remote-branch]
# 删除远程分支 --delete 简写为 -d
$ git push origin -d [branch-name]
# 移除文件
# 从暂存区移除文件,会把工作区相应文件一并删除,回收站无法还原。如果该文件没有提交,则无法删除,可以使用 -f 选项强制删除。
$ git rm [file]
# 移除 commit 的文件,保留工作区文件;如果不加 --cached,那么暂存区和本地的文件都会被删除
$ git rm --cached [file]
# 移除 commit 的文件夹
$ git rm --cached -r [path]
# 克隆远程库到本地
$ git clone [repo-url]
# 克隆指定的分支
$ git clone -b [branch-name] [repo-url]
# --depth 可以简写为 -d
$ git clone --depth [num] https://github.com/user/repo.git
Note
--depth是 clone 命令的一个选项,用于指定克隆的历史记录的深度。num 是一个参数,由自己指定,表示只克隆最近的 num 次提交的历史记录,而不是整个仓库的完整历史记录。这可以节省时间和空间,尤其是在克隆大型仓库时非常有用。如果是为了学习就可以使用
--depth选项只 clone 最近的一次提交,没有必要全部 clone,下载的速度会加快;如果是想要为项目添砖加瓦做贡献则推荐全部 clone。
upstream
# 关联上游仓库
$ git remote add upstream [upstream-repo-url]
# 取消关联上游仓库
$ git remote remove upstream
# 更新上游仓库
$ git pull upstream
# 与上游仓库建立分支映射
$ git pull --track upstream [branch-name]
# 如果已经有一个本地分支,并且想要将其设置为跟踪上游的分支
$ git branch -u upstream/[branch-name] [branch-name]
remote
# 关联远程仓库
$ git remote add origin https://github.com/user/repo.git
# 取消远程关联
$ git remote remove origin
# 更新远程关联的仓库
$ git remote set-url origin [repo-url]
# 删除/清理本地分支存在,但远程仓库中不存在的分支
# 即:清理本地和远程没有跟踪关系的分支
$ git remote prune origin
branch
# 新建分支
$ git branch [new-branch-name]
# 切换到指定分支并更新工作目录
$ git switch -c [branch]
# 查看本地所有分支
$ git branch -a
# 查看远程分支
$ git branch -r
# 查看本地与远程分支的一映射关系
$ git branch -vv
# 重命名本地分支
$ git branch -m [old-branch] [new-branch]
# 删除本地分支,如果要强制删除分支,使用 -D 选项
$ git branch -d [branch]
# 删除远程分支
$ git push -d origin [branch-name]
# 也可以使用以下命令
$ git push origin :[branch-name]
log
# 提交历史
$ git log
# 图形化显示
$ git log --graph
# 单行显示、短格式、长格式 oneline, full
$ git log --pretty=oneline/full
# 单行简写
$ git log --oneline
# 图形化输出 log
$ git log --graph --oneline
# 全格式图形化输出 log
$ git log --graph --pretty=full
reset
# 撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到指定版本
$ git reset --hard 版本ID
# 回退到某个版本,但工作目录和暂存区不会受到影响
$ git reset --soft 版本库ID
stash
git stash 命令将当前未提交的修改(即,工作区的修改和暂存区的修改)先暂时储藏起来,这样当前的工作区就干净了。然后可以直接切换到其它分支进行修改。修改完成后重新切换到当前分支下通过 git stash pop 命令将之前储藏的修改取出来,继续进行新功能的开发工作。
# 贮藏当前的工作区文件的修改
git stash
# 切换其它分支进行开发,开发完成后再切换到当前分支
# 取出最近一次的贮藏文件
git stash pop
上面的只是简单的使用,此选项是支持多次使用的,并且可以查看列表。
# 第一次修改文件
# 藏储文件时附加消息
git stash save [message]
# 第二次修改文件
# 藏储文件时附加消息
git stash save [message]
# 查看列表
git stash list
# 取出最近一次的文件
git stash pop
# 取出指定index的储藏的修改到工作区中
git stash apply stash@{index}
# 将指定index的储藏从储藏记录列表中删除
git stash drop stash@{index}
submodule
# clone 时直接 clone 子模块
git clone --recurse-submodules [repo-url]
# 添加子模块
$ git submodule add [repository-url] [path]
# 初始化子模块,根据 .gitmodules 文件设置子模块的 url
# 常与 update 连用
$ git submodule init --recursive
# 更新子模块,如果没有 clone 子模块则会 clone
$ git submodule update --recursive
# init 和 update 也可以使用一个命令
$ git submodule update --init --recursive
# 查看子模块状态
$ git submodule status
–recursive 为可选项,如果存在,会同时对嵌套的子模块进行相应的操作。
更新 submodule 为最新版本
$ git submodule update --remote
删除 submodule
$ cd [repo]
$ git submodule deinit [submodule-path]
$ rm -rf .git/modules/[submodule-path]
# 有需要的话可以使用 --force 移除
$ git rm -rf [submodule-path]
$ git commit -m "delete submodule"
$ git push
重置 submodule 地址
打开仓库下的 .gitmodules 文件,修改对应的 url 地址并保存,然后执行以下命令:
$ git submodule sync
此时,submodule 的信息已经更新,可以删除旧的子模块再使用 git submodule update –init –recursive 进行子模块初始化。
同时对所有子模块进行操作
$ git submodule foreach [git-cmd]
# 更新所有子模块到最新版本
$ git submodule foreach git pull origin main
# 查询所有子模块的状态
$ git submodule foreach git status
SSH-Key 配置
使用此方式交互减少密码的传输,非常推荐,本文直接讲解如何配置多个平台的 ssh key。
1. 生成Github用的SSH-Key
# Linux Mac
$ ssh-keygen -t ed25519 -C 'xxx@xx.com' -f ~/.ssh/github_id
# Window
$ ssh-keygen -t ed25519 -C 'xxx@xx.com' -f C:/Users/用户名/.ssh/github_id
2. 生成gitee使用的SSH-Key
# Linux Mac
$ ssh-keygen -t ed25519 -C 'xxx@xx.com' -f ~/.ssh/gitee_id
# Window
$ ssh-keygen -t ed25519 -C 'xxx@xx.com' -f C:/Users/用户名/.ssh/gitee_id
2022-08-22 修改为使用 ed25519 算法生成。
ssh-keygen 支持的部分选项说明:
| 选项 | 说明 |
|---|---|
| -b | 该选项指定密钥的位数。管理 SSH 用例的算法可能要求使用特定的密钥长度。一般来说,RSA 密钥使用 2048 位就足够了。 |
| -t | 指定要创建的 key 的类型,常见的有 RSA、DSA、ECDSA 等 |
| -f | 指定存储创建密钥的文件名。 |
| -C | 描述密钥的作用/说明 |
3. 修改 config 文件
SSH 可选参数配置详见:https://www.ssh.com/academy/ssh/config
SSH 配置按照以下顺序读取文件:
- 从命令行指定的选项。
~/.ssh/config中定义的选项(用户配置),一般都使用此配置方式。/etc/ssh/ssh_config中定义的选项(全局配置)。
# github1
# Host 可以自己定义,在此文件中必须唯一,之后在 down 源码时需要使用这个自定义的 host
Host github-repo1
# HostName 是代码托管平台的域名,例如:code.aliyun.com, github.com, gitee.com 等,也可以使用 IP
HostName github.com
# 认证方式:公钥
PreferredAuthentications publickey
# 与公钥配对的私钥路径
IdentityFile ~/.ssh/github1_id
# github2
Host github-repo2
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/github2_id
# gitee
Host gitee.com
HostName gitee.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/gitee_id
如果同一个平台配置了多个不同账号的SSH密钥,那么在进行 clone、remote 等操作时,地址需要做一些改变,否则会找不到而报错。例如 clone github2 账户的某个仓库:
git clone git@github-repo2.com:user/repo.git
4. 测试是否配置成功
# 使用 ssh -T 进行测试,成功的话会打印 Hi,username……
$ ssh -T git@gitee.com
$ ssh -T git@github-repo1
$ ssh -T git@github-repo2
加速访问 Github
在三、四、五、六线城市以及像浪子所在的偏远小山村中想要直接使用浏览器访问 GitHub 是有问题的,输入网址后按下回车键,这个页面都不带刷新的,会直接出现 “无法访问该网站” 的错误。解决办法之一就是修改 hosts 文件,加速访问这个体验并不明显,只是可以访问,偶尔抽风是正常的。推荐使用 302 或者 steam webkit
- Windows 系统,该文件在
C:\Windows\System32\drivers\etc目录下; - Linux 系统,则在
/etc/hosts。
Windows 推荐火绒,修改 hosts 文件超级方便。建议先对 hosts 文件备份,修改错误后可以还原。
访问 IPAddress.com,输入 github.com 回车查询。将获取到的 IP 与 Github 的域名写入到 hosts 文件中,例如:
140.82.113.4 github.com
Git 问题汇总
合并不相关的历史
有时候我们可能不会直接 clone 远程仓库,而是直接在本地创建新的 git 目录,然后在此目录中添加新的文件,最后再关联远程仓库。在这个前提下,如果远程仓库中 已经存在文件,直接 pull 的时候会报错:拒绝合并不相关的历史。
fatal: refusing to merge unrelated histories
这时我们可以使用 --allow-unrelated-histories 选项进行强制合并(也可以按照 Git 的提示去做,应该有设置分支关联的方式。Git 的报错提示还是很不错的)。
git pull origin [remote-branch] --allow-unrelated-histories

说些什么吧!