zoukankan      html  css  js  c++  java
  • 20200530 尚硅谷 Git

    尚硅谷最新Git教程全套完整版(12h带你深入掌握Git)【笔记】

    背景

    虽然一直在用 Git,但是实际只会一些基础操作,并不理解其中的原理,随着工作的时间越来越长,感觉对 Git 的深入理解越来越有必要。

    视频时间

    版本信息

    视频版本:Git version 2.19.1.windows.1

    笔记版本:Git version 2.26.0.windows.1

    1. Git 操作

    版本控制

    版本控制分为集中式(SVN)和分布式(Git)两种;

    • 集中式(SVN):

      SVN 每次存的都是差异,需要的硬盘空间会相对的小一些,可是回滚的速度会很慢

      • 优点:

        代码存成在单一的服务器上,便于项目的管理

      • 缺点:

        服务器宕机:员工写的代码得不到保障

        服务器炸了:整个项目的历史记录都会丢失

    • 分布式(Git)

      Git 每次存的都是项目的完整块照,需要的硬盘空间会相对大一点

      Git 团队对代码做了极致的压缩,最终需要的实际空间比 SVN 多不了多少,可是 Git 的回滚速度极快

    Git 初始化配置

    在 Windows 中,

    system 级别的配置文件位于 C:Program FilesGitetcgitconfig

    global 级别配置文件位于 ‪C:Users80953.gitconfig

    项目的配置文件位于为 .gitconfig

    ## 查看帮助信息
    git --help
    ## 查看 Git 版本
    git --version
    ## 查看 Git 配置信息
    git config --list
    ## 配置全局用户信息
    git config --global user.name "hwj"
    git config --global user.email "hwj@github.com"
    
    ##	配置别名
    git config --global alias.lol 'log --oneline --decorate --graph --all'
    

    Git 底层概念(底层命令)

    基础的 Linux 命令

    * clear 清除屏幕
    * echo 'hello word '>test.tet 命令台书写内容
    * ll 将当前目录下的子目录展现出来
    * find ./ 将当前目录下的子目录以及文件也展现出来
    * find ./ -type f 只讲文件展现出来
    * rm text.txt 删除文件
    * mv a.txt b.txt 更名字
    * cat a.txt 查看文件内容
    * vim a.txt 编辑内容 
    	i 插入 
    	o 插入新行
    	ese 进入命令模式
    	:wq 保存退出 
    	:set nu 显示行号 
    	:q! 强制退出不保存
    

    项目的 .git 目录

    ## 初始化仓库
    git init
    
    • hooks (钩子函数的一个库 类似于回调函数)
    • info (包含一个全局性的排除文件)
    • logs (日志信息)
    • objects (目录存储所有数据内容)
    • refs (目录存储指向数据(分支)的提交对象的指针)
    • config (文件包含项目特有的配置选项)
    • description (显示对仓库的描述信息)
    • HEAD (文件目前被检出的分支)
    • index (文件保存暂存区的信息)

    git 对象

    Git 的核心部分是一个简单的键值对数据库。你可以向该数据库插入任意类型的内容,它会返回一个键值,通过该键值可以在任意时刻再次检索该内容。

    #	hash-object
    ##	向数据库写入内容,并返回对应键值
    ###	返回的键值,前2位为文件夹名称,后38位为文件名称
    ### -w 指示存储数据对象,不指定则不存储,只返回键值
    ### --stdin 指示从标准输入读取内容,不指定则需要在命令尾部给出存储文件的路径
    $ echo 'test content' | git hash-object -w --stdin
    d670460b4b4aece5915caf5c68d12f560a9fe3e4
    
    ## Git 存储文件
    $ git hash-object -w a.txt
    190a18037c64c43e6b11489df4bf0b9eb6d2c9bf
    
    ## 查看 Git 存储的对象
    $ find .git/objects/ -type f
    .git/objects/19/0a18037c64c43e6b11489df4bf0b9eb6d2c9bf
    .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
    
    #	cat-file
    ##	查看任意对象
    ##	根据键值拉取数据,键值不需要完整,只要前面几位就可以
    ### -p 指示自动判断文件类型,并为我们显示格式友好的内容
    ### -t 查看文件类型
    $ git cat-file -p d670460b4
    test content
    $ git cat-file -t d670460b4
    blob
    

    以上所有操作都是在对本地数据库进行操作,不涉及暂存区

    上述操作存在的问题:

    • 记住文件的每一个版本对应的 SHA-1 值并不现实
    • 在 Git 中,文件名并没有被保存,我们仅保存了文件的内容

    解决方案:树对象

    tree 对象

    树对象,它能解决文件名保存的问题,也允许我们将多个文件组织在一起。Git 以一种类似于 UNIX 文件系统的方式存储内容。所有内容均以树对象和数据对象(Git 对象)的形式存储,其中树对象对应了 UNIX 中的目录项,数据对象(Git 对象)则大致上对应文件内容。

    一个树对象包含了一条或多条记录(每条记录含有一个指向 Git 对象或者子树对象的 SHA-1 指针,以及相应的模式、类型、文件名信息)。

    一个树对象也可以包含另一个树对象。

    #	ls-files
    ##	查看暂存区当前的样子
    $ git ls-files -s
    
    #	update-index
    ##	更新索引
    ##	只是为 Git 对象起一个名字,不生成任何对象,需要指定已生成对象的 hash,否则 write-tree 时会报错;但文件名称不需要与实际文件相同
    ##	相同文件如果已存在缓存区中,更新后再生成对象、更新索引,缓存区中会更新为更新后的文件
    ### 文件模式为100644 表明这是一个普通文件
    ### 文件模式为100755 表明这是一个可执行文件
    ### 文件模式为120000 表明这是一个符号连接
    ### --add 因为此前该文件并没有在暂存区中 首次要加add
    ### --cacheinfo 因为要添加的文件在git数据库中,没有位于当前目录下
    git update-index --add --cacheinfo 100644 915c628f360b2d8c3edbe1ac65cf575b69029b61 test.txt
    
    ##	将文件添加为 Git 对象,并更新索引
    ##	hash-object + update-index
    git update-index --add new.txt
    
    #	write-tree
    ##	暂存区做一个快照生成一个对象放到git数据库中
    ##	对象类型是一个树对象
    ##	树对象里面的内容是暂存区的快照(项目的快照)
    ##	暂存区中文件名字不变 如果改变文件的内容,就会重新生成一个hash
    git write-tree
    
    #	rm
    ##	删除操作
    ###	-f 指示强制删除
    ###	--cached 指示删除的是缓存区中的内容
    $ git rm -f --cached a.txt
    rm 'a.txt'
    
    
    #	read-tree
    ##	将一个树对象读入暂存区
    $ git read-tree --prefix=bak 58e6d12d1bf385222144538d11ef7714c87da3b4
    

    存在的问题:

    • 不知道 hash 值对应的是哪一个版本
    • 不知道这个树对象快照的一些基础信息

    这些,正是 提交对象 能为你保存的基本信息

    commit 对象

    #	git commit-tree
    ##	本质就是给树对象做一层包裹包含项目的基础信息
    ##	commit-tree 创建一个提交对象,为此需要指定一个树对象的hash值,以及该提交的父提交对象
    ###	-p 用来指定父提交对象
    echo "first commit" | git commit-tree 019fb2c522b604cd94929085bbac93d60e2f2063
    
    echo "second commit" | git commit-tree e8d77cd21e29ba9a511f129a8b908afc2151bb3b -p f0d25e23b9a52c992f3eab8e4fb8ed6973f670c1
    
    
    

    commit-tree 不但生成提交对象,而且会将对应的快照(树对象)提交到本地库中

    真正代表一个项目的是一个提交对象(数据和基本信息)这是一个链式的!!

    Git 本地操作(高层命令)

    Git 中的区域

    • 工作区
    • 暂存区
    • 版本库

    工作目录中的文件状态

    • 未跟踪(untracked)
    • 已跟踪
      • 已提交(未修改)(unmodified)
      • 已修改(modified)
      • 已暂存(staged)

    img

    高层命令

    #	add
    ##	将修改添加暂存区
    ##	先到版本库,再到暂存区
    ##	hash-object + update-index
    git add ./
    
    
    #	commit
    ##	提交
    ##	生成一个树对象,一个提交对象
    ##	write-tree + commit-tree
    ### -m 指示描述信息
    ###	-a 跳过 add 过程,将所有暂存一起直接提交,后面不能跟文件或目录;文件必须处于已跟踪状态
    git commit -m "first commit a.txt v1" a.txt
    
    #	status
    ##	检查当前文件状态
    git status
    
    #	restore
    ##	add 的反操作,将文件从暂存区移除
    ##	仅移除暂存区,对象仍然存在,工作目录中的文件仍然存在
    ##	作用等同于 rm --cached
    git restore --staged c.txt
    
    #	diff
    ##	查看已暂存和未暂存的更新
    ###	不加参数,与暂存区中的比较
    ###	--cached 指示与已提交的比较
    ###	--staged 同 --cached
    git diff a.txt
    
    #	rm
    ##	删除文件
    ##	rm + git add
    git rm a.txt
    
    #	mv
    ##	文件改名
    ##	mv + git add
    git mv b.txt bb.txt
    
    #	log
    ##	查看历史记录
    ###	--oneline 指示简化日志显示
    git log --oneline
    ###	查看完整的分支图(没删除前)
    git log --oneline --decorate --graph --all
    
    #	reflog
    ##	查看 HEAD 的操作日志
    ##	比完整分支图更详细的日志信息
    git reflog
    

    Git 分支操作(杀手功能)

    分支的本质是指向提交对象的可变指针。

    HEAD 的本质是一个指针,默认指向 master 分支,切换分支就是让 HEAD 指向不同的分支。每次有新的提交时,HEAD 就会带着当前指向的分支,一起向前移动。

    ##	查看分支列表
    git branch
    ##	查看所有分支最后一个提交
    git branch -v
    
    ##	在当前的提交对象上创建一个分支 test
    git branch test
    ##	在指定提交对象上新建一个分支
    git branch test hashcode
    
    ##	切换分支
    git checkout test
    ##	创建分支并且切换过去
    git checkout -b test
    
    ##	删除分支
    ###	删除已合并分支
    git branch -d test
    ###	强制删除分支,不管是否合并
    git branch -d test
    
    ##	合并分支
    git merge test
    
    ##	查看合并到当前分支的分支
    git branch --merged
    ##	查看没有合并到当前分支的分支
    git branch --no-merged
    

    分支切换会改变你工作目录中的文件

    切换分支的时候一定要提交完的时候再切否则会出现问题

    每次切换分支前当前分支一定要是已提交状态,否则会污染主分支,如果第一次提交了再修改的时候没有提交他就不让切换分支了

    最佳实践:每次切分支时,使用 git status 保证分支是干净的。

    分支合并

    合并分支分为快进合并典型合并

    快进合并不会产生冲突

    Git 存储

    解决的问题:

    不希望因为切换分支过多的创建提交

    Git 存储是栈结构,先进后出

    #	stash
    ##	创建存储
    git stash
    
    ## 将栈顶存储移出,并恢复存储
    git stash pop
    
    ##	查看存储列表
    git stash list
    
    ##	恢复存储,不移除出栈
    ##	不指定则默认为栈顶存储
    git stash apply stash@{1}
    
    ##	将存储在栈中删除
    ##	不指定则默认为栈顶存储
    git stash drop stash@{2}
    

    撤销&重置(后悔药)

    ##	工作区撤销修改
    ##	会修改文件内容
    ##	从已修改状态改变为未跟踪状态
    git restore e.txt
    git checkout -- e.txt
    
    ##	暂存区撤销修改
    ##	缓存区内容被修改,不改变文件内容
    ##	从已暂存状态改变为未跟踪状态
    git restore --staged f.txt
    git reset HEAD f.txt
    
    ##	版本库撤销修改
    ###	修改提交注释
    git commit --amend
    

    重置 reset

    #	reset
    ##	撤销一次提交
    ##	动HEAD(带着分支一起移动);不动暂存区和工作目录;文件内容不变
    ##	文件状态从已提交改为已暂存
    git reset --soft HEAD~
    
    ##	动HEAD;动暂存区;文件内容不变
    ##	文件状态从已提交改为已修改
    git reset [--mixed] HEAD~
    
    ##	动暂存区;动文件内容
    git reset --hard HEAD~
    

    git checkoutgit reset --hard 区别:

    • checkout 制动 HEAD;reset --hard 动 HEAD,而且带着分支一起走
    • checkout 对工作目录是安全的;reset --hard 是强制覆盖工作目录

    git checkout -- filename 只动工作目录,不动 HEAD 和暂存区

    git checkout commitHash filename 动工作目录和暂存区,不动 HEAD

    数据恢复

    ##	1. 通过命令查找要恢复的提交 hash
    git reflog
    git log -g
    
    ##	2. 使用两种方式恢复数据
    ###	2.1. checkout(更常用)
    git checkout 分支名称 hashcode
    ###	2.2. reset
    git reset --hard hashcode
    
    

    Tag 功能

    Git 可以给历史中的某一个提交打上标签,以示重要。

    #	tag
    ##	列出标签
    git tag
    ##	正则匹配
    git tag -l "v1*"
    
    ##	为提交对象打上 tag
    git tag v1.0 [commitHash]
    
    ##	查看特定 tag
    git show v1.0
    
    ##	删除标签
    git tag -d v3
    
    ##	检出 tag
    ##	会导致头部分离,可以找到 tag 指向的提交对象后,检出为分支
    git checkout v1.0
    git checkout -b v1.0c dee383a
    

    Git 特点

    • 直接记录快照,而非差异比较
    • 近乎所有操作都是本地执行
    • 时刻保持数据完整性
    • 多数操作仅添加数据
    • 文件的三种状态
      • 已提交(committed)
      • 已修改(modified)
      • 已暂存(staged)
    • Git 管理项目时,文件流转的三个区域
      • 工作目录
      • 暂存区域
      • 本地仓库

    2. 远程仓库

    #	remote
    ##	添加远程分支
    git remote add tg https://github.com/liuxing5yu/testGit.git
    
    ##	重命名远程分支
    git remote rename old new 
    
    ##	删除远程分支
    git remote rm b1
    
    ##	查看远程分支
    git remote -v
    
    #	push
    ##	将 master 分支推到远程仓库
    git push tg master
    
    #	clone
    ##	克隆远程仓库
    git clone https://github.com/liuxing5yu/testGit.git
    
    #	fetch
    ##	拉取远程仓库更新
    git fetch [tg]
    
    ##	合并远程分支
    git merge tg/master
    
    ##	fetch 后出现新的远程分支时,在本地创建对应的本地分支
    git checkout -b cb tg/cb
    git checkout --track tg/b1
    
    ##	设置本地分支与远程跟踪分支同步
    ##	同步后可以直接执行 git push、git pull
    git branch -u tg/master
    
    ##	查看设置的所有跟踪分支
    git branch -vv
    
    ##	同步后,推送提交到远程仓库
    git push
    ##	同步后,拉取远程更新到本地仓库
    git pull
    
    • 可以在 Windows 的【凭据管理器|Windows 凭据】,删除已有的 GitHub 凭据

    • 在 GitHub 仓库的【Settings|Manage access】中可以邀请合作者

    • fetch 后需要 merge 远程分支;如果 fetch 后出现了新的远程分支,需要先建立本地分支,再合并远程分支

    • 远程协作是存在 本地分支,远程跟踪分支,远程分支

    • 远程跟踪分支 是远程分支状态的引用。它们是你不能移动的本地分支。当你做任何网络通信操作时,它们会自动移动。

    • push 和 clone 时,生成远程跟踪分支

    • 当克隆一个仓库时,它通常会自动创建一个跟踪 origin/mastermaster 分支

    解决远程协作冲突

    1. push 冲突

      先 pull,解决冲突后,再 push

    2. pull 冲突

      1. 先提交到本地,然后 push,会产生 push 冲突,之后解决方法如上
      2. 先 stash ,后 pull,stash pop,解决 pop 后的冲突

    删除远程分支

    ##	删除远程分支
    git push origin --delete b1
    ##	列出仍在远程跟踪但是远程已被删除的无用分支
    git remote prune origin --dry-run
    ##	清除上面命令列出的远程无用分支
    git remote prune origin
    

    pull request 流程

    GitHub 上操作 pull request 流程,提交后,等待被合并后关闭

    .gitignore 文件

    可以在 .gitignore 文件中列出要忽略的文件模式

    .gitignore 参考写法

    .gitignore 的格式规范:

    • 所有空行或者以注释符号开头的行都会被Git忽略。

    • 可以使用标准的glob模式匹配。

      • * 代表匹配任意个字符

      • ? 代表匹配任意一个字符

      • ** 代表匹配多级目录

    • 匹配模式前跟反斜杠 / 代表项目根目录

    • 匹配模式最后跟反斜杠 / 说明要忽略的是目录。

    • 要忽路指定模式以外的文件或目录,可以在模式前加上惊収号 ! 取反。

    SSH

    ##	验证用户时走的不是验证密码的道路而是密匙
    ##	在 C:Users用户名.ssh 下生成公私密匙
    ssh -keygen -t rsa -C "邮箱"
    
    ##	在 GitHub 上添加 SSH keys
    
    ##	测试是否成功
    ssh -T git@github.com
    
    • 在 GitHub 的【Personal settings | SSH and GPG keys】里可以添加 SSH keys

    参考资料

  • 相关阅读:
    步步为营——算法初阶 1.算法概述
    Spring学习【Spring概述】
    Codeforces 490F Treeland Tour 树上的最长上升子序列
    汽车电商竞争白热化,“五大门派”谁能登顶?
    程序猿的出路
    Android Studio Share Project On Github
    hdu 1022 Train Problem I(栈的应用+STL)
    Scala, Groovy, Clojure, Jython, JRuby and Java ----我们的工作语言
    Oracle GoldenGate (ogg) 11.2.1.0.20 是最后一个支持oracle db 10g的 ogg版本号
    javascript异步代码的回调地狱以及JQuery.deferred提供的promise解决方式
  • 原文地址:https://www.cnblogs.com/huangwenjie/p/12994172.html
Copyright © 2011-2022 走看看