Git的一些总结

.git 目录结构

|── HEAD|── branches // 分支|── config // 配置|── description // 项目的描述|── hooks // 钩子| |── pre-commit.sample| |── pre-push.sample| └── ...|── info| └── exclude // 类似.gitignore 用于排除文件|── objects // 存储了blob,tree,commit对象| |── info| └── pack // 用于优化仓库体积,通过patch的方式└── refs |── heads└── tags // 标签
复制代码

blob,tree,commit对象

blob

blob对象是文件内容的快照

$ git cat-file -t e0f5c6
blob$ git cat-file -p e0f5c6
reademe
复制代码

tree

tree对象描述了工作目录,每个节点指向对应的blob或者子tree

$ git cat-file -t 443322
tree$ git cat-file -p 443322
100644 blob 723ef36f4e4f32c4560383aa5987c575a30c6535    .gitignore
100644 blob 56a6051ca2b02b04ef92d5150c9ef600403cb1de    1
100644 blob d218c7660f5672293d2b2241741f2e3f25008b9e    2
040000 tree 74080098daf8a1fa7368c2feac12cfab0e648d02    3
100644 blob e0f5c6d282792ef63ea012f200f5d7749b084fa0    README.md
复制代码

commit

commit对象是对tree的封装

$ git cat-file -t 186f17807d
commit$ git cat-file -p 186f17807d
tree 4433224cb7cbb72dae00b5138c8961522c531707
parent 45d0db32885c40a8c3244fa6ec24df2d7a631a3c
author 孙健 <jian.sun@ymm56.com> 1535621955 +0800
committer 孙健 <jian.sun@ymm56.com> 1535621955 +0800
复制代码

扩展 - 手动创建 commit

mktree // 从标准格式文本中创建一个树read-tree // 从仓库中读取到 index 文件ls-files -s // 检查当前 index 文件的结构write-tree // 通过这个 index 在仓库中创建一个树commit-tree // 将一个 tree 包装为 commit 对象-p 指定父commit-m 添加描述branch -f master HEAD // 更改分支指向
复制代码

工作区和暂存区

工作区

工作区就是我们的工作目录

暂存区

暂存区类似一个 tree 对象

$ git ls-files -s
100644 723ef36f4e4f32c4560383aa5987c575a30c6535 0       .gitignore
100644 56a6051ca2b02b04ef92d5150c9ef600403cb1de 0       1
100644 d218c7660f5672293d2b2241741f2e3f25008b9e 0       2
100644 00750edc07d6415dcc07ae0351e9397b0222b7ba 0       3/3
100644 e0f5c6d282792ef63ea012f200f5d7749b084fa0 0       README.md
复制代码

当我们clone一个仓库,或者检出一个提交``的时候,此时HEAD == 暂存区 == 工作区

  • 工作区修改,未添加到暂存区 - HEAD == 暂存区 != 工作区

  • 工作区修改,添加到暂存区 - HEAD != 暂存区 == 工作区

  • 工作区修改,添加到暂存区,提交到仓库 - HEAD == 暂存区 == 工作区 - nothing to commit, working tree clean

add的时候做了什么

  • 从文件中创建 blob

  • 将 blob 写入仓库

  • 更新 index

Commit的时候 做了什么

  • 从 index 文件创建 tree
  • 将 tree 写入仓库
  • 创建一个 commit 对象将树封装起来
  • 将 HEAD 作为新创建 commit 的父 commit,并更新 HEAD 未新创建的 commit

扩展:从一个 tree 更新工作区

$ git read-tree $TREE_HASH // 从一个 tree 写入到 index
$ git checkout-index -a // 从 index 检出到工作区
复制代码

分支,标签,HEAD

branch

# refs/heads/dev
47c871bb634324cfcc41e5a5affee6aa35301e03 // branch总是指向最新的提交$ git cat-file -t 47c871b
commit
复制代码

标签

# refs/tags/dev
47c871bb634324cfcc41e5a5affee6aa35301e03 // tag指向固定的提交// 同上
复制代码

HEAD

# HEAD
ref: refs/heads/dev 此时HEAD随分支前进$ git checkout HEAD^
# HEAD
47c871bb634324cfcc41e5a5affee6aa35301e03 分离HEAD,不随分支前进// 同上
复制代码

merge

merge 常用于将两条分支合并;

略过快速合并

标准的三方合并

上图:

after:

此时,你的开发历史从一个更早的地方开始分叉开来(diverged)。 因为,master 分支所在提交并不是 iss53 分支所在提交的直接祖先,Git 不得不做一些额外的工作。 出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4C5)以及这两个分支的工作祖先(C2),做一个简单的三方合并。

我们分析一下两条分支合并的过程
  • 找到两条分支对应的commit对象;
  • 找到两个commit对象共同的祖先commit对象;
  • 通过两个commit对象下的tree对象对比每个blob对象的差异;
    • 如果不同并且其中一个blob对象与祖先相同,则默认自动合并;
    • 如果不同并且都不与祖先相同
      • 修改同一处地方 产生conflict,需要手动合并
      • 没有修改同一处地方 自动合并
查看合并基底
$ git merge-base master iss53
// C2的HASH_ID
复制代码
合并
* master
$ git merge iss53
// 此时产生冲突$ git merge --abort // 撤销合并
$ git commit -a // 解决冲突后,提交
复制代码
查看冲突
$ git show :1:hello.rb > hello.common.rb // 祖先
$ git show :2:hello.rb > hello.ours.rb // 我
$ git show :3:hello.rb > hello.theirs.rb // 他$ git ls-files -u
复制代码

小技巧

1.有时候我们格式化文件之后,在之后的合并中会产生很多冲突,有没有办法忽略空格上的更改吗?

git merge [branch] --ignore-space-change
git merge [branch] -s recursive -X ignore-space-change-s 选择策略-x 策略选项
复制代码

2.通过revert撤销合并,后面再次merge的时候提示已经合并过了?

再次revert,或者通过新建一个相同的commit,指定其父commit;

$ git commit-tree $TREE_HASH -p $PARENT_HASH // 需要合并的 commit 的tree hash 和其parent hash
$ git branch -f $BRANCH $NEW_COMMIT_HASH // 将分支指向新的 commit
$ git merge $branch // 此时合并就没问题了
复制代码

rebase

继续上图:

after:

首先回到两个分支最近的共同祖先,根据当前分支(也就是要进行衍合的分支 experiment)后续的历次提交对象(这里只有一个 C4),生成一系列文件补丁;

然后以基底分支(也就是主干分支master)最后一个提交对象(C3)为新的出发点,逐个应用之前准备好的补丁文件;

最后会生成一个新的合并提交对象(C4'),从而改写 experiment 的提交历史,使它成为 master 分支的直接下游

需要注意的点

  • rebase是逐步应用补丁,可能会有多个rebase阶段,每次解决冲突都需要:

    $ git add .
    $ git rebase --continue
    复制代码
  • rebase完成之后会丢失之前的对C4的指向,导致C4无法再被找到,此时C4存在于.git/objects中,等待下次gc被回收;

  • rebase类似于多个merge过程,比如已被应用的补丁产生的新的提交会与下一个补丁进行新的三方合并;

黄金准则 - 公用分支不可作为衍合分支

上图:

rebase的滥用可能会导致混乱的提交历史


交互式rebase

$ git rebase -i HEAD~6pick fb257ad9 某次提交说明
pick fb257ad9 某次提交说明
drop fb257ad9 某次提交说明# Rebase a0daba3d..fb257ad9 onto a0daba3d (1 command)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending // 修改某次commit
# s, squash <commit> = use commit, but meld into previous commit // 将commit合并到上一个commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# d, drop <commit> = remove commit // 删除某次commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
复制代码
  • 如果之前错误的合并了某次提交,可以通过drop删除该提交
  • 如果想修改某次提交的信息,可以将该提交对应的状态改为edit

cherry-pick - 摘樱桃

cherry-pick常用于将某些提交应用于其他的分支;

cherry-pick可以理解为”挑拣”提交,它会获取某一个分支的单笔提交,并作为一个新的提交引入到你当前分支上。 当我们需要在本地合入其他分支的提交时,如果我们不想对整个分支进行合并,而是只想将某一次提交合入到本地当前分支上,那么就要使用cherry-pick了。


# cherry-pick的方式与 merge 有所不同,merge 的过程相当于两个 tree 的差异对比,而cherry-pick更像是应用更改;C<---D<---E  branch2/
master   A<---B  \F<---G<---H  branch3|HEAD*** after ***C<---D<---E<---F'<---G'<---H' branch2/
master   A<---B  \F<---G<---H  branch3|HEAD  复制代码

当我们应用某个提交的时候,实际上会通过该提交与其父提交的差异得到发生的改变,并将这些改变应用到主分支上,cherry-pick产生的三方合并,其merge-base是该提交的父提交;

* branch2
$ git cherry-pick B...H // 三点语法,前开后闭第一次 base:B our:E their: F 产生提交 F'
第二次 base:F our:F' their: G 产生提交 G'
第三次 base:G our:G' their: H 产生提交 H'
复制代码

转载于:https://juejin.im/post/5b8907c851882542d14da61c

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/389789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025. 分割数组的最多方案数

2025. 分割数组的最多方案数 给你一个下标从 0 开始且长度为 n 的整数数组 nums 。分割 数组 nums 的方案数定义为符合以下两个条件的 pivot 数目&#xff1a; 1 < pivot < nnums[0] nums[1] … nums[pivot - 1] nums[pivot] nums[pivot 1] … nums[n -1] 同时…

您是六个主要数据角色中的哪一个

When you were growing up, did you ever play the name game? The modern data organization has something similar, and it’s called the “Bad Data Blame Game.” Unlike the name game, however, the Bad Data Blame Game is played when data downtime strikes and no…

命令查看linux主机配置

查看cpu&#xff1a; # 总核数 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 物理CPU个数 X 每颗物理CPU的核数 X 超线程数# 查看物理CPU个数 cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l# 查看每个物理CPU中core的个数(即核数) cat /proc/cpui…

C#中全局处理异常方式

using System; using System.Configuration; using System.Text; using System.Windows.Forms; using ZB.QueueSys.Common;namespace ZB.QueueSys {static class Program{/// <summary>/// 应用程序的主入口点。/// </summary>[STAThread]static void Main(){Appli…

5911. 模拟行走机器人 II

5911. 模拟行走机器人 II 给你一个在 XY 平面上的 width x height 的网格图&#xff0c;左下角 的格子为 (0, 0) &#xff0c;右上角 的格子为 (width - 1, height - 1) 。网格图中相邻格子为四个基本方向之一&#xff08;“North”&#xff0c;“East”&#xff0c;“South”…

自定义按钮动态变化_新闻价值的变化定义

自定义按钮动态变化I read Bari Weiss’ resignation letter from the New York Times with some perplexity. In particular, I found her claim that she “was hired with the goal of bringing in voices that would not otherwise appear in your pages” a bit strange: …

Linux记录-TCP状态以及(TIME_WAIT/CLOSE_WAIT)分析(转载)

1.TCP握手定理 2.TCP状态 l CLOSED&#xff1a;初始状态&#xff0c;表示TCP连接是“关闭着的”或“未打开的”。 l LISTEN &#xff1a;表示服务器端的某个SOCKET处于监听状态&#xff0c;可以接受客户端的连接。 l SYN_RCVD &#xff1a;表示服务器接收到了来自客户端请求…

677. 键值映射

677. 键值映射 实现一个 MapSum 类&#xff0c;支持两个方法&#xff0c;insert 和 sum&#xff1a; MapSum() 初始化 MapSum 对象 void insert(String key, int val) 插入 key-val 键值对&#xff0c;字符串表示键 key &#xff0c;整数表示值 val 。如果键 key 已经存在&am…

算法 从 数中选出_算法可以选出胜出的nba幻想选秀吗

算法 从 数中选出Note from Towards Data Science’s editors: While we allow independent authors to publish articles in accordance with our rules and guidelines, we do not endorse each author’s contribution. You should not rely on an author’s works without …

jQuery表单校验

小小Demo&#xff1a; <script>$(function () {//给username绑定失去焦点事件$("#username").blur(function () {//得到username文本框的值var nameValue $(this).val();//每次清除数据$("table font:first").remove();//校验username是否合法if (n…

5912. 每一个查询的最大美丽值

5912. 每一个查询的最大美丽值 给你一个二维整数数组 items &#xff0c;其中 items[i] [pricei, beautyi] 分别表示每一个物品的 价格 和 美丽值 。 同时给你一个下标从 0 开始的整数数组 queries 。对于每个查询 queries[j] &#xff0c;你想求出价格小于等于 queries[j] …

django-rest-framework第一次使用使用常见问题

2019独角兽企业重金招聘Python工程师标准>>> 记录在第一次使用django-rest-framework框架使用时遇到的问题&#xff0c;为了便于理解在这里创建了Person和Grade这两个model from django.db import models class Person(models.Model):SHIRT_SIZES ((S, Small),(M, …

插入脚注把脚注标注删掉_地狱司机不应该只是英国电影历史数据中的脚注,这说明了为什么...

插入脚注把脚注标注删掉Cowritten by Andie Yam由安迪(Andie Yam)撰写 Hell Drivers”, 1957地狱司机 》电影海报 Data visualization is a great way to celebrate our favorite pieces of art as well as reveal connections and ideas that were previously invisible. Mor…

vue之axios 登陆验证及数据获取

登陆验证&#xff0c;获取token methods:{callApi () {var vm thisvm.msg vm.result //验证地址vm.loginUrl http://xxx///查询地址vm.apiUrl http://yyy/vm.loginModel {username: 你的用户名,password: 你的密码,// grant_type: password,}//先获取 tokenaxios.post(v…

5926. 买票需要的时间

5926. 买票需要的时间 有 n 个人前来排队买票&#xff0c;其中第 0 人站在队伍 最前方 &#xff0c;第 (n - 1) 人站在队伍 最后方 。 给你一个下标从 0 开始的整数数组 tickets &#xff0c;数组长度为 n &#xff0c;其中第 i 人想要购买的票数为 tickets[i] 。 每个人买票…

贝叶斯统计 传统统计_统计贝叶斯如何补充常客

贝叶斯统计 传统统计For many years, academics have been using so-called frequentist statistics to evaluate whether experimental manipulations have significant effects.多年以来&#xff0c;学者们一直在使用所谓的常客统计学来评估实验操作是否具有significant效果。…

吴恩达机器学习+林轩田机器学习+高等数学和线性代数等视频领取

机器学习一直是一个热门的领域。这次小编应大家需求&#xff0c;整理了许多相关学习视频和书籍。本次分享包含&#xff1a;台湾大学林轩田老师的【机器学习基石】和【机器学习技法】视频教学、吴恩达老师的机器学习分享、徐小湛的高等数学和线性代数视频&#xff0c;还有相关机…

saltstack二

配置管理 haproxy的安装部署 haproxy各版本安装包下载路径https://www.haproxy.org/download/1.6/src/&#xff0c;跳转地址为http&#xff0c;改为https即可 创建相关目录 # 创建配置目录 [rootlinux-node1 ~]# mkdir /srv/salt/prod/pkg/ [rootlinux-node1 ~]# mkdir /srv/sa…

319. 灯泡开关

319. 灯泡开关 初始时有 n 个灯泡处于关闭状态。第一轮&#xff0c;你将会打开所有灯泡。接下来的第二轮&#xff0c;你将会每两个灯泡关闭一个。 第三轮&#xff0c;你每三个灯泡就切换一个灯泡的开关&#xff08;即&#xff0c;打开变关闭&#xff0c;关闭变打开&#xff0…

如何生成随机不重复的11位数字

要求 不重复随机11位数字不占存储我们都知道11位数字(random)对应有最大值max和最小值min99999999999和10000000000.很简单的从最小值开始按顺序分发到最大值&#xff0c;就满足了不重复&#xff0c;不占存储&#xff0c;11位数字的特性。那么接下来就要考虑如何生成随机数字这…