B站_尚硅谷教程 Git与GItHub部分为该视频的个人笔记
Learn Documents
apt install git
1.1 版本控制与Git简介
Linus于2005年开发,用于Linux的版本管理,完全支持Linux命令行
是一种分布式管理控制工具 主要用于维护本地库,对本地库进行版本控制 同时可推送到远程库(在代码托管中心创建,如GitHub等)
1.1.1 Git工作流程
基本结构:Workspace——>Index Stage——>Repository
Linux文件系统:Working Tree/Directory——Index File——?
工作流程: 工作区—add—>暂存区—commit—>本地库
本地库—push—>远程库—clone—>本地库
远程库—pull(fetch + merge)—>本地库
1.1.2 本地库与远程库交互
1.1.2.1 团队内协同开发
- clone 下载远程库
- push 推送修改到远程库(需要被邀请加入团队)
- pull 拉取到本地库(本地工作区)
1.1.2.2 跨团队协作
- fork 创建分支(即以自己为管理员创建一个新的内容相同的远程库,此时可以直接push修改内容到这个新的远程库)
- pull request 新远程库发起一个拉取请求(需要被原远程库管理员审核)
- pull (fetch + merge) (原管理员合并修改到原远程库并拉取至本地库)
1.2 Git命令行操作
1.2.1 本地库操作
Git命令一般都是 git <command> --<该命令的不同参数> 形式
1.2.1.1 本地库初始化
mkdir <Project name>
cd <Project name>
git init //此时会提示在当前路径下初始化了一个Git repository(创建了一个.git目录)
ls -lA //同时显示隐藏文件
ll .git/ //.git目录中存放的是本地库相关的子目录和文件,请勿删除或随意修改
签名设置(包含用户名和用户邮箱),用于区分开发人员的身份 这里设置的签名与登录代码管理中心(远程库)的账户无关
//操作时不允许没有签名
cd <Project name>
// 1. 项目级别/仓库级别签名:仅在当前本地库范围内有效
git config user.name XXL
git config user.email ********@***.**
// 2. 系统用户级别签名:登录当前操作系统的用户范围内有效
git config --global user.name XXL
git config --global user.email ********@***.**
//就近原则,二者都有时采用项目级别签名,优先级更高
/***************************************************/
cat ./.git/congif // 查看项目级别签名信息
cd ~
pwd //当前目录,可查看系统用户名
cat ~/.gitconfig //查看系统级别签名信息
//在本地开发一般只设置一个系统的就够了
1.2.1.2 基本操作
- 状态查看、添加与提交
git status //查看工作区、暂存区状态
vim hello.txt //工作区(在项目目录下)创建文件并编辑内容
git add <file> //添加到暂存区,并将新文件变为已追踪(track)的状态
/*******
LF CRLF 行末换行符转换方式
*******/
git rm --cached <file> //从暂存区移除(对工作区无影响)
git commit <file> //提交到本地库
:set nu //git自动调用了vim编辑器,要求对本次commit作注释(Messages)
:wq //添加完注释后退出,会显示本次commit的版本号
git status //再次查看状态,可以看到第一次提交的为(Root commit)
vim hello.txt //再次编辑
git status
git checkout -- <file> //discard changes in working directory
git commit -a //将修改后已追踪的文件直接提交,无需重新git add,但是会导致无法从暂存区撤销,影响历史版本记录
git reset HEAD <file> //修改后已追踪的文件添加至暂存区后,通过该指令 to unstage
git commit -m "Messages About this modify)" <file> //不进入VIM直接添加本次commit的注释
- 版本管理
git log //显示各版本的签名、版号哈希值(详见git原理部分)、提交时间、提交注释,以及HEAD指针(移动该指针以选定版本)
//空格向下翻页,b向上翻页,q退出
//这也是版本注释必要的原因,用于在回退或前进版本时进行清晰直观的管理
git log --pretty=oneline //单行简洁显示
git log --oneline //不完整哈希值显示
git reflog //(推荐使用)不完整显示,同时输出指针需移动步数:HEAD@{steps}
//---------------------------版本选择------------------------------
git reset --hard <hash> //版本选择(前进/回退):基于索引值方式(可以是上述的不完整哈希值)
git reset --hard HEAD^ //只能回退版本:使用异或符号“^”,有几个^回退几个版本
git reset --hard HEAD~<num> //只能回退版本:使用波浪符号“~”,后面的num表示回退几个版本(HEAD~3表示回退3个版本)
/**************
reset的不同参数
1. --soft:仅在本地库移动指针(此时暂存区处于未提交状态,即此时 暂存区和工作区 与 本地库 版本不同,且 本地文件内容 即工作区不改变)
2. --mixed:在本地库移动指针并并重置暂存区(此时工作区处于未添加状态,即此时 工作区 与 暂存区和本地库 版本不同,且 本地文件内容 即工作区不改变)
3. --hard:在本地库移动指针并重置暂存区和工作区(更改本地库、暂存区和工作区内容至相应版本)
***************/
//---------------------------删除恢复------------------------------
vim ***.c
git add <file>
git commit -m "new file" <file>
git status //此时有一个包含此文件的本地库版本
rm <file> //删除工作区中该文件
git status
git add/rm <file> //添加删除操作到暂存区
git status
git commit -m "delete file" <file> //提交删除操作
git status //此时该版本本地库已不包含该文件
/***************
在不删除本地库和本地库日志的情况下,即可通过版本回退、选择,找回本地库中被删除的文件
***************/
/************
添加到暂存区但是没有提交的删除操作,如何找回被删除文件
*************/
vim <file>
git add <file>
git commit -m "new file" <file> //此时HEAD指针指向当前含有该文件的版本
rm <file>
git add <file> //此时添加了该文件的删除操作至暂存区,但是未提交至本地库,即未产生新版本
git status
git reset --hard <hash> //通过重置暂存区至当前版本找回暂存区中添加了删除操作的文件
git reset HEAD //也可以刷新暂存区和操作区至当前版本
/******************
找回文件的前提:
删除前,文件存在时的状态提交到了本地库
此时可以通过 git reset --head [指针位置]
指针位置:历史记录(已提交)或当前位置(已添加未提交)
******************/
//比较文件差异
git diff <file> //将工作区和暂存区中对应的文件进行比较
git diff [本地库历史版本(如HEAD、HEAD^)] <file> //将工作区和本地库历史记录比较
git diff HEAD //不指定文件名时,会列出所有增删
1.2.1.3 分支管理
什么是分支(Branch): 在版本控制过程中,使用多条线同时推进多个任务 产生的结果和fork类似,都是复制一样的文件,只不过分支的管理员仍是原本地库管理员
分支的好处:
- 在合并前均相互独立,并行处理
- 在实现开发功能前,不會对Master分支即主干造成污染
- 当某个分支项目被砍或出现錯誤之后,可以直接删除该分支
- 提高整体开发效率和迭代速度
当合并上线后发现bug,此时一般会开辟一个临时的hot_fix分支用于热修复线上项目,在修复问题后合并至Master
分支具体操作:
git status
git branch -v //查看分支
git branch feature_** //创建名为feature_**的分支
git branch hot_fix //创建名为hot_fix分支
git branch -v
git checkout hot_fix //切换至hot_fix分支
git branch -v
/********************
在该分支进行修改、添加、提交后,此时又一次体现了版本message的重要性
********************/
git branch -v
/**********************
想要合并分支并使修改生效,必须在Master分支下(接受修改的分支为当前所在的分支)
合并分支步骤
1. 切换到接受修改的分支上
git checkout [被合并分支名]
2. 执行merge指令
git merge [分支名]
**********************/
git checkout master
git branch -v
git merge hot_fix //合并指定的hot_fix分支
合并分支时产生冲突(conflict)
/*****************
产生冲突的原因:
当两个分支同时修改并提交了同一个文件的同一个位置(git区分修改是以行为单位),且内容不一致时,合并就会产生冲突
冲突的表现:
冲突后会在该文件的冲突区生成提示和特殊符号,等号分隔的上部分为当前分支内容,下半部分为另一分支内容
此时需要在文件内手动进行修改并删去提示和特殊符号,并重新标记文件冲突状态为已解决
最后在想要合并的分支下merge
*****************/
vim <file> //手动修改
git status
git add <file> //mark resolution,标记
git status
git commit -m "resolve conflict" //conclude merge,在这种状态下不能带文件名操作
git status
1.2.2 远程库操作
//详见GitHub部分
1.3 Git原理
1.3.1 Hash算法简介
明文加密为密文,需要加密算法。哈希算法即为一种加密算法
特点:
- 无论数据量大小,输入同一个哈希算法,得到的加密结果长度固定
- 算法确定且输入确定时,输出结果不变(忽略大小写)
- 算法确定,输入有变化,则输出一定有变化且通常变化很大
- 哈希算法不可逆,密文不可推出明文
Git底层采用的是SHA-1算法 由于哈希算法的特点,被广泛用于验证文件:示意图
Git就是靠这种机制从根本上保证数据的完整性
1.3.2 Git版本数据管理机制
先了解集中式版本控制工具(如SVN)的管理机制: 以文件变更列表的方式存储信息。这类系统将它们保存的信息看作是一组基本文件和每个文件随时间逐步累积的差异。为增量式版本控制,仅保存每个版本相对变更的部分
Git把数据看作是小型文件系统的一组快照。每次提交更新时Git都会对当前的全部文件制作一个快照并保存这个快照的索引。为了高效, 如果文件没有修改,Git不再重新存储该文件,而是只保留一个链接指向之前存储的文件。所以Git 的工作方式可以称之为快照流。
Git快照的递交对象,链表数据结构,包含各个版本之间的父子关系、父节点信息、哈希值等
1.3.3 Git分支管理的本质
分支管理的本质是创建和移动指针 基于版本数据管理机制
注意:HEAD为指向当前分支名的指指针,因此分支间的切换只需将HEAD指向对应的分支名;而分支内部的版本切换则是通过移动分支名指针到对应的链表节点(会带着HEAD),从而实现版本选择
详见视频教程第29集,抽象为指针便于理解
因此,基于Git版本数据管理机制,只有当分支或主干提交了新版本时,才会实质性的产生新的链表节点
Github是Git的一个代码托管中心,Gitee也是一个代码托管中心 回顾前面的知识,代码托管中心可以用于创建远程库
用邮箱注册账号 Get Start
2.1 通过Github实现本地与远程库操作
2.1.1创建本地库并完成基础配置
mkdir -p ~/Git_repo/Hello
cd ~/Git_repo/Hello
git inti
vim hello_git.md //
git add hello_git.md
git commit -m "Hello Git" hello_git.md
2.1.2 登录GitHub创建对应的远程库(不强制同名)
New Repository —— Description(optional) —— public —— README(本地库有就不需要勾选)
cd ~/Git_repo/Hello
git remote -v //查看远程库信息
git remote add origin <https address>
/*******************
远程库https地址:https://github.com/<Owner>/<Repository name>.git
origin为该地址的别名,可以取其他的名字
********************/
git remote -v //此时可以发现出现了两个名为origin的地址(fetch / push)用于取回和推送
//-----------------------------------------------------------
git push origin master //推送本地库至远程库,需要输入账号密码登录,此时对于新的远程库就也创建了一个master分支
//此处出现报错详见下方 Security / Usage 链接
Security / Usage 或参考1. 2. 注意:Token生成后一定要保存好
message会显示在这里
2.2 邀请仓库新成员
git clone <Repository address> //克隆远程库至当前目录(任意)
/**********************
clone功能:
1. 下载完整远程库至本地
2. 创建远程地址别名
3. 初始化本地库
***********************/
/***********************
比如小白克隆了一个大神的开源项目到本地,然后一通操作
此时小白想以自己的GitHub账号push回原远程库地址,发现不行
说明需要原远程库管理员(Owner)邀请小白成为该远程库的贡献者(Contributor)
***********************/
管理员进入仓库下的 Settings —— Collaborators —— Add people 并输入小白的账号名 此时管理员界面会生成一个邀请链接,同时小白会收到含有该链接的邮件,登录小白的GitHub打开链接并接受,即可以小白的账号、账号令牌对原远程库进行push
2.2.1 远程库修改的拉取
pull = fetch + merge
对远程库进行 读 操作都不需要密码,也不需要验证身份 fetch:抓取 merge:合并 pull:拉取 //现在大神想看一下小白改了啥
git fetch origin master //抓取主干至本地
cat hello_git.md //此时会发现本地工作区内容没有变化
git checkout origin/master
cat hello_git.md //此时就能看到新内容并检查
git checkout master
git merge origin/master //合并远程库新内容至本地库
/*********************
大神很满意,让小白再加一些功能,此时小白又一通操作
*********************/
git push //没有指定的情况下,push目标已经被.git文件记录
//这次大神很信任小白,没有检查直接pull
git pull origin master
cat hello_git.md //可以看到修改内容直接被抓取并合并了
2.2.2 协同开发时冲突 对同一文件同一位置(即同一行)进行了修改 均提交到各自本地库,但某一方先推送到远程库时(即另一方没有基于GitHub上远程库的最新版所做修改) 后推送的一方无法推送,需要拉取最新的远程库 此时会进入MERGING状态(冲突待处理) 处理方法参考分支冲突,再次提交至本地库时不能带文件名 最后重新推送至远程库即可 2.3 跨团队协作开发 大神想找外包 外包人员登录自己的账号,找到并 fork 大神的原远程库 会自动在外包人员的代码管理中心创建一个一样的远程库,不过会标注该远程库的原所有者 git clone <Repository address> //这里的仓库地址为外包人员fork的新远程库地址
cd ./<Repo>
vim hello_git.md
git commit -m "waibao" hello_git.md
git push origin master //用外包人员账号,此时推送到了fork的新远程库
然后外包就可以在该新远程库界面点pull request 并点击 New pull request,自行变更后点击 Create pull request,用于编辑向大神发送的合并申请说明 此时大神在自己的远程库就会看到pull request新增了,点击进去查看 可以进行消息对话,让外包继续修改 若双方谈不拢也可以关闭这个pull request(双向) 大神检审核通过后就可以merge了(谨慎操作) merge pull request 时大神需要对本次合并操作添加description 最后confirm merge,远程库的代码就合并起来了 拉取至本地即可开始调试 2.4 SSH免密登录 只能操作一个GitHub账号 cd ~
rm -r .ssh/
ssh-keygen -t rsa -C <email address>
//回车确认,采用默认值
cd .ssh/
cat id_rsa.pub
//复制出现的内容
打开Settings —— SSH and GPG keys —— New SSH key 粘贴刚刚复制的内容进去并确认添加,服务器端配置完成 回到客户端工作区进行测试 vim ssh_test.md
git commit -m "test SSH login" ssh_test.md
git remote -v
git remote add origin_ssh git@github.com:<Owner>/<Repository name>.git
git remote -v //此时发现ssh链接也创建好了
git push origin_ssh master //CONFIRM Yes
只有一个账号时用SSH可以省去每次push都需要登录的操作
Learn CLion CLion配置 Article still building
|