2021-02-21

说明:这是为了面试上传的,是我学习git自己用markdown语法做的笔记,一键粘贴上来的,所以图片不想上传了

git由来

早期为了管理linux系统的代码所开发出来

svn和git对比

svn: 集中管理,服务器单点故障,容错性差

git:分布式版本控制系统,没有中央服务器

  • 开发人员有本地仓库,增删改查。只有一名开发人员,只需本地仓库即可

  • 需要交换代码就需要远程仓库,复制本地仓库到远程共享版本库,其他人员再去clone代码到他的本地仓库

[图片上传失败...(image-9a9a8e-1613918902791)]

  • pull拉取别人更新的代码

基本工作流程(git bash下)

创建本地仓库

  1. 创建本地工作文件夹(工作区) mkdir workfile

  2. 再工作文件夹下创建本地仓库 git init

本地工作闭环

  1. 进入本地仓库,添加一个文件 touch hello.txt并添加一些内容 vim hello.txt

  2. 将刚创建的文件添加到暂存区 git add hello.txt(stage区域)

  3. git commit files将暂存区提交到本地仓库

  4. 本地仓库有一个默认分支master

  5. push将本地库的内容推送到远程库

本地库和远程库交互

作用

  1. 用途团队内部协作

  2. 跨团队协作

流程(团队内部协作)

  1. 项目发起人创建本地项目,本地库

  2. 在代码托管中心创建远程库

  3. 将本地库的内容push到远程库

  4. 其他程序员clone(下载并初始化本地库)远程库的内容到他的本地库,他作修改提交到本地库再push到远程仓库。在此之前不能进行推送,因为远程库为项目发起人创建的。要项目发起人将其拉入团队才可以

  5. 其他程序员修改后推送的内容,项目发起人再执行一个pull(拉取)的操作将修改后的内容放入本地库

    [图片上传失败...(image-d1aeaa-1613918902788)]

跨团队协作

  1. 其他公司的人fork一下项目发起人的库,自己可以进行任意操作及修改,push,pull,clone,最终提交到远程仓库是提交到fork之后的仓库

  2. 确定修改完毕之后发起pullrequest,等待项目拥有者审核之后再合并初始项目种(merge)

  3. 之后自己再拉取pull到本地仓库进行代码修改等操作

    [图片上传失败...(image-4db0c2-1613918902788)]

概念解释

  • 工作区:即工作目录,包含.git文件夹的目录,写代码开发的地方

  • 暂存区:打算要提交的东西,但没提交。临时存储可提交也可撤回

  • 本地库:存储历史版本

1.本地库初始化

git init效果

[图片上传失败...(image-aee9c3-1613918902791)]

  1. 设置签名:区分不同开发人员的身份

    用户名:

    email:

    辨析:这里设置的签名和登录远程库(代码托管中心)的账号和密码没有任何关系

    • 项目级别/仓库级别:仅在当前项目有效

      • git config user.name username

      • git config user.email useremail

      • 签名在当前项目的.git/config文件里

    • 系统用户级别:登录当前操作系统的用户范围

      • git config --global user.name 同上

      • git config --global user.email 同上

      • 签名在家目录下(cd ~)的.gitconfig文件里

        [图片上传失败...(image-eeffe1-1613918902784)]

    • 都有的话采用项目级别的签名就近原则,项目级别的优先于系统用户级别

    • 二者都没有则不允许

  2. 查看签名(保存在config文件里):cat .git/config

    [图片上传失败...(image-a9ed28-1613918902788)]

2.添加提交以及查看状态

  • 查看工作区状态:git status

  • git add可以追踪(track)文件:即用git管理这个文件

  • 用vim good.txt创建一个文件,再用git status查看发现此文件没有被追踪有丢失风险,没有在缓存区(warning: LF will be replaced by CRLF in good.txt.)换行符会被替换

  • git add good.txt之后再查看git status

  • 后悔放入了缓存区可使用 git rm --cached good.txt将此文件移出缓存区(未正真删除磁盘中的文件),此文件又编程未追踪文件

  • 将缓存区的文件提交到本地库:git commit good.txt。之后需要添加一些修改日志(改了些什么,有什么功能改善,本次要干什么事)就是vim编辑器里。使用 :set nu可以查看行号。修改后保存退出:wq

  • 第一次提交作为根提交,后面的数字可看作本次提交的版本好。后面的的本次提交的信息日志3 insertion(+)添加了几行再查看一下状态git status。 working tree clean工作区是干净的

  • 将good.txt去修改一下(前面为新建)添加一行。查看下状态变成modified状态,检测到修改了但此次修改没有存到暂存区。有两种提示。

    [图片上传失败...(image-721834-1613918902788)]

    • 第一个方式,更新

    • 第二个方式,在工作目录取消修改

  • 最后一行是添加到缓存区(git add good.txt)或者直接提交git commit -a good.txt

  • 使用git add添加到缓存区后查看状态可发现将其变成未暂存状态(git restore --staged ..." to unstage)

  • 最后再提交一下(可带参数 -m 直接输入本次的信息无需使用vim编辑器):git commit -m "message" good.txt

3.版本穿梭(前进后退)

  • 准备工作

    • 查看历史记录git log

      [图片上传失败...(image-eb3d88-1613918902785)]

    • commit后面的值为哈希值用于索引,head->master指针,head指向当前版本,对版本作前进后退就是移动这个head指针。author:作者,date:时间。最后一行提交的信息

    • 多添加一些commit多一些历史版本

    • 日志过多之后太多了,不好查看,可用git log --pretty=oneline查看或者git log --oneline或者git reflog(常用,显示移动到版本需要移动步数)

  • 开始版本回溯

    • 查看历史记录

      • git log --pretty=oneline

        [图片上传失败...(image-7ed4f2-1613918902784)]

      • git long --oneline

        [图片上传失败...(image-d99347-1613918902784)]

      • git reflog

        [图片上传失败...(image-e37f6d-1613918902784)]

    • git管理我们的历史版本用head指针指向当前版本,移动head指针实现版本切换

  • 基于索引值前进后退版本

    • git reset --hard [index]即黄色的数字(哈希值)。可前进后退

    • 再查看文件

  • 使用^符号:只能后退

    • git reset --hard HEAD^ 往后退一步

    • git reset --hard HEAD^^ 往后退两步

    • 之后同理,退几步加几个^

  • 使用~符号:解决前面后退数过多尴尬的境地(也只能后退)

    • git reset --hard HEAD~3 后退三步。

hard soft mixed三种回退方式对比

  • hard

    • 重置暂存区和工作区,本地库移动HEAD指针

    • 三个区一起动

      [图片上传失败...(image-cb7fb4-1613918902785)]

  • soft

    • 不会去碰暂存区和工作区,本地库移动HEAD指针

    • 只移动了本地库,暂存区和工作区没动

      [图片上传失败...(image-f128e-1613918902785)]

  • mixed

    • 重新设置暂存区,本地库移动HEAD指针

    • 本地库和暂存区也往后移动,与工作区不同步了

      [图片上传失败...(image-f68722-1613918902785)]

找回删除的文件(只要提交到本地库就不会磨灭了,那条记录就一直都存在,作修改只会增加版本)

  • 准备工作

    • 创建一个文件并commit到工作区

    • rm aaa.txt删除刚才提交到工作区的新文件,查看文件状态

      [图片上传失败...(image-da47b0-1613918902785)]

    • 将此操作删除的文件提交到暂存区git add aaa.txt,并查看状态,将要被提交

      [图片上传失败...(image-16867c-1613918902785)]

    • 提交此被删除文件 git commit -m "delete aaa.txt" aaa.txt

    • 只要恢复到上个文件没被删除的版本,文件即可找回 git reset --hard [index]

添加到暂存区的删除文件找回

  • 准备

    • 创建一个文件 vim apple.txt

    • 添加到暂存区,并提交到本地库git add apple.txt git commit -m "new apple.txt" apple.txt

    • 在磁盘上删除该文件并添加操作到暂存区但不commit提交到本地库rm apple.txt git add apple.txt

    • 这时候如何取回暂存区被删除的文件呢?git reset --hard HEAD(也就是移动指针,刷新三个区,此时HEAD指向的还是原来的版本,所以刷新一下文件就找回来了)

小结

  • 前提:删除前 文件存在时的状态提交到了本地库

  • 操作:git reset --hard [指针位置]

    • 删除操作已经提交到本地库:指针位置指向历史记录

    • 删除操作尚未提交到本地库:指针位置使用HEAD,即当前的状态

文件比较及合并

  • 修改其中一个文件的内容(vim apple.txt)无续提交就可使用 diff命令即可比较内容的不同git diff apple.txt

    [图片上传失败...(image-f6ea60-1613918902786)]

  • 将文件添加至暂存区再进行比较,则会发现没有什么区别

  • 若用指针指向本地库的某一个历史记录则又能看到差异了 git diff HEAD apple.txt

  • 也可以指向其他版本如:git diff HEAD^ apple.txt

小结

  • git diff [文件名]

    • 将工作区中的文件和暂存区对应的文件进行比较
  • git diff [本地库中历史版本] [文件名]

    • 将工作区中的文件和本地库历史记录比较(对应的文件)
  • 不带文件名则比较多个文件:git diff 或者与某一历史版本比较 git diff HEAD

分支

什么是分支?

  • 在版本控制过程中,使用多条线同时推进多个任务,不想对原程序作修改

    [图片上传失败...(image-7a8e54-1613918902786)]

  • master:主分支

  • feature_name,开发某一功能用的名字

  • hot_ifx:热修复,当线上程序出现bug,不停服务器,创建一个hot_分支去修复,修复完成后再合并到主分支完成bug修复

分支好处

  • 同时并行推进多个功能开发,提交开发效率

  • 各个分支在开发过程中,如果某一个分支开发失败,不会对其他分支有任何影响。失败的分支删除重新开始即可

分支操作

  • 查看状态git status可以看到正在主分支上,on branch master,初始化一个git项目后就有master分支

  • 查看现在所有的分支:git branch -v

  • 创建一个分支(在某个项目下的分支下去创建分支):git branch hot_fix

  • 切换分支:git checkout branch_name

实验:

  • 修改hot_fix分支下的某个文件并提交到本地库

  • 未修改文件之前,版本一致

    [图片上传失败...(image-4084c8-1613918902786)]

  • 修改后。分支的版本前进了一步,master分支未动

    [图片上传失败...(image-8accae-1613918902786)]

  • 假设在分支上已修复bug,要合并到master上。

  • 分支合并

    • 第一步:切换(git checkout [分支名])到接受修改的分支上(master),hot_fix修改的内容要合并到master上,则切换到master分支上

    • 第二部:执行merge命令:git merge [branch_name]:例:git merge hot_fix

  • 撒地方

分支合并产生冲突如何解决

  • 原因:两个分支同时推进,修改了同一个文件的同一个位置,不同的内容,git不能够决定产生冲突,由我们决定

  • git merge [branch_name] 表现形式:有冲突会使后面的地方变成merging,有冲突的文件里会有git生成的特殊字符

    [图片上传失败...(image-91505c-1613918902786)]

    [图片上传失败...(image-a0ce13-1613918902786)]

  • HEAD至= 之前是当前分支的内容,=至master的内容是另一分支的内容(master为另一分支的名称)

  • 如何解决:

    • 编辑到自己满意的程度,删除特殊符号即可

      [图片上传失败...(image-23d870-1613918902785)]

    • 使用add提交到暂存库标记为已解决冲突git add good.txt。再查看状态 status变成冲突已解决的状态了

      [图片上传失败...(image-f906f5-1613918902785)]

    • 提示用commit完成合并,以往用commit带文件名,此次结束合并用commit不能带文件名,日志还是得带

    • 用命令git commit -m "resolve conflict"完成分支合并,此时查看状态,合并已完成,后面的merging标记消失(冲突标记)

      [图片上传失败...(image-4527ef-1613918902785)]

  • 冲突解决:

    • 第一步:编辑文件,删除特殊符号

    • 第二步:把文件修改到满意的程度,保存退出

    • 三:git add [file_name]

    • 四:git commit -m "log"

      • 注意:此时commit一定不能带具体文件名,因为此时这命令代表的时结束合并

git版本数据管理机制

集中式版本控制系统

  • 每个版本做的修改都保存起来,保存增量数据,节约服务器存储空间

  • 恢复起来时,将每个版本的修改的地方拼到一起来恢复

git管理工具

每个版本保存快照,有重复的数据,如果文件没有修改则,git不再重新存储该文件,只保留一个链接指向之前存储的文件

[图片上传失败...(image-1013fb-1613918902790)]

[图片上传失败...(image-ef3258-1613918902790)]

  • git分支管理的本质是创建和移动指针

[图片上传失败...(image-ef2261-1613918902790)]

  • root commit 根,即第一次提交(commit)。再提交就会以根节点为父节点。

  • 初始化本地库就会创建master分支,HEAD指针指向master分支。

  • 创建一个分支。SVN:文件目录都复制一套。GIT:新建一个指针(testing),指向某一个版本

  • 切换分支的本质:将HEAD指针指向testing

    [图片上传失败...(image-ba9adf-1613918902786)]

  • 切换分支后再提交只会影响testing指针,前进一个版本

    [图片上传失败...(image-a69eca-1613918902786)]

  • 切换回master只会将HEAD指针指向master

    [图片上传失败...(image-e4d6fc-1613918902786)]

  • 此时master再提交一个文件,testing和master指向了两个不同的版本,都以同一个父节点

    [图片上传失败...(image-f6eed-1613918902786)]

远程交互测试

本地准备工作

  1. 本地初始一个库 mkdir huashan; git init

  2. 新建一个txt文件添加一些内容,并提交到本地库

远程准备

  1. 登录github创建相应的远程仓库。最好与本地库名字相同(可不同)方便自己识别

  2. 一般不创建readme.md,本地可能也有,避免冲突

本地创建远程库的别名

  1. 首先得知远程库的地址,去github获取(https://github.com/pharoskgg/huashan.git)

  2. 每次推送带这么长的地址不方便,git提供了一个命令使其保存在本地

  3. git remote -v:查看远程仓库的别名

  4. git remote add origin(后面地址的别名) https://github.com/pharoskgg/huashan.git。将此地址保存在本地

推送

  1. git push origin(远程仓库的别名) master(需要推送的分支)

  2. 然后会跳出登录框需要登录github,两次输入账户密码

    [图片上传失败...(image-34d50-1613918902786)]

  3. 从本地的master->远程的master:对于远程库来说它没有分支,所以是一个new branch【新分支】

克隆

  1. 完整的把远程库下载到本地

  2. 创建origin远程别名

  3. 初始化本地库

其他团队成员要推送到远程库

  1. 需要邀请其他成员(github账号)加入到此项目当中

  2. 被邀请的人接受邀请

  3. 最后才可以推送

拉去其他人修改后的远程库

pull = fetch + merge

远程协同开发团队冲突

  • A修改文件并推送了,B刚好改的同一个文件的同一个地方,此时B不能进行推送,github认为你还不知道文件已经更新,会提示你pull到本地合并好本地文件(进入merging模式)。同前面冲突解决的方法一样。然后才可以推送到远程

  • 总结

    • 如果不是基于github远程库的最新版本所作的修改,不能推送,必须先拉去。

    • 拉去下来如果进入冲突状态,则按照”分支冲突解决"操作即可

SSH免密登录

注意

  1. 不用每次登录的原因是win10有凭证管理系统。记住账号密码了!(https协议通信)

  2. 使用ssh地址则可避免每次输账号密码

开始

  1. cd ~(进入git 的家目录)

  2. 删除以前创建的.ssh目录 rm-r .ssh/

  3. 重新生成一下:ssh-keygen -t rsa -C emai([email protected] ) 直接一路回车默认即可

  4. 进入该生成的目录cd .ssh/ 复制 id_rsa.pub里所有的内容

  5. 将复制的内容粘贴至github上的 ssh keys

  6. 新建远程地址的别名(使用ssh地址) git remote add origin_ssh [ssh地址]

  7. 再进行推送即可git push orgin_ssh(远程仓库的别名) master(需要推送本地的分支的名字)

将远程主机 origin 的 master 分支拉取过来,与本地的 brantest 分支合并。

 git pull origin master:brantest

你可能感兴趣的:(2021-02-21)