这是我参与「第三届青训营 -后端场」笔记创作活动的的第4篇笔记
Git基本命令
项目初始化
-
mkdir demo
-
cd demo
-
git init
参数:
- --initial-branch 初始化的分支
- --bare 创建一个裸仓库(纯Git目录,没有工作目录)
- --template 可以通过模板来创建预先构建好的自定义git目录
配置
-
git configGit 配置,分成本地,用户,系统基本的配置不同级别的Git配置:
-
--globalgit config --global user.name "yumo"配置用户名git config --global user.email "1304960237@qq.com"配置用户邮箱git config --global alias.cin "commit --amend --no-edit"配置命令别名
-
--system在 /etc/gitconfig -
--local在本地仓库的 .git/config
-
-
gir remoteGit Remote 配置,分成 SSH 和 HTTP 两种协议实现,不同协议有不同的免密配置方式查看remote
- git remote -v
添加remote
git remote add origin_ssh git@github.com:git/git.gitgit remote add origin_http https://github.com/git/git.git
为同一个origin设置不同的push和fetch的url
git remote add origin git@github.com:git/git.gitgit remote set-url --add --push origin git@github.com:my_repo/git.git
SSH Remote
-
URL :
git@github.com:git/git.git -
免密配置 : SSH可以通过公私钥的机制,将生成公钥存放在服务端,从而实现免密访问。
- 目前的Key的类型有四种:dsa、rsa、ecdsa、ed25519
- 默认使用的是rsa,由于一些安全问题,现在不推荐使用dsa和rsa,优先推荐使用ed25519
- 新版本的windows代码可能会禁用dsa、rsa,从而导致本地无法拉取远程代码
- 生成公私钥:
ssh-keygen -t ed25519 -C "1304960237@qq.com"密钥默认存在~/.ssh/id_ed25519.pub
提交代码
-
git add将代码从工作区提交到暂存区git cat-file -p ce013625030ba8dba906f756967f9e9ca394464a查看加密后的文件内容
-
git commit将暂存区代码提交到 Git 存储Objects : commit / tree / blob 在 git 里面统一称为 Objects ,除此之外还有个 tag 的 object
-
Commit : 存储提交信息,一个 Commit 可以对应唯一版本的代码
-
Tree : 存储文件的目录信息
-
Blob : 存储文件的内容
串联三个信息:
- 通过 Commit 寻找到 Tree 信息,每个 Commit 都会存储对应的 Tree ID
- 通过 Tree 存储的信息,获取到对应的目录树信息
- 从 tree 中获得 blob 的 ID,通过 Blob ID 获取对应的文件内容
Refs
-
Refs 文件存储的内容:refs 的内容就是对应的 Commit ID,因此把 ref 当做指针,指向对应的 Commit 来表示当然 Ref 对应的版本
-
不同种类的 ref :reds/heads 前缀表示的是分支,除此之外还有其他种类的 ref ,比如 refs/tags 前缀表示的是标签
Branch
git checkout -b <分支名>创建一个新分支- 分支一般用于开发阶段,是可以不断添加 Commit 进行迭代的
Tag
git tag <标签名>生成一个tag- 标签一般表示的是一个稳定版本,指向的 Commit 一般不会变更
git tag -a <标签名> -m <附注信息>添加一个附注标签
- 附注标签:一种特殊的 Tag ,可以给 Tag 提供一些额外的信息
追溯历史版本
git log
修改历史版本
-
commit --amend
git commit --amend通过这个命令可以修改最近的一次 commit 信息,修改之后 commit id 会变
-
rebase
-
通过
git rebase -i HEAD~3可以实现最近三个的修改- 合并 commit
- 修改具体的 commit message
- 删除某个 commit
-
-
filter --branch
- 该命令可以指定删除所有提交中的某个文件或者全局修改邮箱地址等操作
-
悬空Object:修改Commit后发现新增了一个object,但是以前的没有被删除。这个以前的没有ref指向的object称为悬空object
git fsck --lost-found检查悬空Commit
-
垃圾回收
-
GC:通过 git gc 命令,可以删除一些不需要的 object ,以及会对 object 进行一些打包压缩来减少仓库的体积
-
Reflog:用于记录操作日志,防止误删除后数据丢失,通过 reflog 来找到丢失的数据,手动将日志设置为过期
-
指定时间:
git gc prune=now指定的时修建多少之前的对象,默认是两周前 -
完整流程:
git reflog expire --expire=now --allgit gc prune=now
远端同步
-
拉取代码
git clone拉取完整的仓库到本地目录,可以指定分支、深度git pull拉取远端某分支,并和本地代码进行合并,操作等同于git fetch+git merge,也可以通过git pull --rebase完成git fetch+git rebase以解决冲突git fetch将远端某些分支最新代码拉取到本地,不会执行merge操作,会修改refs/remote内的分支信息,若需要和本地代码合并则需要手动操作
-
推送代码
-
git push将本地代码同步至远端 -
冲突问题:
- 如果本地的commit记录和远端的commit 历史不一致,则会产生冲突,比如
git commit--amendorgit rebase都有可能导致这个问题。 - 如果该分支就自己一个人使用,或者团队内确认过可以修改历史则可以通过
git push origin master -f来完成强制推送,一般不推荐主干分支进行该操作,正常都应该解决冲突后再进行推送。
- 如果本地的commit记录和远端的commit 历史不一致,则会产生冲突,比如
-
推送规则限制:可以通过保护分支,来配置一些保护规则,防止误操作,或者一些不合规的操作出现,导致代码丢失。
-
常见问题
配置了Git配置,但依然无法拉取代码
- 免密认证没有配
- Instead Of 配置没有配,配的 SSH 免密配置,但是使用的还是 HTTP 协议访问
Fetch了远端分支,但是本地的分支历史没有变化
- Fetch 会把代码拉取到本地的远端分支,但是并不会合并到当前分支,所以当前分支历史没有变化。
研发流程
分支管理工作流-Github Flow
Github 的工作流,只有一个主干分支,基于 Pull Request往主干分支中提交代码。
选择团队合作的方式:
- owner创建好仓库后,其他用户通过Fork 的方式来创建自己的仓库,并在 fork 的仓库上进行开发
- owner创建好仓库后,统一给团队内成员分配权限,直接在同一个仓库内进行开发
代码合并
git merge <分支名> --ff-onlyFastForward 不会产生一个merge节点,合并和保持一个线性历史,如果 target 分支有了更新,则需要通过 rebase 操作更新 source branch 后才可以合入git merge <分支名> --no-ffThree-Way Merge 三分合并,会产生一个新的merge节点
如何选择合适的工作流
没有最好,只有最合适,针对小团队合作,推荐使用 Github 工作流即可:
- 尽量保证少量多次,最好不要一次性提交上千行代码
- 提交Pull Request 后最少需要保证有CR(Code Review)后再合入
- 主干分支尽量保持整洁,使用fast-forward 合入方式,合入前进行rebase
更多优质文章可以查看我的掘金主页,或者个人博客 www.yumoyumo.top