看完这个课程理解了一些东西,但很多东西也没搞清楚:比如rebase 、还有团队协作的方式。这些还需要打一打基础或是一些深入学习,下面是对课程知识点的一些记录:
1. git的最小配置:user.name 和user.email
git config --global user.name 'your_name'
git config --global user.email 'your_email@domain.com'
这里填的email 最好是真实的email ,如果操作中出现问题,git 管控的web 系统可以自动向email 发送邮件。
--local // 只对某个仓库有效
--global // 对当前用户所有仓库有效
--system // 对系统所有登录的用户有效(基本不用)
git config user.name 'your_name' // 缺省等同于local
- 查看
config 的配置,不加范围值默认是全部的值的信息
git config --list --local(需要在仓库目录下执行)
git config --list --global
git config --list --system
当你golbal 的仓库设置好用户之后,在文件内设置local 的用户信息,是local 的优先级高。优先级:local >global >system 。
2. 创建一个本地仓库
- 把已有项目代码纳入
git 仓库
cd 项目文件夹
git init
- 新建的项目直接用
git 管理
cd 某个文件夹
git init 项目名
cd 项目名
4. git 文件重命名
git reset --hard // 暂存区、工作区路径上所有变更都会被清楚掉
git mv old_filename new_filename // 变更文件名
5.命令行查看版本历史commit
git log // 当前分支(branch)历史
git log --all // 所有分支(branch)历史
git log --oneline // 简洁的git 提交记录
git log -n4 --online // -nx最近的x次记录
git checkout -b temp commitid // 基于某个commitid创建一个分支,commitid也可以是一个分支名,因为分支的本质也是一个commitid
git commit -am 'xxx' // 工作区若没有新增的,可以直接使用该命令直接add并commit
git branch -av // 查看所有分支的略缩信息
git log --all --graph // 所有分支历史,且关系树图形化
git log --online --all temp // 查看所有分支(而不是temp分支,--all 后面指定分支,以--all优先 )的所有commit的略缩信息;
git log --online temp // 查看当前分支
git help --web log // 查看log都有什么--参数
6. 视图查看(一般用于查看commit 的关系树)
gitk --all
7. 探秘.git 目录
config :当前 git 的配置文件,可直接在里面修改 user.name 和 user.email description :仓库的描述信息文件HEAD :(指向当前所在的分支),例如当前在 develop 分支,该文件存储的当前的分支文件的地址 refs/heads/develop ,若分支改变内容也会跟着改变hooks [文件夹] :git执行时的钩子文件objects [文件夹] :(存放所有的 git 对象,对象哈希值前 2 位作为文件夹名称,后 38 位作为对象文件名, 可通过 git cat-file -p 命令,拼接文件夹名称+文件名查看)- refs [文件夹]
heads :存放当前项目的所有分支tags :存放的当前项目的所有标签,又叫做里程碑,比如开发到某个版本,可以打上标签标识
- 一些相关的命令:
? cat :用来显示文件。 例如 cat text.md 显示 text.md 文件的内容 ? ls -al :表示列出当前目录下的所有文件(包括隐藏文件) ? git cat-file -t 哈希值 :查看哈希存放的是什么类型?是commitid还是tagid ? git cat-file -p 哈希值 :查看哈希存放的是什么内容 ? git cat-file -s 哈希值 : 查看 git 对象的大小
8. commit、tree、blob 的关系
commit :一个commit 只对应一棵树。tree : 树代表某一个commit 的一个关系视图, 视图里面存放了当前commit 对应的本项目仓库的所有的文件夹以及文件的快照,这个时间点文件夹和文件长什么样。blob :是具体的某一个文件,且文件和文件名无关而与文件内容有关,例如:index1.html 、index2.html 内容相同只会生成一个bolb ,这样设计的好处可以大大节省存储空间。 `
9. 分离头指针
分离头指针:是指HEAD 指针没有指向分支,而是直接指向某个commit 的状态;一般情况下HEAD 指针是指向分支的。
场景: 分离头指针产生commitid 之后,若不关联分支,同事切换回某个分支,该commit 会被丢掉。若关联分支,该commit 才会被保留。
10. HEAD (头指针) 和 branch
- 可以指向分支和
commit ,也可以不跟分支挂钩(分离头状态) branch 的内容记录的也是commit ,所以HEAD 最后落脚的是commit
git checkout -b 基于哪个分支 要创建的分支
git checkout -b 要创建的分支
git diff commit1 commit2 // 比较分支差异
git diff HEAD HEAD^1^ // 比较HEAD和HEAD的爷爷的比较
11.删除不需要的分支(一般不建议删远程仓库的分支)
如果分支没有合并(no-fast-forward )过使用-d 删除会报错提示,此时确定可以删除 可以用-D 删除
git branch -d branchname // 删除合并过的分支
git branch -D branchname // 强制删除
12. 修改最新commit 的message
修改最近一次的commit 的message
git commit --amend
进入vim 编辑页面 --> 点击 i (英文输入法)开始编辑说明文字 --> 按esc 然后输入:wq! 强制保存退出vim
13. 修改老旧的commit 的message
只适用我们未提交到远程仓库的分支
git rebase -i 输入要修改分支的父分支
copy xxxx
// 按i, 然后把copy改成r, esc :wq! 进入修改message
// 按i, 修改message,按esc :wq! 保存并退出
这个操作是git 帮我们做的一个分离头指针操作,修改后commitid 已经变了,但bolb 对象还是那个blob 对象
14. 合并commit (远程仓库不要执行该操作,会影响同事们的操作)
场景:多次提交的commit ,本质上是同一个功能,这时候我们可以对commit 进行合并让commit 更简洁。
// rebase依然是基于父commit操作
git rebase -i xxxx
pick xxxx1
squash xxxx2
squash xxxx3
squash xxxx4
pick xxxx5
// 把2、3、4合并到1里面去
15. 把间隔的commit整理成1个
git rebase -i --root // 如果要操作root commit可以使用该命令
间隔的commit 合并一般会有冲突,此时需要解决冲突,然后使用git rebase --continue ,继续进入合并操作。
16. 暂存区和HEAD 如何比较
git diff --cache
// --cache 表示暂存区
// 暂存区和HEAD比较差异
git diff
// 默认比较工作区和暂存区的差异
git diff -- 具体文件名 具体文件名 具体文件名
// 工作区和暂存区某几个文件的差异
17. 暂存区还原成HEAD 指向的代码
场景:
git reset HEAD
// 把暂存区所有的东西恢复成HEAD
git reset HEAD -- styles/style.css
// 把暂存区某个文件 恢复成HEAD的文件
git checkout -- 某个文件
// 把工作区恢复成暂存区,变更工作区的内容一般用checkout
18. 消除某个分析最近几次的提交
git reset --hard commitId
// 工作区暂存区都回退到这个分支的代码
git reset --hard HEAD^
// 工作区暂存区退回到上个版本
git reset --hard HEAD 退回到HEAD
// 工作区暂存区退回到HEAD
19. 看看不同的commit 的差异
git diff branch1 branch2
// 所有文件, 分支可以换成不同的commit
git diff branch1 branch2 -- index.html
// index.html
20. 正确的删除文件
git rm 文件名
// 删除文件并提交到暂存区
21. 开发时遇到加急任务如何操作
git stash
// 存放
git stash list
git stash pop
// 存放的内容弹出来,删除stash里的该条内容
git stash apply
// 存放的内容弹出来,且不删除该条内容
22. 指定不需要管理的文件
.gitignore 文件
.d :以.d 结尾的文件和文件夹都不被管控.d/ :该文件夹及文件夹下的不被管控,但.d 文件会被管控
23. 将git 远程代码拉取到本地的相关知识
- 常用的4种
git 传输协议
- 本地协议1,例:
/path/to/repo,git (相对路径),哑协议; - 本地协议2,例:
file:///path/to/repo.git (///开头是三个斜杠),智能协议; http/https 协议,智能协议,使用该协议拉取代码需要输入账号密码; ssh ,工作中最常用的智能协议,使用该协议拉取代码需要创建ssh 公私钥,并把公钥配置在远程仓库对应的账号;
哑协议和智能协议的区别:1. 直观区别:哑协议不可见,智能协议可见,比如传输了多少东西,传输进度等;2.智能协议比较快;
- 相关命令:
git clone --bare 协议 仓库名称
// --bare 表示不带工作区的裸仓库
git remote -v
// 显示所有远程仓库
git remote show remote_name
// 显示要查看的远程仓库信息,git中常见的origin就是仓库名称
git remote add zhineng(remote的名称) 协议
// 创建远程仓库,并命名,若自己拉取的仓库代码,远程仓库会自动被命名为origin
git push zhineng
// 推送到zhineng远程仓库
git push --set-upstream zhineng master
// 把名为zhineng的远程仓库设为上游,默认会提交到该仓库
git push --set-upstream <remote> <branch>
// 该命令等同于 git push -u <remote> <branch>
24. 配置公私钥 (ssh 协议)
gitub帮助文档地址
公私钥创建好之后可以在多个服务器上使用
ssh-keygen -t rsa -b 4096 -C 'your_email@163.com'
// 1. 默认生成用于SSH-2的RSA密钥。这里使用的是rsa。
// 2. -C用来注释,可以标识这个密钥,指出密钥的用途或其他有用的信息。在这里输入自己的邮箱或者其他都行。
// 3. 输入完会要求输入密语字符串(passphrase),不填表示没有密语。
// 4. 接着会让输入2次口令(password),空表示没有口令。
// 5. 次回车即可完成当前步骤,此时[c盘>用户>自己的用户名>.ssh]目录下已经生成好了。
id_rsa(文件名) 私钥(留在本地)
id_rsa(文件名) 公钥(放到github)
去profile-> ssh配置ssh(一个账号可以有多个公钥)
25. 个人github 仓库的常用属性
Description ,可以让别人快速搜到你readme ,搜索的时候会到readme 中搜关键字的.gitignore ,可以选不同语言的默认配置licenses ,开源协议 MIT 协议是可以商用的(在github创建的仓库会有这个文件,在本地创建的没有)
27. 什么是fast-forward
fast-forward 到底是什么? 通俗的解释:commit 和commit 之间,子commit 有一个箭头指向父commit ,用这种方式,版本演变的历史就会形成一幅带方向的图,把commit 比做人的话,孙子和爷爷之间,儿子和爸爸之间就是fast-forward 的关系,而堂兄之间就不是fast-forward 的关系了。
官网解释:fast-forward 是merge 的一种特殊类型,你把A 分支合入到B 分支的时候,恰好B 分支指向的commit 是A 分支的祖先,在这种情况下,我们无须额外创建一个merge 的commit ,而只需把B 分支指向A 分支对应的commit 就行。
举个例子,本地分支往远端分支做push ,如果远端分支不是本地分支的祖先,那它俩就不是fast-forward 了。反之,它俩就是fast-forward 的关系。
26. 本地推送到github
fetch 是拉取,push 是推送,pull 拉取的时候会进行一些合并操作 rebase 和 merge 两种不同的合并方式
git remote add xxx
// 新增远端的仓库
git remote remove xxx
// 删除远端的仓库
git push xxx --all
// 将所有的分支push到xxx仓库,push之前要pull,否则远端仓库被其他人变更过远端的分支
git fetch remotename branchname
// 仅仅拉取远端的内容,不会做其他操作
git pull
// 拉取远端的内容,并与本地的内容做一个合并
git merge remotename/master
// remotename/master合并到当前分支,两个分支必须有关联
git merge --allow-unrelated-histories remotename/master
// 合并两个没有关联的分支, 新生成的树是有两个父亲的
27. 多人协作,不同人修改了不同文件如何处理
如果不是我们自己创建的远程仓库名称,克隆下来的远端仓库名称默认都叫origin
场景:一个用户基于xxx 分支创建分支并修改了一个文件并提交到远程,第二个用户拉取代码,基于xxx 分支创建分支,修改了一些内容,此时未提交。
此时第一个用户又修改了一些东西提交到该分支,此时第二个用户开始提交,结果导致失败。
因为此时第二个用户xxx 分支的commitid ,远程xxx 分支的commitid 不一致,属于no-fast-forward 。
如何处理?
- 通过
merge
git fetch
git merge github/xxx分支
// 把远程的xxx分支合并到当前的xxx分支
pull 也可以,pull 会给远端的分支和本地分支自动merge ,我把git pull 理解为fetch + merge 。
28. 多人协作,有人修改了文件名并提交同时有人基于旧文件名修改了内容
git 能感知到同一个文件的修改和重命名,但需要我们到vim确认 :esc:wq!
29. 多人协作,两个人都修改了文件名
会报冲突,且文件都保留到冲突中,需要rm 不需要的文件,add 想保留的文件
30. 禁止向集成(公共)分支执行push -f 操作
-f 即使不是fast-forward 也能push 上去,例如:当本地使用git reset --hard commitid111 回到很早以前的commit 作为HEAD ,此时强制提交会删除掉远程仓库在commitid111 之后的提交
31. 公共分支禁止更改历史
集成分支不要做rebase (变基)行为
32. issue 是什么
github 中的issue 需求:bug 和任务都可以放到issue 管控。
33. github 如何搜索想查找的项目
- 关键字 +
in:readme ,在readme 里面搜关键字,例:git 学习资料in:readme 。 stars:>1000 ,星大于1000 的项目。language:javascript ,项目的语言等。
34. 团队工作流
SETTING 可以设置允许哪些本地代码合并的类型,可以设置通过审核才能进行合并 工作流:
- 主干开发,就直接再
master 上开发,不创建特性分支,并及时对代码进行更新。适用团队都是一些技术比较好的团队。2. git flow (特性分支),包含了很多中版本:github flow是相对简单,但不流程并没那么完善的一种。
|