git高阶使用心得

简介

Git 是一个免费的开源分布式版本控制系统,用于高效地处理从小型到大型的各种项目。它由 Linus Torvalds 于 2005 年创建,旨在管理 Linux 内核开发。Git 以其速度、数据完整性和分布式工作流的灵活性而闻名,已成为软件开发中最受欢迎的版本控制工具之一。

原理(https://git-scm.com/book/en/v2

其本质是一个基于 Key-Value 的内容寻址文件系统,核心部分是一个简单的键值对数据库(key-value data store)

1 git文件系统的结构如下

image.png

COMMIT_EDITMSG最后一次提交备注信息

FETCH_HEAD 保存了远程仓库中每个分支

ORIG_HEAD当前分支最新的提交

config 文件包含项目特有的配置选项

description 文件仅供 GitWeb 程序使用

hooks 目录包含客户端或服务端的钩子脚本(hook scripts)

info 目录包含一个全局性排除(global exclude)文件

packed-refs 拉取远端的所有分支,标签

refs 目录存储指向数据(分支、远程仓库和标签等)的提交对象的指针

logs引用日志数据

HEAD 文件指向目前被检出的分支

objects 目录存储所有数据内容

index 文件保存暂存区信息。

2 objects 存储方式

在 Git 文件系统中,使用Object 存储所有类型的内容,也称为 Git 对象,不同类型的 Object 共同构成了一整套对象模型。

3 Git 对象模型主要包括以下 4 种对象

● 二进制对象(Blob Object)存储文件内容。

● 树对象(Tree Object)目录类型文件

● 提交对象(Commit Object)

● 标签对象(Tag Object)

在 Git 文件系统中,使用一个 40 位的 SHA-1 值 作为一个文件或目录存储内容时所占用的,一个 Object 文件的唯一标识符,在进行匹配查找时候,其中前 2 位 SHA-1 值作为存储子目录,后 38 位 SHA-1 值作为文件名。
git所有对象均存储在 .git/objects/ 目录下,并采用相同格式进行表示: 类型 + 空格 + 存储内容
可以使用底层命令 git cat-file 来查看仓库的一个 git Object 的存储内容
查看对象的类型 git cat-file -t SHA-1
查看对象的内容长度 git cat-file -s SHA-1
查看对象的内容 git cat-file -p SHA-1
下面分析下提交对象
下图是一个提交对象(Commit Object)

C009E858-4C36-4525-BFD4-06D007F2A55D.png

tree aaaa5e107a54b94dc11d45420a31cbd6c77cb244: 表示提交文件所处的文件目录
parent 7557a68d51cfa50194c8be76e4b59e787a2d26e9: 上一次提交所生成的哈希值
分析下树对象(Tree Object)目录类型文件
image.png

里面包含了下一级的树对象(Tree Object)以及二进制对象(Blob Object)可以进一步通过git cat-file -p SHA-1命令查看内容
如果直接查看二进制对象(Blob Object)可以直接看到文件的具体内容
D8F26324-2FC3-4BA7-A541-36509BF85E5C.png

4 包文件

如果两次提交同一个文件,Git 也会用一个全新的对象来存储新的文件内容,你的磁盘上现在有两个几乎完全相同的对象。
如果 Git 只完整保存其中一个,再保存另一个对象与之前版本的差异内容,岂不更好?
事实上 Git 可以那样做。 Git 最初向磁盘中存储对象时所使用的格式被称为“松散(loose)”对象格式。 但是,Git 会时不时地将多个这些对象打包成一个称为“包文件(packfile)”的二进制文件,以节省空间和提高效率。 当版本库中有太多的松散对象,或者你手动执行 git gc 命令,或者你向远程服务器执行推送时,Git 都会这样做。 要看到打包过程,你可以手动执行 git gc 命令让 Git 对对象进行打包,这样可以大大节约你的磁盘存储
下面是手动进行git gc 命令后的文件夹


D8DBB19E-C558-434F-B6F5-E111FC4DAEE4.png

打包后还保留着的几个文件夹的对象是未被任何提交记录引用的数据对象
剩下的文件会新创建的包文件和一个索引
Git 打包对象时,会查找命名及大小相近的文件,并只保存文件不同版本之间的差异内容。
你可以查看包文件,观察它是如何节省空间的。 git verify-pack 这个底层命令可以让你查看已打包的内容:


image111.png

git使用

Mac上安装git方法:通过Xcode安装 $ xcode-select --install

配置git用户信息(git提交所带的用户信息):

git config user.name ; git config —global user.name

git config email ; git config —global user.email

注意事项:在同一台电脑上更换gitlab的账号时需要把电脑钥匙串里面之前存储的账号密码删除。

1 Git本地操作

工作区:我们平时编辑代码的目录文件夹

暂存区:用于临时存放你的改动(git add .)

提交修改到本地:只提交暂存区的修改: git commit git commit -m “提交信息”

把暂存区的修改回退到工作区: git reset HEAD flie

丢弃工作区的修改: git checkout -- file

回退到上一次的提交: git reset -- hard HEAD^

回退到某一次提交:

● git log 获取某一次的提交commitId

● git reset -- hard commitId

恢复回退的提交: git reflog获得commitId

2分支管理

远程库克隆: git clone 远程库地址

查看远程库的信息: git remote

查看远程库详细信息: git remote -v

创建分支同时切换分支: git checkout -b 分支名或者: git switch -c 分支名

创建分支: git branch 分支名

切换分支: git checkout 分支名或者: git switch 分支名

查看分支: git branch

推送分支: git push origin 分支名字

分支合并: git merge 要合并的分支名字 或者: git merge --no-ff -m “提交信息” 分支名

当前分支变基到目标分支(即 master)上:git rebase master

server分支变基到目标分支(即 master)上:git rebase master server

选中在 client 分支里但不在 server 分支里的修改,将它们在 master 分支上重放作为 client 分支: git rebase --onto master server client

将某一个分支中的一段提交同时应用到其master分支中: git rebase commit1 commit2 --onto master

删除某一个分支的一系列提交: git rebase --onto 分支名~5 分支名~3 分支名(需要未push的提交,否则需要强制push)

交互式变基(交互式变基可以把多个提交合并成一个提交): git rebase -i master (操作未推到服务器的提交)

指定的提交(commit)应用于其他分支: git cherry-pick commitID

指定的多个提交应用于其他分支: git cherry-pick commitID1 commitID2

转移一系列的连续提交: git cherry-pick commitID1..commitID2

删除本地分支: git branch -d 分支名

强行删除分支: git branch -D 分支名

删除远程分支: git push origin --delete 分支名

回滚远程提交:

● 本地代码回滚到某一次提交: git reset --hard commitID

● 加入-f参数,强制提交,远程端将强制跟新到reset版本: git push -f origin 分支名

3 储藏功能

储藏功能 把当前工作现场“储藏”起来: git stash 或者: git stash save “信息”

恢复暂存恢复后,stash内容并不删除: git stash apply

恢复暂存恢复后,stash内容删除: git stash pop

查看暂存列表: git stash list

恢复某一个暂存: git stash apply stash@{0}

4 标签管理

默认标签是打在当前的内置最新提交的commit上的.

查看所有标签: git tag

打新标签: git tag 标签名

打之前提交的标签:

● Git log找到历史提commit id, 然后打上: git tag 标签名 commitId

● 还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字: git tag -a 标签名 -m “标签说明” commitId

看标签的文字说明: git show 标签名

删除标签: git tag -d 标签名

推送某个标签到远程: git push origin 标签名

一次性推送全部尚未推送到远程的本地标签: git push origin --tags

删除远程标签:

● 先删除本地标签

● 然后: git push origin :refs/tags/标签名

Sourcetree使用

1 是否展示暂存区

建议平时使用时候打开暂存区,这样避免一些不想提交的文件,比如一些环境的配置等直接提交上去


image2.png

2 merge操作

把目标分支合并到当前分支

如果你想要合并某一分支的某一提交节点到当前分支,也可以直接使用merge操作,像下图那样。这样某个提交节点之前的所有提交会合并到当前分支


image3.png
image4.png

3 rebase操作(https://git-scm.com/docs/git-rebase

使用场景:

变基基础功能和合并类似,起到分支合并的作用,而且使用变基操作可以保持当前分支提交记录的整洁性,使我们可以更容易查看分支的提交记录。未推送过远端,或者一个人开发一个分支,没有进行合并操作的情况下,的时候可以放心的在你自己的分支上使用rebase操作。
有时候当我们执行commit操作之前忘记pull远端分支会造成。拉取失败,这个时候我们可以勾选上用变基代替合并,可以让代码拉取下来
变基还有一些更加强大,方便与我们的操作,在下面的交互式变基会详细讲解,先说下变基的基本操作


image5.png
image6.png
image9.png

变基实现的过程:git会从两个分支的共同(待变基分支,变基到的分支)的第一个提交节点开始提取待变基(一般是当前分支)分支上的修改,然后将待变基分支指向基分支的最新提交,最后将刚才提取的修改应用到基分支的最新提交的后面


image10.png

rebase后


image11.png

注意事项:尽量在你未推送过远端的时候才进行rebase操作

● 如果多人开发同一个分支的时候如果你已经push过,基分支又有改动,这个时候进行rebase操作的时候后,另外一个人在push代码就会出现错误。
思考总结meger和rebase:
相同点:都可以进行两个分支合并
不同点:
● 合并可以保存整个历史记录,变基可以创建线性历史记录,难以追溯历史,可能会造成提交丢失,
● 使用sourcetree解决冲突时候,使用“我的版本”解决冲突,使用“他人的版本”解决冲突是相反的
● rebase可以让某一段提交合并到分支上,也可以删除某各分支上的某一段提交,等等
meger只能合并某一个提交之前的所有的提交合并到某一个分支上

4 interactive Rebase 操作

使用场景:
● 可以把多次提交合并成一次提交,比如你调试某个功能,或者修复某个bug时候进行了多次提交,这个时候可以把这些提交合并成一次提交,保持功能的完整性。
● 修改历史提交记录,可以使你的提交看起来更加的友好
● 修改历史提交顺序
● 修改历史提交,例如将中间的某一次分割成多次提交,保证功能的独立性
● 删除历史提交,比如你提交记录中的任意某一次提交的功能,或者修改不想要了,可以使用该功能,和下面的提交回滚比较提交的纪录也会被删除。
这些功能保证提交记录的整洁性,提高review代码的效率
更多其他的功能可以使用git命令实现

截屏2024-06-11 18.59.54.png

image12.png

注意事项:
需要是未push的提交,否者只能强制push(sourcetree设置成允许强制push,sourcetree语言设置为英文时有这个设置选项)
强制推送可能会导致数据丢失,所以在使用它之前,应该与团队成员沟通,确保你有完整的备份,确保这个操作是安全的

5 重置提交

把分支重置到某一个提交节点,比如:你的分支合并错了,或者刚提交功能产品不要了,提交的bug修改错误等等
下面看下具体操作


image13.png
image14.png

软合并:将此次提交回滚到指定提交位置,但这个过程中会将修改过的文件暂存到暂存区
混合合并:将此次提交回滚到指定的位置,但这个过程中不会将修改过的文件暂存到暂存区,而是将修改过的文件存放在工作区
强行合并:将此次提交回滚到指定的位置,但这个过程中将直接丢弃之前修改的所有文件
● 回滚本地的提交
根据实际需求选取合并类型,再点击确定即可
● 回滚远程提交(不建议)
注意事项:不建议进行此操作
1.先按照上面回滚本地提交的操作重置到某次提交,
2.强制push(sourcetree设置成允许强制push,sourcetree语言设置为英文时有这个设置选项)

6 提交回滚(把某一次提交回滚掉,本地远程都可以)

当我们开发的时候某一次提交的功能,不想要了,可以使用这个操作

imag17e.png

注意事项:会有提交记录,和回滚记录

7 patch

应用场景:可以灵活的把某些提交记录,应用到其他分支,在某些极端情况下我当前分支只想要另一个分支的某几个提交,比如向测试在我的分支功能上模拟在另一个分支修复的某个bug,或者是产品是想上线某个分支上的一部分功能。避免再人工写一遍代码,这样提高效率,避免出错,和人工再一次修改相比合并代码的时候,也不会有冲突
● 创建补丁(生成一个.diff文件)


image18.png
image19.png

注意事项:

  1. 点击创建前注意选择好存储位置
  2. 可以把多个提交记录一块创建补丁
    ● 应用补丁


    image20.png
image21.png

注意点:
sourcetree工作区或者暂存区有内容时候右键该区域有应用补丁的入口,或者通过sourcetree—>动作—>应用补丁

8 cherry-pick

应用场景:把某些提交记录,应用到其他分支,和上面的patch使用场景类似


image22.png
image23.png

● cherry-pick patch区别:
cherry-pick 操作比较快捷,patch可以把生成的.diff文件发送给别人使用,也可以对未提交的改变创建补丁。
● cherry-pick, merge区别:
merge只能合并某一个提交之前的所有的提交记录合并到某一个分支上,会把整个分支上的所有修改都合并过来。cherry-pick可以灵活的操作某一个或者某些提交

9 stash(可以跨分支使用)

使用场景:把暂时不提交的代码修改存贮下来以便下次使用,比如在某一个分支还没开发完的功能暂时存储下来,切换到另一个分支紧急开。或者把某些公用的调试代码暂存起来在多个分支上使用


image25.png
image26.png

10 tag

使用场景: 可以在某个版本发布后打上标签用于记录,如果你在版本打包上线后,打了tag,发现审核未通过,又进行了一些修改,这个时候如果版本号没有变化,你可以不必删掉这次tag重新打tag,可以使用下面的移动标签的功能
移动标签功能:(已经打好的标签移动提交节点)
● 在“标签名称”列中,键入要移动的现有标签。
● 在高级选项下,选中“ 移动现有标签 ” 框。通过点击下面的按钮(箭头指向)指定要移动的提交:


截屏2024-06-13 16.50.38.png

11 checkout

把HEAD指向任何一个提交记录,以便进行其他操作,比如,以这个节点创建新分支

12 存档

以某个提交节点把工程存储到某个文件夹下

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容