Git随笔

Git

前言

​ 由于我的记性不大好,代码什么的经常忘。所以我的笔记是经常作为我的查阅手册存在的。但同时我也想在每一次通读我的笔记后,能完整的遍历一次Git的核心内容。

​ 所以我尽量在查阅性和理解性内容中找到一个平衡。尽可能的做到两者兼得233

Git简介

Git是一个版本控制器。版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本。系统会保存你所有版本的历史记录

  • 可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态。
  • 可以多个人协同工作

版本控制器分为集中式与分布式两种

​ 集中式的代表就是SVN,分布式的代表是Git。

集中式

优点:是把代码存放在单一的服务器上,便于项目的管理。

缺点:就是只要整个项目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险

特点:存的只是每个版本之间的差异和索引所以所占空间小。但是相对应的回滚就会变慢

分布式

分布式版本控制的核心概念就是去中心化。它将所有的版本都存放在每一个电脑上。并且可以通过远端仓库Github来跨组进行开发。

特点:git每次存的都是项目的完整快照,需要的硬盘空间会相对大一点。(Git团队对代码做了极致的压缩,最终需要的实际空间比SVN多不了多少)可是Git的回滚速度极快。

优点:

1.断网的情况下也可以进行开发(因为版本控制是在本地进行的)

2.使用Github进行团队协作,哪怕Github挂了,每个客户端保存的也都是完整的项目(包含历史记录的)

极其适合管理大项目

Git的底层概念

Git的两条主线

区域

工作区

暂存区

版本库

对象

Git对象:

key:value 组成的键值对(key是val对应的hash值)键值对在git内部是一个blob类型

不论是文件还是控制台程序最终存储的类型都是blob类型的文件

Git对象的问题:

1.记住文件的每一个版本所对应的SHA-1值并不现实

2.在Git中,文件名并没有被保存–我们仅保存了文件的内容。并且每一个文件都会对应一个blob类型的文件所以Git对象并不适合直接作为版本控制

树对象:

树对象(tree object),他能解决文件名保存的问题,也允许我们将多个文件组织到一起。每一次提交一个新版本就多一个树对象。树对象就像是一次项目的快照。树对象的生成也是一个键值对类型的文件。键值为它的Hash值。类型为Tree

git对象代表文件的一次次版本。tree对象是项目的一次次版本

Tree对象的问题

Tree对象虽然可以代表一个版本的项目快照。但是若是想重用这些快照,你必须记住所有Tree对象的hash值。而且你也完全不知道是谁保存了这些快照,在什么时刻保存的,以及为什么保存这些快照。而以上这些。正是提交对象能为你保存的信息

提交对象:

提交对象就是对树对象 做一个封装。把该版本的信息,上一个版本的hash值,提交人和注释等信息封装进去。

find .git/objects/  -type f  //查看所有的git对象
git cat-files -p  //查看内容 
git cat-files -t  //查看类型 

项目的每一个版本都是一个提交对象,而项目的每一次快照都是一个树对象

Git的本地操作(高层命令)

Git的初始化
查看版本信息
git --version
配置用户名和邮箱

安装成功后。需要配置用户名和邮箱。方便别人review你的代码或者你的代码有BUG时联系你

git config --global(或者--system 或者啥都不写) user.name "你的名字"
git config --global user.email "你的邮箱"

你任何时候都可以通过

git config --list

来查看你的配置信息

注意–global时指当前用户。–system是指该系统下所有的用户。而什么都不写仅代表当前文件。当前项目的优先级最高。如果当前项目没有就往上找

初始化Git仓库
git  init

初始化后,当前目录下会出现一个名为.git的目录,所有Git需要的数据和资料都存放在这个目录中。不过目前,仅仅是按照既有的结构框架初始化好了里边所有的文件和目录。但我们还没有开始跟踪管理项目中的任何一个文件。

工作区中每一个文件都是两种状态,以跟踪或未跟踪

一旦文件提交到暂存区一次。那他就是追踪状态了

Git的提交操作

将文件添加到暂存区(本质是先将文件添加到版本库再放入暂存区)你修改了几个文件就会生成几个Git文件.所以说Git是绝对安全的,哪怕没有提交到版本库只是记录到暂存区,你对文件的所有修改都会记录为Git对象。

当你觉得暂存区里的内容可以构成一个版本的时候。提交Git就会生成一个Tree对象和包裹着Tree对象的提交对象。

所以一次提交至少要包含一个Git对象,一个Tree对象和一个提交对象

Git查看暂存区命令
git ls-files -s 

Git将修改添加到暂存区
git add ./
 

一旦添加底层的代码如下

git hash-object -w 文件名(修改了多少个工作目录中的文件 此命令就要被执行多少次)

Git将暂存区提交到版本库
git commit -m "注释内容"
           -a   //Git会直接将所有已追踪的文件添加到版本库。可跳过暂存区
 

一旦提交底层的代码如下
git write-tree
git commit-tree 哈希码

从版本库中删除文件或修改文件名
git rm (目标文件)

它会删除这个文件然后再将此次修改添加到暂存区,你只需要最后再提交一下就可以了

查看文件状态
git status

已追踪的文件的状态有三种:已提交,已修改,已暂存

查看文件与暂存区中文件的区别
git diff 

查看文件跟暂存区的区别

查看缓存区与版本库中文件的区别
git diff --cached
git diff --stager //1.61版本以上支持

查看哪些更新已经暂存起来了准备好下次提交

查看历史记录
git log 
 	 --oneline  //每个版本只显示一行简略信息
git reflog /
log与reflog的区别

log:只会留下你想看到的记录,也就是你撤回的,回退的记录它是不显示的。

reflog:只要是HEAD有变化,那么git reflog就会记录下来(包括撤销命令,修改提交注释命令)

起别名
git config --global (别名)  (你想配别名的命令不需要加引号)

Git的分支操作

需求

当我们合作开发或者自己想加一个新功能的时候就可以创建分支。来避免万一写错了污染原来代码的情况

本质

Git分支的本质其实就是指向提交对象的动态指针

显示分支列表
git branch   后面不跟参数显示分支列表
         -v  可以查看每一个分支的最后一次提交
创建分支
git branch   (分支名)

时光机
git branch (分支名) (该版本的Hash) 新建一个分支并且使分支指向对应的提交对象
切换分支
git checkout (分支名)
//慎用
-b (分支名) 创建并切换到该分支

切换分支会动三个地方

1.HEAD

2.暂存区

3.工作目录

Checkout移动的是HEAD指针而分支是留在原地的。如果想带着分支一起跑需要用reset

最佳实践每次切换分支前,当前分支一定得是干净的(已提交状态),

否则在切换分支时,如果当前分支上有未暂存

的修改(第一次)或者有未提交的暂存(第一次)分支可以切换成功但是这种操作会把未提交的文件带过来,污染其他分支

删除分支
git branch -d (分支名) //如果该分支没有被合并需要使用  -D   强制删除分支
合并分支

git merge (你想合并掉的分支名)
查看项目分叉历史
git log --oneline --decorate --graph --all

建议起别名

Git临时存储

需求

该功能会将未完成的修改保存到一个栈上,而你可以在任何时候重新应用这些改动。比如你改bug改一半,老板又叫你去改另一个更重要的BUG这个时候你就可以使用这个功能

查看Git的存储
git stash  list 
Git的存储
git stash 

其本质也是做一次提交但是普通日志上不会显示

取出存放的版本
git stash apply  stash@{数字}

如果不指定则默认取栈顶元素

git stash pop 

应用储藏然后立即从栈上扔掉它

git stash drop (名字)

删除所选元素

Git的撤销

需求

对提交不满意想要撤回(好正常的需求)

对提交不满意的情况基本分为以下三种情况

工作区

​ 想撤回自己在工作目录中的修改

暂存区

​ 想撤回自己的暂存

版本库

​ 想撤回自己的提交

​ 1.提交的时候注释写错了QAQ

​ 2.提交后发现需要修改代码

​ 但是Git并没有给予回退版本库的操作。对于第一种情况。可以使用 git commit --amend来重新修改注释。第二种情况就只能重新提交一次,生成一个版本

撤回工作区修改
git checkout --(文件名)
撤回暂存区修改
git reset (分支名)  (文件名)
重新修改版本注释
git commit --amend

–amend的本质是HEAD带着分支回到了上一个版本。等你修改好后生成一个新的版本。而老的版本会变成树主干上的一个不起眼的小小的分叉,没有意外会因为主线的推进再也无人知晓。想想还有点沧桑感有木有被Git的垃圾回收器回收

reset的本质就是移动HEAD的指向

重置版本
git reset --soft (哈希值)  //HEAD~代表回退到上一个版本。只回退Commit的部分
git reset --mixed (哈希值)  //回退工作区和暂存区的部分
git reset --hard (哈希值)  //三个区的东西都回退

–hard标记是rest命令唯一的危险用法,它也是Git会真正地销毁数据的仅有的几个操作之一。

​ 假如你在工作区和暂存区还有文件checkout会把文件带过去。而如果用hard的话这些文件会被直接覆盖

重置单独文件
git reset [--mixed] 哈希值 文件名
checkout和reset的区别

1.checkout只动HEAD --hard动HEAD而且带着分支一起走

2.checkout对工作目录是安全的。 --hard是强制覆盖工作目录

数据恢复

如果硬重置回以前版本后发现重置前的文件还有用处想找回。但是log里面已经不显示重置前的分支了

那就通过reflog找到重置前的Hash码。再硬重置回去

Tag标签

Git可以给历史中的某一个提交打上标签,以示重要。比如我们可以用这个功能来标记发布版本

查看标签
git tag  //查看所有标签
   -l  //带条件查询
   

查看特定标签
git show (标签名)		
创建标签
git tag (标签名)
检出标签
git checkout -b(标签名) 

如果不加-b创建分支的话会导致仓库处于“分离头指针“状态。在此状态下,如果你做了某些更改然后提交他们,标签不会发生变化,但是你的新提交将不属于任何分支。也就是除非访问确切的Hash值。再也无法访问。

所以如果你切回来需要进行更改。这通常需要创建一个新分支

Git的远程操作

首先和github勾搭的话需要一种加密措施,SSH或者HTTPS。这里我使用的是SSH公私钥。

创建一对公私钥
ssh-keygen -t rsa -C [用户名]

将公钥输入到Github中就可以了

测试本地仓库与github的连通性
ssh -T git@github.com	
增加远程地址

首先我们需要本地仓库和Github上的一个仓库发生关系。

git remote add <远端代号> <远端地址>

远端代号: 是指远程链接的代号,一般直接用 origin 作代号,也可以自定义;

远端地址: 默认远程链接的 url;

push操作
git push -u <远端代号> <本地分支名称>

远端代号: 是指远程链接的代号;

分支名称: 是指要提交的分支名字,比如 master;

fetch操作
git fetch <远端代号> <远端分支名>;

fetch是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。

pull操作
git pull <远端代号> <远端分支名>;

pull的本质是git fetch+git merge

clone操作
git clone <远端地址> <新项目目录名>

项目目录名: 是指为克隆的项目在本地新建的目录名称,可以不填,默认是 GitHub 的项目名;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值