这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记
这里总结一下Git的基本知识
一、git是什么
首先让我们来了解一下Git是什么
-
本地版本控制
- 依托于本地磁盘进行版本控制
-
集中式版本控制
- 存在一个统一的远端服务器,用于版本控制,本地不存储版本控制
-
分布式版本控制
- 每个库都拥有所有的版本控制信息,远端服务器用于不同库之间进行版本信息同步
二、为什么要学习Git
- 业界绝大多数公司都是基于Git进行代码管理,因此Git是一个程序员的必备技能
- 目前绝大多数的开源项目都是基于Git维护的,参与这些项目的开发都需要使用Git
三、Git 基本使用方式
查看Git目录
tree .git
没有tree命令请先安装
sudo apt-get install tree
项目初始化
mkdir
cd study
git init
其他参数:
--initial-branch 初始化的分支
--bare 创建一个裸仓库(纯Git目录,没有工作目录)
--template 可以通过模板来创建预先构建好的自定义Git目录
常见Git配置
查看配置
cat .git/config
用户名配置
git config --global user.name "benben"
git config --global user.email benben@....com
Instead of 配置
git config --global url.git@github.com:.insteadOf https://github.com/
# npm using https for git
git config --global url."https://github.com/".insteadOf git@github.com:
git config --global url."https://".insteadOf git://
# npm using git for https
git config --global url."git@github.com:".insteadOf https://github.com/
git config --global url."git://".insteadOf https://
Git命令别名配置
git config --global alias.cin "commit --amend --no-edit"
即用cin代替commit --amend --no-edit命令
Git Remote
git remote 命令用于在远程仓库的操作。
查看Remote
git remote -v
添加Remote
git remote add origin_ssh git@github.com:git/git.git
git remote add origin_http https://github.com/git/git.git
更换Remote url
git remote set-url [remote's name] [new url]
//Ex: git remote set-url origin git@github.com:git/...
同一个Origin设置不同的Push和Fetch URL
git remote add origin git@github.com:git/git
git remote set-url --add --push origin git@github.com:MY_REPOSITY/git
HTTP Remote
免密配置
- 内存:
git config --global credential.helper 'cache --timeout=3600'
- 硬盘:
git config --global credential.helper "store --file/path/to/credential-file"
不指定目录的情况默认是~/.git-credentials
SSH Remote
SSH可以通过公私钥的机制,将生成的公钥存放在服务端,从而实现免密访问
目前的Key的类型有四种,分别是dsa、rsa、ecdsa、ed25519,默认使用的是rsa,但由于一些安全问题,现在不推荐使用rsa和dsa了,优先使用ed25519。
ssh-keygen -t ed25519 -C "your_email@example.com"
密钥默认存在~/.ssh/id_ed25519.pub
Git Add
git add 命令可将该文件添加到暂存区
//添加一个或多个文件到暂存区
git add [file1] [file2] ...
//添加指定目录到暂存区,包括子目录
git add [dir]
//添加当前目录下的所有文件到暂存区
git add .
使用git status可以显示工作目录和暂存区的状态。
Refs
Refs文件的内容就是对应的Commit ID
因此把ref当做指针,指向对应的Commit来表示当前Ref对应的版本。
refs/head前缀表示的是分支,除此之外还有其他种类的ref,比如refs/tags前缀表示的是标签。
Branch
git checkout -b可以创建一个新分支
分支一般用于开发阶段,是可以不断添加Commit进行迭代的
git checkout -b test
以上命令切换到一个新分支'test'
Tag
标签一般表示的是一个稳定版本,指向的Commit一般不会变更
git tag v0.0.1
通过git tag命令生成tag
Annotation Tag 附注标签
附注标签是一种特殊的Tag,可以给Tag提供一些额外的信息。
通过git tag -a命令来完成附注标签的创建。
git tag -a v0.0.2 -m "my version v0.0.2"
查看版本信息:
cat .git/refs/tags/v0.0.2
//得到一串ID,如:
//be7fb8574500354cd5887443552e92134c4c2486
//查看tag object的内容
git cat-file -p be7fb8574500354cd5887443552e92134c4c2486
历史版本的追溯和修改
追溯历史版本
- 获取当前版本代码
通过Ref指向的commit可以获取唯一的代码版本。
- 获取历史版本代码
Commit里面会存有parents commit字段,通过commit的串联获取历史版本代码。
修改文件,并提交,创建新的commit并查看最新的commit,发现新增parents信息。同时ref会指向新的commit。
修改历史版本
1. commit --amend
通过这个命令可以修改最近一次的commit信息,修改之后commit ID会变。
git commit --amend
2. rebase
通过git -rebase -i HEAD~3可以实现对最近三个commit的修改
- 合并commit
- 修改具体的commit message
- 删除某个commit
3. filter - branch
该命令可以指定删除所有提交中的某个文件或者全局修改邮箱地址等操作。
Objects
commit /tree /blob /tag在git中都统一称为Object
- Blob 存储文件内容
- Tree 存储文件目录信息
- Commit 存储提交信息,一个Commit对应唯一版本代码
三个信息的关系:
-
通过Commit寻找到Tree信息,每个Commit都会存储对应的Tree ID。
-
通过Tree存储的信息,获取到对应的目录信息。
-
从Tree中获得blob的ID,通过Blob ID获取对应的文件内容。
这里补充一些说明:
-
新增的Object
修改Commit后我们可以发现git object又出现了变化
但之前的commit并没有被删除。
-
悬空的Object
即没有ref指向的object
Git GC
- GC
通过
git gc命令,可以删除一些不需要的object,以及会对object进行一些打包压缩来减少仓库的体积。
指定时间:
git gc prune=now指定的是修剪多久之前的对象,默认是两周前
- Reflog reflog是用于记录操作日志,防止误操作后数据丢失,通过reflog来找到丢失的数据,手动将日志设置为过期。
Git Clone & Pull & Fetch
Clone
拉取完整的仓库到本地目录,可以指定分支,深度
Fetch
将远端某些分支最新代码拉取到本地,不会执行merge操作,会修改refs/remote内的分支信息,如果需要和本地代码合并需要手动操作。
Pull
拉取远端分支,并和本地代码进行合并,操作等同于git fetch + git merge,也可以通过git pull --rebase完成git fetch + git rebase操作
Git Push
常用命令:
一般使用git push origin master命令即可完成
冲突问题:
- 如果本地的commit记录和远端的commit历史不一样,则会产生冲突,比如
git commit --amend或者git rebase都有可能导致这个问题。
2.如果该分支就自己一个人使用,或者团队内确认过可以通过git push origin master -f来完成强制推送,一般不推荐主干分支进行该操作,正常都应该解决冲突后再进行推送。
推送规则限制:
可以通过保护分支,来配置一些保护机制,防止误操作,或者有一些不合规的操作出现,导致代码丢失。
四、Git 常见问题
1. 明明配置了Git,但是依然没有办法拉取代码
可能原因:
-
免密认证没有配
-
Instead Of配置没有配,配的SSH免密配置,但是使用的还是HTTP访问
2. Fetch了远端分支,但是看当前的分支历史还是没有变化
可能原因:
- Fetch会把代码拉取到本地的远端分支,但是并不会合并到当前分支,所以当前分支历史没有变化