关于代码托管:4个视频教你正确使用华为云代码托管服务CodeArts-Repo

源代码是企业最贵重的资产之一,一旦保留源代码的零碎呈现安全性或稳定性问题,将给企业商业及信用带来不可估量的损失。随着软件规模的不断扩大,生成软件的源代码规模也在急剧回升,单个软件系统规模已达数亿行、开发人员达数千人——如何治理好宏大的源代码,并让企业员工继续稳固的发展软件开发流动将成为一个重大的挑战。 华为云代码托管服务CodeArts Repo是一款全栈自研、基于Git的云端代码托管服务,旨在爱护企业外围代码资产平安,晋升企业研发品质和效率。 为了让您更好地理解并应用CodeArts Repo,本文将通过4个短视频为你介绍CodeArts Repo的个性实际操作。 01 个性简介CodeArts Repo是华为全栈自研的代码托管服务,基于Git提供分布式代码治理和协同开发能力,助力不同规模企业的研发品质和效率晋升。 https://www.bilibili.com/video/BV1ur4y1d75j/?aid=744777483&ci... 02 创立代码仓CodeArts Repo代码托管服务,可一键创立代码仓库,反对自定义策略配置、平安治理、疾速配置同步等性能。 https://www.bilibili.com/video/BV1EG411f7Yx/?aid=404852818&ci... 03 代码协同开发CodeArts Repo代码托管服务,笼罩云、管、端、车、IT等超大产品协同开发,10亿级代码治理,万人团队并发在线协同作业、高并发代码下载,反对不同规模团队跨地区高效协同。 https://www.bilibili.com/video/BV1tX4y1x7b4/?aid=359823469&ci... 04 代码检视审核CodeArts Repo代码托管服务,基于分支和成员角色的代码上库作业流控制,配合工具自动化检查和人工审核流程,内嵌华为CleanCode实际成绩,保障每一行上库代码的品质。 https://www.bilibili.com/video/BV1mm4y1n7oQ/?aid=702331995&ci... 目前,华为云CodeArts Repo现在已广泛应用于国内外财政、社保、物流、能源等畛域,减速企业数字化转型。 如上海某出名大型物流企业领有超过100个零碎平台,1000多个仓库,其业务波及快递、物流、跨境、仓储与供应链等多项业务和解决方案。该企业应用CodeArts Repo治理代码和帮助标准企业开发流动,无效晋升研发团队合作效率,升高代码品质问题70%。 源于华为,服务世界,华为云CodeArts Repo着力将华为公司30余年的源代码治理教训外溢,服务千百行业。面向未来,华为云将对CodeArts Repo继续翻新降级,摸索边缘下载减速、多仓协同,提供更丰盛的安全检查个性,携手国内外客户、搭档以及开发者,独特晋升软件开发品质和效率。 华为云CodeArts Repo服务已上线体验通道:https://www.huaweicloud.com/product/codehub.html?utm_campaign...

September 8, 2023 · 1 min · jiezi

关于代码托管:重磅腾讯云-CODING-入选软件供应链产品名录

点击链接理解详情 2023 年 8 月 25 日,由中国信息通信研究院、中国通信标准化协会联结主办的“2023 首届 SecGo 云和软件平安大会”在京召开。会上正式公布了第二期《软件供应链厂商和产品名录》,旨在晋升软件供应链透明度,宣传推广一批成熟度高、具备示范作用的优良案例,踊跃应答一直呈现的软件供应链平安治理难题。腾讯云 CODING 代码托管平台凭借先进的国产技术计划胜利入选中国信通院软件供应链厂商和产品名录全家福,欠缺信息安全软件畛域矩阵。 软件供应链产品名录以产品安全为次要指标,通过对软件供应链厂商和产品安全性进行验证。云计算开源产业联盟牵头编撰名录,致力于共筑软件供应链平安生态,促成软件供应链平安产业衰弱有序倒退,同时为用户抉择适合的厂商及产品提供选型领导。 腾讯云 CODING 作为目前国内市场上惟一基于企业级 Java 技术齐全自主研发的一站式软件研发平台,其企业级代码治理平台提供平安、高速的 Git/SVN 代码仓库服务,能够实现代码与协同事项的无效关联,提供金融级代码平安解决方案,包含代码分片存储、仓库平安检测、暗藏分支、目录权限设置等,为客户提供企业级的代码治理服务,通过代码托管平台能够平安、高效地进行团队代码合作,助力我的项目的疾速迭代和继续交付。 要害劣势自主研发全面国产化自主研发,产品已申请软件著作权及专利;反对鲲鹏、飞腾、海光等国产芯片,反对麒麟、统信、TencentS Sever 等国产操作系统。 功能强大全面稳固的代码托管平台,笼罩代码仓库、版本治理、合并申请、代码评审等。CODING 代码评审性能反对变更内容的行级比照和评论,评审者可发动代码倡议,发起者可间接利用变更内容。同时反对接入自动化代码评审工具,如 流水线、代码扫描,执行后果可作为门禁管控合并申请合入。此外,还反对评审受权、CodeOwner、未解决评论等评审策略,严控合入规范,保障重要分支的代码品质。 高可用存储及备份机制CODING 代码仓库别离提供了原生 Git 代码托管能力和原生 SVN 代码托管能力,反对横向扩大。其中 Git 代码托管反对高可用,采纳分片+多正本的形式保障了数据冗余平安,局部数据存储节点的故障不影响服务可用性及数据完整性;同时,欠缺的数据备份、复原计划,多维度确保数据的平安、牢靠。 多维度的平安管控策略CODING 代码托管反对精细化的成员权限,企业可按需配置权限管控模型。反对协定、分支、文件门路、提交者、ip 等多维度的推送管控能力。 定制化解决方案提供残缺的私有化部署计划及高质量的交付,提供丰盛凋谢的 API 及反对定制化开发。并具备业余的售后服务,可依据企业需要,提供平台应用征询,专属服务团队 7×24 小时不间断的售后技术支持。 欠缺的凋谢能力内置丰盛的 openapi、service hook,能够灵便与上下游工具链如:项目管理、继续集成、对立门户等第三方零碎进行对接。 丰盛的最佳实际腾讯云 CODING 目前服务 300 万开发者,五万多家企业,辐射互联网、金融、政企、工业、运营商、媒体、医疗、教育等各个行业。 将来,腾讯云 CODING 代码托管将持续深耕代码平安治理畛域,助力更多企业稳固、高效地进行团队代码合作,为企业数据安全保驾护航。 名录及全家福获取形式扫描下方二维码取得电子版《软件供应链厂商和产品名录》及全家福:

September 1, 2023 · 1 min · jiezi

关于代码托管:你能发现这段-Python-代码中的-bug-吗

点击链接理解详情 【CSDN 编者按】大家一起来找 Bug。 原文链接:https://dwrodri.gitlab.io/can-you-spot-the-bug-in-this-python... 本文已获作者受权,未经容许,禁止转载! 作者 | Derek Rodriguez 译者 | 弯月 责编 | 夏萌 出品 | CSDN(ID:CSDNnews) 最近,在解析文本时,我遇到了一个非常乏味的问题。在深入探讨之前,让我先来介绍一下背景故事。我的工作是剖析文本文件中的一些以逗号分隔的数据,如下所示: 这个文本文件蕴含若干宽度可变的十六进制值,每行至多三个字段。我只关怀第一个和第三字个段。在我看来,剖析工作可分为三步: 循环读取每一行数据;利用逗号将数据分解成一个列表;选取第一个和第三个元素,并将它们转换为整数。看似很简略,我能够应用 pandas DataFrame 编写几行代码就够了。 上面是我编写的代码: 你发现 bug 了吗?反正我没看进去。上面,我来具体解释一下这段代码,并深刻分析我到底错在哪儿了。 代码详解 CSV文件是列表的列表 我简略地认为,CSV 数据就是列表的列表。因而,我能够将各个元素视为嵌入列表。我从网上的一篇帖子中找到了读取嵌入列表的代码,而后复制粘贴: nested_lists = [[1,2,3],[4,5,6],[7,8,9]]flattened_list = [element for sublist in nested_lists for element in sublist]以前我曾接触过 C 和 C++,之后才学习了 Python,因而在学习嵌套推导式时,我感觉 Python 只是机器能够了解的伪代码。这个嵌套列表会生成以下字节码: 而后,我一些本人的代码进行扩大,最终失去了以下代码: 谬误 事实证明,Python 无奈依照我的设想将可迭代的文本合成与推导式联合起来,你必须把 .split(",") 调用放在另一个列表中: 这让我有点伤脑筋,因为 .split(",") 自身就是一个列表,将它打包到另一个列表中,岂不变成了双重嵌套列表?我不太明确。我尝试通过编译器浏览器寻找答案。下图展现了正确的生成器表达式与我编写的代码之间的差别: ...

August 17, 2023 · 1 min · jiezi

关于代码托管:爆测一周22年必看最细致代码托管工具测评

版权申明: 本文转载于公众号 [JavaGuide] 。 原文链接:【https://mp.weixin.qq.com/s/A7...】 前言大家好,我是 Gudie。明天的内容次要是为了帮忙大家在进行代码托管工具选型时可能思考得更加全面。 大家平时也接触Github、Gitee 这些开源场景的代码托管平台,他们对集体开发者敌对,能够接触到很多优良的开源我的项目。但对团队代码治理,光这些还不够,还须要思考老本、速度、和其余研发工具买通等。最近在帮初创企业团队做代码托管的选型,因为公司业务属性,迭代比拟快,人力缓和,没有足够资金老本投入自建代码托管,而且最放心的是本人搞的话容灾安防做的不到位,导致企业代码数据出问题。 网上代码托管选型的文章不少,不过大多内容有点长远,很多最新的平台没有包含进来,集体花了大略一个星期的工夫,把目前市面上比拟火的代码托管平台(开源托管平台:Github、Gitee;企业级托管平台:Gitlab、阿里云效Codeup、 腾讯Coding)做了一些比拟,比拟的维度包含速度、老本、产研工具链完整性、平安、统计报表等,心愿能够帮忙正在进行代码托管选型的技术同行做决策选型。 在开展具体比拟前,先给出集体体验的论断供大家参考,不便大家对应到关注的内容: 维度Github(国外)Gitlab(国外)Gitee阿里云云效Codeup腾讯Coding平台性质国外开源托管平台国外企业级托管平台国内开源托管平台国内企业级托管平台国内企业级托管平台实用对象开源,集体向企业级,各种类型规模团队均实用,而自建版本有保护老本和危险,适宜有人力有资本的大企业抉择开源,集体向企业级,性能全面,各种类型规模团队均实用,代码托管、CICD、测试治理等产品模块能够自在搭配组合企业级,性能全面,但产品能力较简略,例如CICD原生反对的组件少,资源权限治理能力弱,适宜小团队场景应用速度慢(无代理 KiB/s 级)慢(无代理 KiB/s 级)中快 (MiB/s 级)快(MiB/s 级)研发工具链完整性托管性能残缺,但平台原生反对如测试治理、部署治理较弱,不过能够不便地通过集成三方和插件市场补足托管性能残缺,且具备DevOps一站式治理能力托管性能残缺,根本无DevOps其余模块反对托管性能残缺,且具备DevOps一站式治理能力托管性能残缺,但DevOps其余模块如测试治理、继续集成与部署反对较弱平安性能国外产品不评估国外产品不评估开源平台不评估高较高数据度量插件、无企业视角维度丰盛(企业、库视角,研发价值流视图)看上去维度较少,次要是提交、行数的代码奉献指标维度丰盛(企业、库视角,除了提交、代码行这类代码奉献外,还有成员的评审流动参与率、千行代码评论数、扫描问题趋势等)维度较少(企业视角,目前看到提交、代码行、合并申请次数这3个指标)价格/容量根底版收费,高级性能付费 ; eam:4美元人/月 ; Enterprise:21美元人/月根底版收费,平安标准等企业个性付费 Premium:19美元人/月Ultimate:99美元人/月收费企业版;人数:5人;仓库总容量:5G 单仓库:<=500MLFS:无收费企业版:人数:不限仓库总容量:不限单仓库:<=5GLFS:不限收费企业版:人数:不限仓库总容量:100G单仓库:<=2GLFS:?应用场景在选型时,首先要明确你的应用场景,是想在开源社区里合作开发(通常是集体开发者),还是想要领有私密的代码仓库(通常是企业团队)。 开源合作场景如果在意开源场景,目前可抉择国外的 Github,或是国内的 Gitee。 GithubGitHub 代码托管平台,蕴含了全世界很多优良的开源我的项目,能够从GitHub获取到很多很多优良的开源我的项目来进行学习,也能够将本人的我的项目上传上去与别人分享,当初已被微软收买。GitHub最开始并没有收费的公有仓库,被微软收买之后,个人用户才反对了创立公有仓库,尽管也能反对公有库,但他的次要场景还是集中在开源合作这件事上。 对于微软收买GitHub,不少用户的反馈比拟强烈。人们感觉开源必须得中立,有了微软背景就不独立了,GitHub跟开发者之间的间隔,可能会越走越远,后续如何倒退得持续察看。 GiteeGitee 码云是国内的一个开源代码托管社区(哈哈这名字总让人感觉和阿里有关系,其实阿里云有本人的代码托管服务),因为GitHub属于国外的网站,因而国内用户拜访的时候,常常会很慢,影响体验,而 Gitee 不存在拜访速度慢的问题,而且中文化也比拟敌对,比拟适宜国内的开源爱好者们应用。不过因为百度鼎力投资了Gitee,不少开发者认为它也不这么中立了。 尽管比照 Github 还有较大差距,不过随着国家政策的激励,国内开源也正在疾速倒退的过程中。 企业/公有托管场景如果你对代码私密性要求比拟高,通常在企业、团队公有代码治理场景下应用,那么国外的Gitlab,国内的阿里云云效Codeup、腾讯Coding 是更好的抉择。 GitlabGitLab 利用 Ruby on Rails 开发,据说最早也用过 Github 进行托管,后独立倒退为出名的代码托管平台,同时反对 SaaS 版和自治理的私有化部署版本,因为其丰盛的代码合作管控能力,备受企业青眼,不过因为是国外的平台,云服务的访问速度还是存在慢和不稳固的问题。 对于企业,还有一个抉择是私有化部署托管服务。例如 Gitlab 就凋谢了根底版本供企业自行部署应用,目前在国内企业中的使用量还是比拟宽泛的。然而私有化部署是一把双刃剑,如果企业有足够的资本和人力,将托管服务部署在本人的服务器上感觉最平安,可是如果容灾和防护不到位,宕机数据失落、黑客拖走代码也不是没有产生过。所以,如果自信有足够的技术实力的企业,能够抉择私有化部署,反之,抉择大公司提供的 SaaS 托管云服务是更好的决策。 阿里云云效 Codeup提到阿里云的代码托管,一搜全是阿里云 Code,然而事实是这个平台早在 2020 年就曾经升级成阿里云 Codeup (https://codeup.aliyun.com/)了,同时带了个云效的品牌名,降级为提供笼罩项目管理、代码治理、测试治理、继续集成、制品治理、公布治理的 DevOps 一站式研发治理平台。 听起来挺简单,简略说就是你在开发过程中须要用到的各种工具都在一个平台上提供给你了,违心用哪些你本人选。这对于企业来说大大降低了治理难度,以前有一堆账号一堆工具,切来切去本人都凌乱了,数据也扩散在各个工具里,人也不好管,来个新人教半天讲不明确。当初一个平台一套账号就搞定了。 鉴于本文次要聊代码托管,就把云效外面托管产品 Codeup 拎进去看。它提供基于 Git 的代码托管服务,主打企业级托管,因而在管控和平安层面做了不少增强,因为在国内,访问速度相比 Gitlab、Github 快不少。 ...

January 19, 2022 · 1 min · jiezi

关于代码托管:如何通过云效Codeup完成代码合并

如何通过云效Codeup实现代码合并云效代码治理Codeup是阿里云出品的一款企业级代码治理平台,提供代码托管、代码评审、代码扫描、品质检测等性能,全方位爱护企业代码资产,帮忙企业实现平安、稳固、高效的研发治理。Codeup 提供欠缺的配置能力反对丰盛的代码评审场景,自动化代码扫描进步评审效率。基于 WebIDE 的评审工具给你带来全新的评审体验。 你能够通过「分支设置」实现代码评审场景定制。 在设置中能够通过「敏感信息检测」及「Java 代码规约扫描」去晋升评审效率。 实现设置后你能够新建「合并申请」-通过合并申请-合并分支流程实现分支合并。 合并申请当分支代码想合并骨干时,能够通过提交合并申请的形式进行。 Codeup 反对多种合并申请校验形式:通过评审人数目校验、CodeOwner 机制、主动扫描卡点等。 新建合并申请 在列表页展示新建入口,点击后展示新建合并申请弹层。 若设置默认评审人(详见分支设置)则在评审人局部主动将默认评审人填写在评审人列表中。若开启 CodeOwner 机制(详见CodeOwner 机制)则默认回填 CodeOwner 且不可删改。 在信息填写实现后点击确定实现合并申请创立。 通过合并申请 代码抵触解决 当合并的分支存在代码抵触时,零碎会主动卡点,无奈进行合并操作。Codeup 提供了两种抵触解决形式:命令行形式 及 Web IDE 可视化抵触解决。 命令行形式: //步骤1 fetch并切换到源分支git fetch origingit checkout sourceBranch//步骤2 合并指标分支git merge origin/master //步骤3 解决抵触并pushWeb IDE 可视化解决:用户关上 Web IDE,零碎会默认展现本次合并发生冲突的文件和抵触的代码字段 评审人卡点 在设置评审人通过数目时,通过数量小于设定数目时则进行卡点。 评论 反对评审人基于文件改变提出评论。 鼠标点击代码行可开展行评论,参见①。所有评论信息可通过开展②查看,同时能够在②中进行整体评论。 输出行评论可抉择间接公布或存为草稿,草稿仅本人可见。 评审实现后可点击右上角的③提交评论进行多份草稿的对立提交,提交后别人可见。 点击④实现提交。 自动化卡点 参见 敏感信息检测和 Java 代码规约扫描 局部。扫描后果点击⑤跳转文件详情查看: 反对Web IDE查看改变文件 ...

October 14, 2021 · 1 min · jiezi

关于代码托管:别再自建代码托管系统了云效代码托管平台免费不限容量

别再自建代码托管零碎了,应用云效代码托管平台收费、不限容量,云效代码治理 Codeup,10万企业都在用的代码治理平台,提供代码托管、代码评审、代码扫描、品质检测、继续集成等性能,全方位爱护企业代码资产,帮忙企业实现平安、稳固、高效的代码托管和研发治理。 为什么应用云端托管平台?一些企业在最后开始进行代码托管时会抉择自建代码托管零碎,这就意味着须要以下筹备工作: 选型适宜企业开发场景的开源软件;筹备托管存储硬件设施;在这个过程中可能会遇到的问题: 须要对开源软件十分相熟的人员进行搭建与保护;破费老本购买实体或云端存储服务器;须要专门破费老本晋升平安及稳定性,否则容易造成托管零碎呈现问题影响交付进度;查看下方视频请点击:https://cloud.video.taobao.co... 绝对自建,云托管平台在代码存储方面,提供了高可用多正本,主动备份,并可能反对高速拜访。而在代码平安方面也提供了欠缺保障机制,升高成员泄露代码数据的危险。 综合以上剖析,对于中小企业,以及大型企业的开发团队而言,抉择云平台托管代码,实际上是更省心、更便捷、更平安的抉择。 云效Codeup稳固的代码托管平台,业界当先的多正本架构,让代码托管稳固、疾速,源自阿里巴巴自研技术,撑持阿里百万级代码库和数万工程师合作历经屡次「双十一」我的项目实际与挑战。

September 29, 2021 · 1 min · jiezi

借助URLOS快速安装Gogs

简介Gogs 是一款极易搭建的自助 Git 服务。 今天我们介绍一种更快速的安装方法,那就是通过URLOS一键安装Gogs。urlos是什么? URLOS是一个云主机管理软件,基于Docker容器技术打包和运行应用,包含负载均衡和故障转移等高级功能,可自动识别机器和云应用的故障并将云应用转移至可用的机器上,单机故障并不影响业务开展。 你可以使用以下命令安装URLOS: curl -LO www.urlos.com/iu && sh iu在此不讨论URLOS的使用方法,感兴趣的朋友请自行搜索,我们直接来看URLOS如何快速安装Gogs: 安装流程1.登录URLOS系统后台,在应用市场中搜索“Gogs”,找到之后,直接点击安装按钮 2.填写服务名称、选择运行节点、服务端口、选择智能部署 3.填写域名:www.aaa.com(这里填写自己的域名) 然后点击“提交”按钮,等待部署完成; 4.创建数据库应用市场中搜索“mysql”,安装mysql-5.6: 填写如下: 点击“提交”后等待mysql-5.6部署完成; 在服务列表里找到刚刚安装成功的mysql,选择”管理数据库“ 点击右上角的添加数据库 填写如下: 5. Gogs初始化向导访问在第3步中填写的域名:www.aaa.com。 点击“立即安装”。 安装成功后,注册一个帐户并登录:

July 10, 2019 · 1 min · jiezi

CODING 研发管理系统上线全球加速,助力企业跨区域协作

CODING 研发管理系统现已全面支持全类型代码仓库的全球加速访问。随着国内互联网红利的日趋枯竭与全球互联网的加速普及。越来越多的企业开始走出国门,将目光投向全世界,搭建跨国体系。跨出国门的中国企业在选择服务时,首要考虑国内的速度和可靠性,同时需要兼顾全球各地区的访问稳定性,故而往往向国内的服务商寻求全球化解决方案。为了更好地服务这部分用户,解决其研发管理的异地协作问题,CODING 产品团队对产品架构进行了优化调整,并且联合腾讯云的网络团队,优化全球线路,为用户提供全球范围内的就近接入。这一优化已经明显提升了 CODING 研发管理系统的各地区访问速度,减少了延迟、抖动、丢包等网络问题对产品服务的影响,提升了在全球范围的访问体验。为此我们做了一个对比测试,来看看国内主流的研发管理系统的代码托管模块在跨大洲情况下的速度表现。测试方法git clone 克隆前端框架 React 代码仓库(latest commit 4d5cb64)开源地址:https://github.com/facebook/r…仓库大小:90.66 MiB克隆速度以 Receiving objects 最终输出的日志为准。连续克隆 3 次,记录每次克隆速度,取 3 次的平均值。测试服务器海外地区使用的 AWS EC2 实例机型:t2.micro (变量 ECU, 1 vCPU, 2.5 GHz, Intel Xeon Family, 1 GiB 内存)使用的服务器系统发行版:Ubuntu 18.04 LTSGit 客户端版本号:2.17.1国内使用的 UCloud 云主机(上海二可用区B)机型:标准型N1(CPU 1 核,Intel Xeon E5-2630 V3 (Haswell),1 GiB 内存)使用的服务器系统发行版:Ubuntu 16.04 LTSGit 客户端版本号:2.7.4测试结果CODING 研发管理系统在全球各地的访问速度和稳定性上都有极佳表现,至少 2MiB/s 的连接速度,确保您的团队能享受不受地域限制的异地无缝协作研发体验。CODING 研发管理系统在各大洲访问速度表现:注:以上数据是在中国时区,工作时间的测试结果。立足中国,连接全球,依托全球加速的上线,CODING 研发管理系统将结合先进的研发管理理念和中国研发团队长期的实践经验,帮助出海企业将研发效能提升至全新标准。扫描二维码获取完整测试截图报告

April 9, 2019 · 1 min · jiezi

版本控制工具——Git常用操作(下)

本文由云+社区发表作者:工程师小熊摘要:上一集我们一起入门学习了git的基本概念和git常用的操作,包括提交和同步代码、使用分支、出现代码冲突的解决办法、紧急保存现场和恢复现场的操作。学会以后已经足够我们使用Git参加协作开发了,但是在开发的过程中难免会出错,本文主要介绍版本控制的过程中出错了的场景,以及Git开发的一些技巧,让我们用的更流畅。上集回顾:Git的基本概念一个人使用Git时的代码版本控制–(提交、拉代码、分支操作)多人合作时的代码版本控制–(合并冲突、暂存代码)本文核心:后悔药-各种后悔操作(撤消commit,回滚,回退远程仓库等)哎呀,提交的时候漏了文件tag操作git忽略不想提交的文件后悔药撤消当前commit如果你发现刚刚的操作一不小心commit了,所幸你还没有推送到远程仓库,你可以用reset命令来撤消你的这次提交。reset命令的作用:重置HEAD(当前分支的版本顶端)到另外一个commit。我们的撤消当前提交的时候往往不希望我们此次提交的代码发生任何丢失,只是撤消掉commit的操作,以便我们继续修改文件。如果我们是想直接不要了这次commit的全部内容的任何修改我们将在下一小节讨论。来,我们先说一句蠢话来diss老板$ touch to_boss.txt$ echo ‘my boss is a bad guy!’ > to_boss.txt$ git add to_boss.txt$ git statusOn branch masterYour branch is up to date with ‘origin/master’.Changes to be committed: (use “git reset HEAD <file>…” to unstage) new file: to_boss.txt$ git commit -m “[+]骂了我的boss”[master 3d113a7] [+]骂了我的boss 1 file changed, 1 insertion(+) create mode 100644 to_boss.txt创建to_boss.txt文件,并向其写入了my boss is a bad guy!add然后status查看新文件已经加入跟踪commit提交了这次的修改好了,刚刚我们“不小心”diss了我们的老板,要是被发现就完了,所幸还没有push,要快点撤消这些提交,再换成一些好话才行。我们使用以下命令:$ git reset –soft head^$ git statusOn branch masterYour branch is behind ‘origin/master’ by 1 commit, and can be fast-forwarded. (use “git pull” to update your local branch)Changes to be committed: (use “git reset HEAD <file>…” to unstage) new file: to_boss.txt$ cat to_boss.txtmy boss is a bad guy!$ echo ‘my boss is a good boy!‘my boss is a good boy!$ echo ‘my boss is a good boy!’ > to_boss.txt$ cat to_boss.txtmy boss is a good boy!$ git add to_boss.txt$ git statusOn branch masterYour branch is behind ‘origin/master’ by 1 commit, and can be fast-forwarded. (use “git pull” to update your local branch)Changes to be committed: (use “git reset HEAD <file>…” to unstage) new file: to_boss.txt $ git commit -m “[]夸了我的boss”[master 8be46aa] []夸了我的boss 1 file changed, 1 insertion(+) create mode 100644 to_boss.txtgit reset –soft head^撤消了本次提交,将工作区恢复到了提交前但是已经add的状态将to_boss.txt的内容改成了my boss is a good boy!add然后commit提交好了,有惊无险,这就是撤消commit的操作。另一种情况是如果你想撤消commit的时候支持舍弃这次全部的修改就把git reset –soft head^改成git reset –hard head^,这样你本地修改就彻底丢掉了(慎用),如果真用了想找回来怎么办?见救命的后悔药。当然了,你只要开心不加soft或hard参数也是安全的(相当于使用了–mixed参数),只不过是撤消以后你的本次修改就会回到add之前的状态,你可以重新检视然后再做修改和commit。回退远程仓库要是我们做的更过分一点,直接把这次commit直接给push怎么办?要是被发现就全完了,我们来看看github上的远程仓库。upload successful完了,真的提交了(我刚刚push的)让我们冷静下来,用撤消当前commit的方法先撤消本地的commit,这次我们来试试用hard参数来撤消$ git reset –hard head^HEAD is now at 3f22a06 [+]add file time.txt$ git statusOn branch masterYour branch is behind ‘origin/master’ by 1 commit, and can be fast-forwarded. (use “git pull” to update your local branch)nothing to commit, working tree clean$ git push origin master –forceTotal 0 (delta 0), reused 0 (delta 0)To github.com:pzqu/git_test.git + 3d113a7…3f22a06 master -> master (forced update)使用git reset –hard head^回滚到上一个commit使用git status查看现在的工作区情况,提示Your branch is behind ‘origin/master’ by 1 commit,代表成功表了上一次的提示状态,nothing to commit, working tree clean代表这次的修改全没了,清理的算是一个彻底。如果还想找回来怎么办,我们还真是有办法让你找回来的,见救命的后悔药。git push origin master –force 命令强制提交到远程仓库(注意,如果是在团队合作的情况下,不到迫不得已不要给命令加–force参数) 让我们看看githubupload successful真的撤消了远程仓库,长舒一口气。暂存区(Stage)到工作区(Working Directory)如果我们刚刚执行了git reset –soft或者add等的操作,把一些东西加到了我们的暂存区,比如日志文件,我们就要把他们从暂存区拿出来。$ git statusOn branch masterYour branch is up to date with ‘origin/master’.Changes to be committed: (use “git reset HEAD <file>…” to unstage) new file: mysql.log $ git reset – mysql.log$ git statusOn branch masterYour branch is up to date with ‘origin/master’.Untracked files: (use “git add <file>…” to include in what will be committed) mysql.lognothing added to commit but untracked files present (use “git add” to track)status查看暂存区,里面有一个mysql.log被放进去了git reset – mysql.log把mysql.log取出来status可以看到真的取出来了 然后如果不要想这个文件的话再rm掉就好啦,但是如果这些文件每次自动生成都要用这种方式取出暂存区真的好累,我们可以用 git忽略不想提交的文件回滚文件到某个提交当我们想要把某个文件任意的回滚到某次提交上,而不改变其他文件的状态我们要怎么做呢?我们有两种情况,一种是,只是想在工作区有修改的文件,直接丢弃掉他现在的修改;第二种是想把这个文件回滚到以前的某一次提交。我们先来说第一种:取消文件在工作区的修改$ cat time.txt10:41$ echo 18:51 > time.txt$ git statusOn branch masterYour branch is up to date with ‘origin/master’.Changes not staged for commit: (use “git add <file>…” to update what will be committed) (use “git checkout – <file>…” to discard changes in working directory) modified: time.txtno changes added to commit (use “git add” and/or “git commit -a”)$ cat time.txt18:51$ git checkout – time.txt$ cat time.txt10:41更新time.txt的内容,可以status看到他发生了变化git checkout – time.txt , 取消这次在工作区的修改,如果他已经被add加到了暂存区,那么这个命令就没有用了,他的意思是取消本次在工作区的修改,去上一次保存的地方。如果没有add就回到和版本库一样的状态;如果已经加到了暂存区,又做了修改,那么就回加到暂存区后的状态将文件回滚到任意的版本我们这里说的把文件回滚到以前的某个版本的状态,完整的含义是保持其他文件的内容不变,改变这个文件到以前的某个版本,然后修改到自己满意的样子和做下一次的提交。核心命令git checkout [<options>] [<branch>] – <file>…我们还是用time.txt这个文件来做试验,先搞三个版本出来,在这里我已经搞好了,来看看:版本1,time.txt内容00:50commit 35b66ed8e3ae2c63cc4ebf323831e3b917d2b1d4 (HEAD -> master, origin/master, origin/HEAD)Author: pzqu <pzqu@example.com>Date: Sun Dec 23 00:51:54 2018 +0800 []update time to 00:50版本2,time.txt内容18:51commit 856a74084bbf9b678467b2615b6c1f6bd686ecffAuthor: pzqu <pzqu@example.com>Date: Sat Dec 22 19:39:19 2018 +0800 []update time to 18:51版本3,time.txt内容10:41commit 3f22a0639f8d79bd4e329442f181342465dbf0b6Author: pzqu <pzqu@example.com>Date: Tue Dec 18 10:42:29 2018 +0800 [+]add file time.txt现在的是版本1,我们把版本3检出试试。$ git checkout 3f22a0639f8d – time.txt$ cat time.txt10:41$ git statusOn branch masterYour branch is up to date with ‘origin/master’.Changes to be committed: (use “git reset HEAD <file>…” to unstage) modified: time.txt使用checkout+commit id+– filename的组合,横跨版本2把历史版本3的time.txt搞出来了查看状态,time.txt被改变了我们来把time.txt恢复到版本1,同样的方法,因为版本1是上一次提交我们可以省略掉版本号$ git checkout – time.txt$ cat time.txt00:50看到了吧!只要用git checkout commit_id – filename的组合,想搞出哪个文件历史版本就搞出哪个。到了这里,你可能会很懵比,reset和checkout命令真的好像啊!都可以用来做撤消checkout语义上是把什么东西取出来,所以此命令用于从历史提交(或者暂存区域)中拷贝文件到工作目录,也可用于切换分支。reset语义上是重新设置,所以此命令把当前分支指向另一个位置,并且有选择的变动工作目录和索引。也用来在从历史仓库中复制文件到索引,而不动工作目录。还想不通可以给我发邮件:pzqu@qq.com救命的后悔药来到这里我已经很清楚的你的现况了,你的代码丢了现在一定非常的着急,不要慌,总是有办法找回他们的。但是前提是要保证你的项目根目录下.git文件夹是完整的,要是手动删除了里面的一些东西那就真完了。还要保证一点,你的代码以前是有过git追踪的,最少add过找回你丢失的历史记录Git提供了一个命令git reflog用来记录你的每一次命令,贴个图吧直观点:upload successful有没有发现,git reflog里的全部都是和改变目录树有关的,比如commit rebase reset merge,也就是说一定要有改变目录树的操作才恢复的回来像add这种操作就不能恢复了吗?那肯定不是,只是要用更麻烦点的方式来恢复git log是一样的,也可以看到所有分支的历史提交,不一样的是看不到已经被删除的 commit 记录和 reset rebase merge 的操作 我们可以看到git reflog前面的就是commit id,现在我们就可以用之前介绍过的方法来回滚版本了,撤消当前commit$ git reset –hard 856a740HEAD is now at 856a740 []update time to 18:51$ git log -1commit 856a74084bbf9b678467b2615b6c1f6bd686ecff (HEAD -> master)Author: pzqu <pzqu@example.com>Date: Sat Dec 22 19:39:19 2018 +0800 []update time to 18:51 $ git reset –hard 35b66edHEAD is now at 35b66ed []update time to 00:50$ git log -2commit 35b66ed8e3ae2c63cc4ebf323831e3b917d2b1d4 (HEAD -> master, origin/master, origin/HEAD)Author: pzqu <pzqu@example.com>Date: Sun Dec 23 00:51:54 2018 +0800 []update time to 00:50commit 856a74084bbf9b678467b2615b6c1f6bd686ecffAuthor: pzqu <pzqu@example.com>Date: Sat Dec 22 19:39:19 2018 +0800 []update time to 18:51根据git reflog返回的结果,用git reset –hard commit_id回退到856a740这个版本git log -1看近一行的日志,可以看到目前就在这了再根据git reflog的结果,用git reset –hard 35b66ed跑到这次提交git log -2看到两次提交的日志,我们就这么再穿梭过来了,就是这么爽 但是我们如果只是想把此提交给找回来,恢复他,那还是不要用reset的方式,可以用cherry-pick或者merge来做合并找回忘记提交的历史记录你之前没有commit过的文件,被删除掉了,或者被reset –hard的时候搞没了,这种情况可以说是相当的难搞了,所幸你以前做过add的操作把他放到过暂存区,那我们来试试找回来,先来创建一个灾难现场$ echo ‘my lose message’ > lose_file.txt$ git add lose_file.txt$ git statusOn branch masterYour branch is up to date with ‘origin/master’.Changes to be committed: (use “git reset HEAD <file>…” to unstage) new file: lose_file.txt$ git reset –hard 35b66ed8HEAD is now at 35b66ed []update time to 00:50$ git statusOn branch masterYour branch is up to date with ‘origin/master’.nothing to commit, working tree clean$ lsREADME.md need_stash.txt share_file.txt time.txt创建一个叫lose_file.txt的文件并写入内容my lose message,并把他加到暂存区用git reset –hard 35b66ed8用丢弃一切修改的方式来使现在的工作区恢复到35b66ed8版本,因为还没提交所以也就是恢复到当前的(head)版本。我们用status和ls再看,这个叫lose_file.txt的文件真的没了,完蛋了,第一反应用刚刚学到的命令git reflow会发现根本就不好使核心命令:git fsck –lost-found,他会通过一些神奇的方式把历史操作过的文件以某种算法算出来加到.git/lost-found文件夹里$ git fsck –lost-foundChecking object directories: 100% (256/256), done.Checking objects: 100% (3/3), done.dangling blob 7f5965523d2b9e850b39eb46e8e0f7c5755f6719dangling commit fdbb19cf4c5177003ea6610afd35cda117a41109dangling commit 8be46aa83f0fe90317b0c6b9c201ad994f8caeafdangling blob 11400c1d56142615deba941a7577d18f830f4d85dangling tree 3bd4c055afedc51df0326def49cf85af15994323dangling commit 3d113a773771c09b7c3bf34b9e974a697e04210adangling commit bfdc065df8adc44c8b69fa6826e75c5991e6cad0dangling tree c96ff73cb25b57ac49666a3e1e45e0abb8913296dangling blob d6d03143986adf15c806df227389947cf46bc6dedangling commit 7aa21bc382cdebe6371278d1af1041028b8a2b09这里涉及到git的一些低层的知识,我们可以看到这里有blob、commit、tree类型的数据,还有tag等类型的。他们是什么含义呢?upload successfulblob组件并不会对文件信息进行存储,而是对文件的内容进行记录commit组件在每次提交之后都会生成,当我们进行commit之后,首先会创建一个commit组件,之后把所有的文件信息创建一个tree组件,所以哪个blob代表什么文件都可以在tree 里找到 我们来看看怎么恢复刚刚不见了的lose_file.txt文件,在上面执行完git fsck –lost-found命令,返回的第一行blob我们看看他的内容git show 7f5965523d2b9e850b39eb46e8e0f7c5755f6719my lose messagegit show 7f5965523d2b9e850b39eb46e8e0f7c5755f6719 > lose_file.txt$ lsREADME.md lose_file.txt need_stash.txt share_file.txt time.txt看到没有,就是我们丢失的文件内容,这样就找回来了! 我们再来看看commit tree的内容$ git cat-file -p fdbb19cf4c5177003ea6610afd35cda117a41109 tree 673f696143eb74ac5e82a46ca61438b2b2d3bbf4 parent e278392ccbf4361f27dc338c854c8a03daab8c49 parent 7b54a8ae74be7192586568c6e36dc5a813ff47cf author pzqu <pzqu@example.com> 1544951197 +0800 committer pzqu <pzqu@example.com> 1544951197 +0800 Merge branch ‘master’ of github.com:pzqu/git_test $ git ls-tree 3bd4c055afedc51df0326def49cf85af15994323 100644 blob c44be63b27a3ef835a0386a62ed168c91e680e87 share_file.txt用git cat-file -p可以看到commit的内容,可以选择把这个commit合并到我们的分支里,还是reset merge rebase cherry-pick这些命令来合commitgit ls-tree列出tree下面的文件名和id的记录信息,然后就可以根据这些来恢复文件了后记:如果你发现执行git fsck –lost-found的输出找不到你想要的,那么在执行完git fsck –lost-found后会出现一堆文件 在 .git/lost-found 文件夹里,我们不管他。可以用以下命令来输出近期修改的文件$ find .git/objects -type f | xargs ls -lt | sed 3q-r–r–r– 1 pzqu staff 32 12 23 12:19 .git/objects/7f/5965523d2b9e850b39eb46e8e0f7c5755f6719-r–r–r– 1 pzqu staff 15 12 23 01:51 .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391-r–r–r– 1 pzqu staff 162 12 23 00:51 .git/objects/35/b66ed8e3ae2c63cc4ebf323831e3b917d2b1d4$ git cat-file -t 7f5965523d2b9e850b39eb46e8e0f7c5755f6719blob$ git cat-file -p 7f5965523d2b9e850b39eb46e8e0f7c5755f6719my lose message$ git cat-file -t b2484b5ab58c5cb6ecd92dacc09b41b78e9b0001tree$ git cat-file -p b2484b5ab58c5cb6ecd92dacc09b41b78e9b0001100644 blob f9894f4195f4854cfc3e3c55960200adebbc3ac5 README.md100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 need_stash.txt100644 blob 83f50ec84c00f5935da8089bac192171cfda8621 share_file.txt100644 blob f0664bd6a49e268d3db47c508b08d865bc25f7bb time.txt这里用find .git/objects -type f | xargs ls -lt | sed 3q返回了近3个修改的文件,想要更多就改3q这个数值,比如你想输出100个就用100qgit cat-file -t 7f5965523d2b9e850b39eb46e8e0f7c5755f6719 就能看见文件类型 把最后一个/去掉 复制从objects/ 后面的所有东西放在-t后面git cat-file -p id就能看见文件内容,是不是很爽漏提交有时候会碰到我们已经commit但是有修改忘记了提交,想把他们放在刚刚的commit里面,这种时候怎么做呢?$ git log –name-status –pretty=oneline -135b66ed8e3ae2c63cc4ebf323831e3b917d2b1d4 (HEAD -> master, origin/master, origin/HEAD) []update time to 00:50M time.txt$ git statusOn branch masterYour branch is up to date with ‘origin/master’.Changes to be committed: (use “git reset HEAD <file>…” to unstage) new file: lose_file.txt new file: test_amend.txt $ git commit –amend –no-edit[master 31cc277] []update time to 00:50 Date: Sun Dec 23 00:51:54 2018 +0800 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 lose_file.txt create mode 100644 test_amend.txt $ git log –name-status –pretty=oneline -131cc2774f0668b5b7c049a404284b19e9b40dc5d (HEAD -> master) []update time to 00:50A lose_file.txtA test_amend.txtM time.txt查看文件提交日志只有time.txtstage里还有新的修改在使用git commit –amend –no-edit合并到上一个提交里,如果不加–no-edit参数的话,会提示你来修改commit提示信息(这个命令也可以用在重复编辑commit message)。查看日志,合并提交成功!tag标签创建一个tag标签是一个类似于快照的东西,常常用于测试和发布版本。所以我们常常把tag名以版本号来命名,比如:v1.0beat1这样我们怎么创建标签呢?首先先切换到想打标签的分支,然后直接打就可以了。$ git branch dev/pzqu master release_v1.0$ git tag -a release_v1.0 -m “release v1.0”$ git tag release_v1.1$ git tagrelease_v1.0release_v1.1$ git push –tagsCounting objects: 2, done.Writing objects: 100% (2/2), 158 bytes | 158.00 KiB/s, done.Total 2 (delta 0), reused 0 (delta 0)To github.com:pzqu/git_test.git * [new tag] release_v1.0 -> release_v1.0 * [new tag] release_v1.1 -> release_v1.1切换到想打tag的分支创建名为release_v1.0带有信息release v1.0的tag创建的不带有tag的提交信息的release_v1.1git tag查看tag推送本地全部tag也可以推送单个tag$ git push origin release_v1.1Total 0 (delta 0), reused 0 (delta 0)To github.com:pzqu/git_test.git * [new tag] release_v1.1 -> release_v1.1我们来删除tag$ git tag -d release_v1.0Deleted tag ‘release_v1.0’ (was eb5d177)$ git push origin :refs/tags/release_v1.0To github.com:pzqu/git_test.git - [deleted] release_v1.0$ git tagrelease_v1.1本地删除名为release_v1.0的tag远程删除名为release_v1.0的tag对历史提交打tag先看看当前的log31cc277 (HEAD -> release_v1.0, tag: release_v1.1, origin/release_v1.0, master) []update time to 00:50856a740 []update time to 18:513f22a06 [+]add file time.txt4558a25 (origin/dev/pzqu, dev/pzqu) []test stashd9e018e []merge master to dev/pzqu比方说要对[]update time to 18:51这次提交打标签,它对应的commit id是856a740,敲入命令:$ git tag v.9 856a740$ git log –pretty=oneline –abbrev-commit31cc277 (HEAD -> release_v1.0, tag: release_v1.1, origin/release_v1.0, master) []update time to 00:50856a740 (tag: v0.9) []update time to 18:51成功打上git忽略不想提交的文件我们有两种情况,一种是我们根本就不想这些文件出现在git库里比如日志文件;另一种是git远程仓库里有这些文件,就像通用的配置文件,我们必须要在本地修改配置来适应运行环境,这种情况下我们不想每次提交的时候都去跟踪这些文件。忽略自动生成的垃圾文件、中间文件、敏感信息文件忽略文件的原则是:忽略操作系统自动生成的文件,比如缩略图等;忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。我们要怎么做呢?在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。$ echo “.log” > .gitignore$ touch test.log$ touch test2.log$ ls -a . .git README.md need_stash.txt test.log test_amend.txt .. .gitignore lose_file.txt share_file.txt test2.log time.txt$ git status On branch release_v1.0 nothing to commit, working tree clean 创建并写入忽略规则*.log忽略全部以.log为后缀的文件 创建了test.log和test2.log * status查看,真是工作区是clean,新创建的文件没有被跟踪忽略远程存在,本地不想与远程同步的文件添加跟踪忽略核心命令:git update-index —assume-unchanged 文件名upload successful创建time.txt文件并写入10:41,提交到远程仓库使用命令git update-index —assume-unchanged加time.txt加到忽略名单里修改time.txt的内容为10:43status查看确实没有被跟踪 看远程仓库upload successful取消跟踪忽略核心命令:git update-index —no-assume-unchanged 文件名upload successfulpull同步远程仓库,真的没有更新刚刚被添加跟踪忽略的文件git update-index —no-assume-unchanged取消跟踪忽略status查看,出现文件的跟踪查看跟踪记录如果忘记了哪些文件被自己本地跟踪upload successful使用命令git update-index —assume-unchanged加time.txt加到忽略名单里使用git ls-files -v| grep ‘^h\ ‘命令可以看到小写h代表本地不跟踪的文件小结学完本文章,你将学会撤消commit,回滚暂存区,回滚工作区、回退远程仓库两种方法找回不小心丢失的文件提交的时候漏了文件,修改commit的提交信息tag操作,创建、创建有描述信息的tag、删除tag、删除远程tag、推送本地单个tag和全部taggit忽略自动生成的垃圾文件、中间文件、敏感信息文件;忽略远程存在,本地不想与远程同步的文件并恢复跟踪和查看哪些文件被跟踪注意事项理论上,git日常用到的命令是 diff show fetch rebase pull push checkout commit status 等,这些命令都不会导致代码丢失,假如害怕代码丢失,可以预先commit一次,再进行修改,但切记不可使用自己不熟悉的命令 任何命令,不要加上-f的强制参数,否则可能导致代码丢失建议多使用命令行,不要使用图形界面操作下集引用git官网廖雪峰的官方网站-git篇hexo博客部署到vps关于git reset –hard这个命令的惨痛教训Git 基础再学习之:git checkout – file如何理解git checkout – file和git reset HEAD – file此文已由腾讯云+社区在各渠道发布获取更多新鲜技术干货,可以关注我们腾讯云技术社区-云加社区官方号及知乎机构号 ...

March 8, 2019 · 6 min · jiezi

版本控制工具——Git常用操作(上)

本文由云+社区发表作者:工程师小熊摘要:用了很久的Git和svn,由于总是眼高手低,没能静下心来写这些程序员日常开发最常用的知识点。现在准备开一个专题,专门来总结一下版本控制工具,让我们从git开始。完成本系列博客的阅读以后,你将掌握git的基本概念与git的基本命令,可以在本地随心所欲的完成代码的提交撤销保存修改等操作、可以流畅的参与多人协作,本文致力于快速的入门,如果涉及到更高级的功能需要进行更深一步的学习。本文核心点:Git的基本概念一个人使用Git时的代码版本控制–(提交、拉代码、分支操作)多人合作时的代码版本控制–(合并冲突、暂存代码)什么是Git简介git是世界上目前最先进的分布式版本控制系统,致力于团队、个人进行项目版本管理,完美的解决难以比较代码、难以合并代码、难以取消修改、难以在写当前代码的过程中保存未完成的修改去修改线上版本的bug等的痛点。git是一个非常强大的工具,但作为一个git使用者来说,不用完全学习Git的知识点与命令,因为有的命令的使用频率非常的低甚至数年都不会用到,让我们来由浅入深进行学习。git的历史git是linux的创始人linus,在付费版本控制工具BitMover收回对Linux社区免费使用权利的时候,一怒之下花费两个星期的时间写出来的。(牛笔的人)开始安装git选择自己的操作系统对应的git版本安装,安装成功后运行git version后,输出git版本则安装正确。git 官方: https://git-scm.com/downloads配置用户信息使用git config命令来配置用户名和邮箱git config –global user.name “pzqu” git config –global user.email pzqu@example.com如果用了 –global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 –global选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。使用git config user.name和git config user.email来检查是否成功,也可以直接用git config –list来列出全部git配置信息来查看创建git托管的项目假如我们创建一个项目叫make_money,先创建一个文件夹叫make_money,再使用git init命令创建git项目。# pzqu @ pzqu-pc in ~/Documents/code/test [0:05:29]$ mkdir make_money# pzqu @ pzqu-pc in ~/Documents/code/test [0:06:24]$ lsmake_money# pzqu @ pzqu-pc in ~/Documents/code/test [0:06:29]$ cd make_money# pzqu @ pzqu-pc in ~/Documents/code/test/make_money [0:07:10]$ git initInitialized empty Git repository in /Users/pzqu/Documents/code/test/make_money/.git/# pzqu @ pzqu-pc in ~/Documents/code/test/make_money on git:master o [0:07:12]$ ls -altotal 0drwxr-xr-x 3 pzqu staff 96 11 7 00:07 .drwxr-xr-x 3 pzqu staff 96 11 7 00:06 ..drwxr-xr-x 9 pzqu staff 288 11 7 00:07 .git创建成功以后,会出现一个叫.git的隐藏文件夹,这个就是你的git仓库,以后所有的git操作历史提交记录信息就全部记录在此了,只要这个文件夹在就可以记住我们的全部git操作工作区和暂存区在使用git的时候还要清楚暂存区和工作区的含义,参考廖雪峰的官方网站-git篇-工作区和暂存区常见情况提交代码新文件与修改# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [11:37:50]$ lsREADME.md# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [11:42:02]$ touch file1.txt# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master x [11:42:15]$ git add file1.txt# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master x [11:42:23]$ git statusOn branch masterYour branch is up to date with ‘origin/master’.Changes to be committed: (use “git reset HEAD <file>…” to unstage) new file: file1.txt# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master x [11:56:38]$ git commit -m “[+]add new file1.txt”[master 66cc488] [+]add new file1.txt 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 file1.txt上图操作包含:创建新文件file1.txtadd 添加修改的内容到索引status 查看修改的内容commit 把索引提交到本地分支git add . :监控工作区的状态树,此命令会把工作时的所有变化提交到暂存区,包括文件内容修改(modified)以及新文件(new),但不包括被删除的文件。git add -u:他仅监控已经被add的文件(即tracked file),他会将被修改的文件提交到暂存区。add -u 不会提交新文件(untracked file)。(git add –update的缩写)git add -A :是上面两个功能的合集(git add –all的缩写)upload successfulgit show 列出最近一次的提交对于commit:像这样,你不断对文件进行修改,然后不断提交修改到版本库里,就好比玩RPG游戏时,每通过一关就会自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状态。有些时候,在打Boss之前,你会手动存盘,以便万一打Boss失败了,可以从最近的地方重新开始。Git也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。删除文件# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [12:55:24]$ lsREADME.md file1.txt# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [12:55:25]$ git rm file1.txtrm ‘file1.txt’# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master x [12:55:30]$ lsREADME.md# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master x [12:55:32]$ git statusOn branch masterYour branch is ahead of ‘origin/master’ by 1 commit. (use “git push” to publish your local commits)Changes to be committed: (use “git reset HEAD <file>…” to unstage) deleted: file1.txt# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master x [12:55:40] C:128$ git commit -m “[-]delete file1.txt”[master e278392] [-]delete file1.txt 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 file1.txt上图操作包含:创建新文件file1.txtgit rm 删除file1.txt文件status 查看修改的内容commit 把索引提交到本地分支tip1: 如果没有用git rm删除文件,在本地删除文件后,git add一下再提交可以达到同样的效果tip2: 要是你加班太晚,头晕不小心删除了不想删除的文件怎么办?见下一篇:版本控制工具——Git常用操作(下)-后悔药拉代码方法一 pull# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [17:01:13]$ git pullremote: Enumerating objects: 4, done.remote: Counting objects: 100% (4/4), done.remote: Compressing objects: 100% (2/2), done.remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0Unpacking objects: 100% (3/3), done.From github.com:pzqu/git_test 5fd4d8f..7b54a8a master -> origin/masterMerge made by the ‘recursive’ strategy. share_file.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 share_file.txt上图命令:git pull查看本地仓库变化git logupload successful上图可以看到向远程仓库pull的时候,出现了两个新的commit,commit 7b54a8ae74…的提交信息为Create share_file.txt,另一个commit fdbb19cf4c51770的提交信息为Merge branch ‘master’ of github.com:pzqu/git_test。事实上主线只有一个提交,为什么会出现这种情况? 是因为pull其实会做两个操作拉远程仓库代码到本地自动与当前分支合并并生成一个合并成功的提交注意这里的第二个个步骤如果远程有人和你改了同一个文件就会出现一个冲突,这个时候git会提示你哪些文件有冲突,手动改了再提交一次就可以了。详情见合并冲突方法二 fetch我在远程修改了文件,向share_file.txt加了一行内容tom modify,此时拉代码。# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [21:07:21]$ git fetch# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [21:08:43]$ git rebase origin/masterFirst, rewinding head to replay your work on top of it…Applying: [+]add new file1.txtApplying: [-]delete file1.txt上图所示有以下两个操作fetch 拉取远端代码到本地rebase 把本地代码提交基于远端分支重新replay效果如下:upload successful上图是git log所输出的提交内容,刚刚pull的时候忘记把pull自动产生的merge提交到远程,rebase的时候把本地的提交放到了远程提交之后,看起来就是一条直线,比较优雅,也是推荐的方式。同样的,如果产生了冲突,详情见合并冲突分支操作创建分支分支是多人协同最经典的地方所在,我们来创建一个分支$ git checkout -b dev/pzqu origin/masterBranch ‘dev/pzqu’ set up to track remote branch ‘master’ from ‘origin’.Switched to a new branch ‘dev/pzqu’$ git branch* dev/pzqu mastergit checkout -b 分支名 其他分支,-b代表创建并切换到新建的分支,分支名代表新创建的分支叫什么名字,这里叫dev/pzqu ,其他分支代表基于哪一个分支来创建,这里基于远程的master分支origin/master,如果省略则代表基于当前分支git branch展示本地的分支情况,加-a参数可以展示全部的分支,包括远程分支在分支前,指明了现在所在的分支是dev/pzqu切换分支$ git checkout -b dev/pzqu2Switched to a new branch ‘dev/pzqu2’$ git branch dev/pzqu dev/pzqu2 master$ git checkout dev/pzquSwitched to branch ‘dev/pzqu’Your branch is up to date with ‘origin/master’.$ git branch* dev/pzqu dev/pzqu2 master基于当前分支创建了一个新的分支并自动切换过去dev/pzqu2git checkout 已存在的分支名切换分支回到dev/pzqu删除分支$ git branch* dev/pzqu dev/pzqu2 master $ git branch -D dev/pzqu2Deleted branch dev/pzqu2 (was 7c9be37).$ git branch* dev/pzqu master 位于dev/pzqu,删除了dev/pzqu2分支合并冲突合并同一个分支的冲突(常见)为了产生一个冲突,我在另一个地方向远程仓库提交了代码,更改share_file.txt文件,加了一行内容tom add for merge,本地修改同一个文件加了一行pzqu add for merge,并提交到本地,这样一来,本地和远程仓库的同一个文件就不一样了,一会拉代码一定会产生一个冲突。效果如下:upload successful一般rebase或pull冲突的时候,都会出现提示,然后git status会出现上图图示这个时候不可以进行任何分支切换和commit操作,按照他提示进行处理git status提示哪个文件是都被修改的,both modified,然后使用编辑器修改该文件,解决冲突解决完成后,git add 添加该冲突文件git rebase –continue,并更新commit message,完成整个rebase流程 我们来看看这个冲突的文件:upload successfulGit用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,我们修改如下后保存:upload successfulgit add再git rebase –continue后完成rebase,效果如下,再push的远程仓库即可upload successful合并不同分支的代码产生冲突关于怎么创建分支与切换分支见创建分支和切换分支,这里只讨论合并时产生的冲突的情况,我们已经基于master分支创建了一个dev/pzqu分支$ git branch* dev/pzqu master切换到master分支,加一行master add for merge并提交,文件内容如下:$ cat share_file.txttom addtom modifytom add for mergepzqu add for mergemaster add for merge切换到dev/pzqu分支,向share_file.txt加入一行dev/pzqu add for merge并提交,现在share_file.txt内容如下:$ cat share_file.txttom addtom modifytom add for mergepzqu add for mergedev/pzqu add for merge现在两个分支的同一个文件内容不一样了,现在我们在dev/pzqu分支上进行合并:$ git merge masterAuto-merging share_file.txtCONFLICT (content): Merge conflict in share_file.txtAutomatic merge failed; fix conflicts and then commit the result.# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:dev/pzqu x [11:17:31] C:1$ git statusOn branch dev/pzquYour branch is ahead of ‘origin/master’ by 1 commit. (use “git push” to publish your local commits)You have unmerged paths. (fix conflicts and run “git commit”) (use “git merge –abort” to abort the merge)Unmerged paths: (use “git add <file>…” to mark resolution) both modified: share_file.txtno changes added to commit (use “git add” and/or “git commit -a”)$ cat share_file.txttom addtom modifytom add for mergepzqu add for merge<<<<<<< HEADdev/pzqu add for merge=======master add for merge>>>>>>> master上图出现了一个冲突,是我们意料之中的,修改share_file.txt文件,解决此冲突:$ cat share_file.txttom addtom modifytom add for mergepzqu add for mergedev/pzqu add for mergemaster add for merge$ git add share_file.txt# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:dev/pzqu x [11:22:40]$ git commit -m “[]merge master to dev/pzqu”[dev/pzqu d9e018e] []merge master to dev/pzqu# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:dev/pzqu o [11:23:00]$ git statusOn branch dev/pzquYour branch is ahead of ‘origin/master’ by 3 commits. (use “git push” to publish your local commits)nothing to commit, working tree clean冲突解决也提交了,看看我们现在的分支内容:upload successful上图我们可以看到:master分支比远程origin/master分支多一次提交,dev/pzqu分支由于是基于origin/master分支,合并了master分支的提交和当前dev/pzqu分支的提交,超出本地master两个提交,致此我们把master合并到dev/pzqu的操作就完成了。通常我们开一个新的开发分支是为了在自己的分支上写代码,方便提交也不会把主线弄乱,现在我们用同样的方法将dev/pzqu合并到master分支,然后把两个分支都提交到远程。$ git checkout masterSwitched to branch ‘master’Your branch is ahead of ‘origin/master’ by 1 commit. (use “git push” to publish your local commits)$ git merge dev/pzquUpdating 58f047a..d9e018eFast-forward share_file.txt | 1 + 1 file changed, 1 insertion(+)$ git push origin masterTotal 0 (delta 0), reused 0 (delta 0)To github.com:pzqu/git_test.git 7c9be37..d9e018e master -> master $ git push origin dev/pzquCounting objects: 9, done.Delta compression using up to 8 threads.Compressing objects: 100% (9/9), done.Writing objects: 100% (9/9), 887 bytes | 887.00 KiB/s, done.Total 9 (delta 2), reused 0 (delta 0)remote: Resolving deltas: 100% (2/2), done.remote:remote: Create a pull request for ‘dev/pzqu’ on GitHub by visiting:remote: https://github.com/pzqu/git_test/pull/new/dev/pzquremote:To github.com:pzqu/git_test.git * [new branch] dev/pzqu -> dev/pzqu切换到master分支合并dev/pzqu到master分支master推到远程仓库如果dev/pzqu要保留,就可以推送到远程仓库。upload successful现在我们可以看到全部的分支都在一起了,强迫症都舒服了。暂存代码保存现场这种情况一般是出现在你正在完成一个功能,但是忽然线上发现了一个Bug,必须马上开一个新的分支来修复bug,但是现在的功能没写完不打算提交(commit),现在怎么办??不用怕暂存代码来帮助你。$ git statusOn branch dev/pzquYour branch is up to date with ‘origin/master’.Changes to be committed: (use “git reset HEAD <file>…” to unstage) new file: need_stash.txt modified: share_file.txt$ git stashSaved working directory and index state WIP on dev/pzqu: d9e018e []merge master to dev/pzqu$ git stash liststash@{0}: WIP on dev/pzqu: d9e018e []merge master to dev/pzqu$ git statusOn branch dev/pzquYour branch is up to date with ‘origin/master’.nothing to commit, working tree clean//省略操作:去创建一个Bug分支,修复他并完成与主线的合并,删除Bug分支。//省略操作:切回来当前分支继续开发//下面来恢复现场$ git stash apply stash@{0}On branch dev/pzquYour branch is up to date with ‘origin/master’.Changes to be committed: (use “git reset HEAD <file>…” to unstage) new file: need_stash.txtChanges not staged for commit: (use “git add <file>…” to update what will be committed) (use “git checkout – <file>…” to discard changes in working directory) modified: share_file.txtstatus查看到有2个文件修改没有提交stash把修改放到暂存区,并生成一个idstash list列出暂存区所有内容stash apply重新把暂存区内容放到本地这里的stash apply成功的把暂存区的一次暂存恢复到了本地,但是暂存区还有会保存这次暂存,如果想删除这次暂存要用git stash drop来删除;也可以用git stash pop,恢复最后一次暂存的同时把stash内容也删了。$ git stash drop stash@{0}Dropped stash@{0} (bfdc065df8adc44c8b69fa6826e75c5991e6cad0)$ git stash list好了,暂存区清干净了。 注意:要放到暂存区的文件一定要先通过git add加到index小结本文阅读结束以后,我们学会了Git的基本概念,知道git的作用、历史;学会安装配置Git,使用Git创建项目托管以及工作区和暂存区的概念学会Git的本地操作,提交、拉代码、创建切换删除分支操作,多人合作时的代码版本控制,学会了不同情况下的合并冲突、暂存代码操作下集预告Git常用操作(下)我计划给大家介绍以下点:后悔药-各种后悔操作(撤消commit,回滚,回退远程仓库等)哎呀,提交的时候漏了文件tag操作git忽略不想提交的文件注意事项理论上,git日常用到的命令是 diff show fetch rebase pull push checkout commit status 等,这些命令都不会导致代码丢失,假如害怕代码丢失,可以预先commit一次,再进行修改,但切记不可使用自己不熟悉的命令 任何命令,不要加上-f的强制参数,否则可能导致代码丢失建议多使用命令行,不要使用图形界面操作引用git官网廖雪峰的官方网站-git篇hexo博客部署到vps此文已由腾讯云+社区在各渠道发布获取更多新鲜技术干货,可以关注我们腾讯云技术社区-云加社区官方号及知乎机构号 ...

March 8, 2019 · 5 min · jiezi

5分钟入门git模式开发

本文由云+社区发表作者:唐维黎导语基于gui工具TortoiseGit让你快速进入git开发模式。目前项目已逐步从svn移步到git开发模式,其中也针对git统一协议了适合git的开发规范, 最重要一点就是分支模型的,为了规范开发,不直接在主干上修改代码,一切代码都提交至分支dev,然后再由分支合并到主干master。 首先保证每个仓库下有以下两个常驻分支(永远不删除的分支): master:主干分支,始终保持跟外网服务器一致,只用于外网发布,这样就可以保证文件不会带出去的风险; dev:基于master创建,用于开发新功能和新需求的分支。开发流程如下:1. 基于dev分支创建dev-xxx分支,开始进行普通的常规需求开发,开发完成后,Commit提交代码到本地仓库,如果这个新项目或者功能比较大有多人协同开发,怕会相互影响对方的代码,现从dev-xxx分支创建新分支dev-xxx-user进行开发,前提是dev-xxx分支需要push到线上;2. 开发完成后将dev-xxx分支合并到dev分支,然后部署dev到测试环境进行测试,测试过程中有bug的话修复完后同样合并到dev分支。如果是在多人协同开发的情况下先将dev-xxx-user分支合并到dev-xxx,再将dev-xxx合并到dev分支;3. 测试完成后,将dev分支合并到master分支,然后进行正式发布。发布完成后删除dev-xxx和dev-xxx-user分支; 如果担心在最后一步合并代码到master时有问题,也可以在测试的时候随时更新到本地master(先checkout master分支到本地),但不要push到线上,本地master 如果一定push到线上的话,这就要保证你的需求未测试发布前,别人不会发master与你相关的文件另外,如果是外网BUG或者日常,就可以在master上直接创建分支,修复完成后发布,定时同步dev分支,这样可以提高效率 ~ 下面以一个简单的需求来实际操作下,看看TortoiseGit的使用方法: (前提本地是有安装git和TortoiseGit)1. 克隆代码仓库到本地在指定文件夹下,右键 -> Git Clone.. 点确定后会提示你输入用户名和密码,这个跟svn类似 然后等待一会代码就成功克隆到本地了,速度比svn要快很多,另外也可以直接用命令行的方式git clone XXXXX.git代码克隆后,后续分支都是在本地的同一份代码上进行分支创建,而无需再次克隆2. 创建本地分支创建分支前请实时git pull线上仓库到本地,保证本地dev是最新 进入刚克隆下来的目录,右键 -> TortoiseGit -> Create Branch..3. 查看及切换当前分支右键 -> TortoiseGit -> Switch/Checkout… 切换成功后,可通过Git bash查看是否真的切换过来 也可以在命令行直接git branch查看,高亮的为当前分支 重要:注意在开发的时候请保证当前自己所修改的代码是当前需求的分支4. 开发完成后Commit右键 Git Commit -> ‘dev-xxx’ 提交记录一定要填 ,其它信息可选Commit到本地仓库,Commit这里也可以直接一次性push到线上仓库,但一般情况下不会这么干, 在多人协作的时候,其他人要合并代码到dev-xxx分支时可以直接一键commit+push5. 合并分支首先切换到要合并的目标分支(切换分支见上述3),本次要将dev-xxx合并到dev分支,我们切换到dev分支, 右键 -> TortoiseGit -> Merge…6. 提交到线上仓库右键 -> TortoiseGit -> Push…会要求你输入用户名和密码 提交成功后,提单部署测试环境7. 合并到master主干分支测试通过并完成后,将dev分支合并到master并push到线上仓库,提单发布外网, 合并到master的时候,可以将线上的master分支checkout到本地,然后进行本地的dev和master合并,再push到线上, 也可以直接将本地dev直接合并到线上master(remotes/origin/master)分支,本地合并冲突比较好解决,也不会影响线上。到此本次需求完成此文已由腾讯云+社区在各渠道发布获取更多新鲜技术干货,可以关注我们腾讯云技术社区-云加社区官方号及知乎机构号

February 15, 2019 · 1 min · jiezi

想晋级高级工程师只知道表面是不够的!Git内部原理介绍

本文由云+社区发表作者:腾讯工蜂用户:王二卫从不一样的视角了解git,以便更好的使用git一、git & git 版本库认识git 是一个内容寻址的文件系统,其核心部分是一个简单的键值对数据库(key-value data store),可以向该数据库插入任意类型的内容,它会返回一个40位长的哈希键值。并在此基础上提供了一个版本控制系统的用户界面。git 版本库其实只是一个简单的数据库,其中包含所有用来维护与管理项目的修订版本和历史信息。其不同于subversion,git版本库不仅提供版本库中所有文件的完整副本,还提供版本库本身的副本。在git版本库中,git维护两个主要数据结构:对象库(object store),索引(index)。从整体来看,一个项目的git仓库,就如一张带节点的渔网(该渔网是一张有向网),随着项目的不断推进,该渔网也将不断的向四周扩散。渔网上的节点就像一个个的提交,从某一个正常的节点都能漫游至项目最开始的起点。而分支就如该网上不同节点上的一个特殊标记,分支的演变就是该标记不断的移至其他节点。 分支的合并,根据合并方式的不同,使得这一张网的交叉紧密度越来越高。1.1git对象类型对象库是git版本库实现的心脏,包含四种类型:块(blob,binary lare object),文件的每一个版本表示为一个块。一个blob被视为一个存储任意数据,且内部结构被程序忽略的变量或文件的黑盒。一个blob保存一个文件的数据,但不包含任何关于这个文件的元数据(Metadata,描述数据的数据)。目录树(tree), 一个目录树对象代表一层目录信息。它记录blob标识符、路径名和在一个目录里所有文件的一的元数据。它也可以递归引用其他目录树或子树对象,从而建立一个包含文件和子目录的完整层次结构。提交(commit),一个提交对象保存版本库中每一次变化的元数据,每一个提交对象指向一个目录树对象,这个树对象在一张完整的快照中补货提交时版本库的状态。标签(tag) ,一个标签对象分配一个可读的名字给一个特定的对象,通常是一个提交对象。为了有效的利用磁盘空间和网络带宽名,git把对象压缩并存储在打包文件(pack file)里,这些文件也在对象库里。1.2索引索引是一个临时的、动态的二进制文件,不包含任何文件内容,它仅仅追踪你想要提交的那些内容。使得开发的推进与提交的变更之间能够分离开来。1.3引用引用(ref)是一个保存SHA-1值的文件,该文件的名字指针来替代原始的SHA-1值,一般指向提交对象。本地分支名称、远程跟踪分支名称和标签名都是引用。.git/refs.git/refs/heads.git/refs/tags1.3.1 创建一个引用$ echo “1a410efbd13591db07496601ebc7a059dd55cfe9” > .git/refs/heads/master现在可以通过新建的引用来代替SHA-1的值: $ git log —pretty=oneline master 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit cac0cab538b970a37ea1e769cbbde608743bc96d second commit fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit不提倡直接编辑引用文件,可以通过update-ref更新某个引用 $ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9比如新建一个分支(git分支的本质:一个指向某一系列提交之首的指针或引用) $git update-ref refs/heads/feature-zhangsan cac0ca1.3.2 符号引用符号引用(symbolic reference),间接指向git对象,其实际也是一个引用,不像普通引用那样包含一个SHA-1值,它是一个指向其他引用的指针。 git自动维护几个用于特定目的的特殊符号引用,这些引用可以在使用提交的任何地方使用。HEAD 始终指向当前分支的最近提交,不像普通引用那样包含一个 如: $ cat .git/HEAD ref: refs/heads/master若执行 $ git checkout test,git会这样更新HEAD文件 ref:refs/heads/testORIG_HEAD 某些操作(如:merge、reset),会把调整为新值之前的先前版本的HEAD记录到OERG_HEAD中,只用其可以恢复或回滚之前的状态或做个比较FETCH_HEAD git fech命令将所有抓取分支的头记录到.git/FETCH_HEAD中MERGEHEAD 正在合并进HEAD的提交1.3.3 远程引用如果你添加了一个远程版本库并对其执行过推送操作,Git 会记录下最近一次推送操作时每一个分支所对应的值,并保存在 refs/remotes 目录下。 如:$cat .git/refs/remotes/origin/master ca82a6dff817ec66f44342007202690a93763949 发现添加的远程origin远程库的master分支锁对应的SHA-1值,就是最近一次与服务器通信时master分支所对应的SHA-1值。 远程引用和分支(位于 refs/heads 目录下的引用)之间最主要的区别在于,远程引用是只读的。 虽然可以git checkout 到某个远程引用,但是 Git 并不会将 HEAD 引用指向该远程引用。 因此,你永远不能通过commit 命令来更新远程引用。 Git 将这些远程引用作为记录远程服务器上各分支最后已知位置状态的书签来管理。二、git底层命令cat-file 展示git仓库对象实体的类型、大小和内容ls-remote 显示远程库信息ls-files 显示由工作目录中添加到缓存中的文件的相关信息ls-tree 列出树对象内容read-tree 将给出的树写入索引但不写入缓存write-tree 按照索引区内容创建树对象symbolic-ref 同步引用信息update-index 更新树对象内容至索引三、.git 结构说明HEAD 指示目前被检出的分支index 保存暂存区信息config* 包含项目特有的配置选项description 仅供gitweb程序使用,用户一般不需要关注。hooks 包含客户端和服务端的钩子info 包含全局排除(global excude)文件,存放那些不希望被记录在.gitignore中的忽略模式objects 存储所有数据内容refs 存储指向数据(分支)的提交对象的指针四、git 版本演变准备工作:创建一个没有任何文件的git初始库 $ git init test Initialized empty Git repository in /data/work/test/test/.git/4.1 git数据存储演示hash-object 存储任意类型数据至数据库,并返回hash 键值$ echo ‘test conten’ | git hash-object -w —stdind670460b4b4aece5915caf5c68d12f560a9fe3e4 -w 执行写入数据库操作,若不指定该选项,只会返回hash,不会写入数据库。 –stdin 标准输入输出读取 默认存入是blob类型,通过-t 参数指定$ find .git/objects/ -type f .git/objects//d6/870460b4b4aece5915caf5c68d12f560a9fe3e4一个文件对应一条内容,这个内容的名称以该文件内容加上特定头部信息一起的sha-1校验和。头部信息-对象类型(blob或tree或commit)+一个空格+数据内容长度+一个空字节 git 会通过zlib将文件内容和头部信息拼接一起的内容进行压缩写入磁盘某个对象,并用计算出的sha-1值的前两个字符串作为目录名称,后38个字符串作为子目录内文件的名称。$ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4test content4.2 简单版本控制演示4.2.1 创建初始版本$ echo ‘version 1’ > test.txt$ git hash-object -w ./test.txt 83baae61804e65cc73a7201a7252750c76066a304.2.2 更新版本$ echo ‘version 2’ > test.txt$ git hash-object -w ./test.txt 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a此时数据库已经存储了test.txt两个不同的版本,如下:$ find .git/objects/ -type f .git/objects//1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a .git/objects//83/baae61804e65cc73a7201a7252750c76066a30可以通过cat-file -p查看内容,以上都是数据(blob)对象。可以使用 cat-file -t查看。4.3 树对象引入树对像(tree object) 解决文件名和目录保存问题。一个树对象包含了一条或多条树对象记录,每条记录包含一个指向数据对象或子树对象的sha-1指针,以及相应的模式/类型/文件信息。如下所示:$ git cat-file -p master^{tree}100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README 100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile 040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib$ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 100644 blob 47c6340d6459e05787f644c2447d2595f5d3a54b simplegit.rbmaster^{tree}指向master分支最新提交所指的树对象。 数据对象几种类型100644: 表示一般文件100755: 表示可执行文件120000: 表示 指针—add: 将未跟踪文件加入缓存区—cacheinfo 将数据对象文件加入工作区4.3.1 将文件加入暂存区$ git update-index —add —cacheinfo 100644 83baae61804e65cc73a7201a7252750c76066a30 test.txt4.3.2 生成树对象创建第一个树 $ git write-tree 将暂存区内容生成一个树对象,并输出树对象SHA-1 d8329fc1cc938780ffdd9f94e0d364e0ea74f5794.3.3 演变一个复杂的树$ echo ‘new file’ > new.txt$echo ‘test file2’ > test.txt$git update-index —cacheinfo 100644 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt$ git update-index test.txt$ git update-index —add new.txt创建第二个树$ git write-tree 0155eb4229851634a0f03eb265b69f5a2d56f341$ git cat-file -p 0155eb4229851634a0f03eb265b69f5a2d56f341 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt 100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt此时发现,第一个树丢了,并没有跟第一个树有关系,通过 read-tree进行链接 $ git read-tree —prefix=bak d8329fc1cc938780ffdd9f94e0d364e0ea74f579$ git write-tree 3c4e9cd789d88d8d89c1073707c3585e41b0e614$ git cat-file -p 3c4e9cd789d88d8d89c1073707c3585e41b0e614 040000 tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579 bak 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt 100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt4.3.4 查看我们生成的树4.4 提交对象引入通过commit对象将这些树对象串起来。 创建第一个提交 $ echo ‘first commit’ | git commit-tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579 fdf4fc3344e67ab068f836878b6c4951e3b15f3d创建第二个提交 $ echo ‘second commit’ | git commit-tree 0155eb -p fdf4fc3 cac0cab538b970a37ea1e769cbbde608743bc96d创建第三个提交 $ echo ‘third commit’ | git commit-tree 3c4e9c -p cac0cab 1a410efbd13591db07496601ebc7a059dd55cfe9版本库目录变化**$ find .git/objects -type f** .git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # tree 2 .git/objects/1a/410efbd13591db07496601ebc7a059dd55cfe9 # commit 3 .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a # test.txt v2 .git/objects/3c/4e9cd789d88d8d89c1073707c3585e41b0e614 # tree 3 .git/objects/83/baae61804e65cc73a7201a7252750c76066a30 # test.txt v1 .git/objects/ca/c0cab538b970a37ea1e769cbbde608743bc96d # commit 2 .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 # ‘test content’ .git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 # tree 1 .git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 # new.txt .git/objects/fd/f4fc3344e67ab068f836878b6c4951e3b15f3d # commit 1提交版本图没有执行read-tree$ git log –stat 92387commit 923879712b02f980a2edbe1cee315d883ee72503Author: erweiwang <erweiwang@tencent.com>Date: Tue Jul 17 15:55:53 2018 +0800 second commit new.txt | 1 + test.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)commit e624badd39a25484a08ae74231be65ea50a0fe32Author: erweiwang <erweiwang@tencent.com>Date: Tue Jul 17 15:54:20 2018 +0800 first commit test.txt | 1 + 1 file changed, 1 insertion(+)五、包文件Git 最初向磁盘中存储对象时所使用的格式被称为“松散(loose)”对象格式。 但是,Git 会时不时地将多个这些对象打包成一个称为“包文件(packfile)”的二进制文件,以节省空间和提高效率。 当版本库中有太多的松散对象,或者你手动执行 git gc 命令,或者你向远程服务器执行推送时,Git都会这样做。git 打包对象时,会查找命名及大小相近的文件,并只保存文件不同版本之间的差异内容和文件最新版本的完整内容。六、引用规格引用规格的格式由一个可选的 + 号和紧随其后的 : 组成,其中 是一个模式(pattern),代表远程版本库中的引用; 是那些远程引用在本地所对应的位置。 + 号告诉 Git 即使在不能快进的情况下也要(强制)更新引用。[remote “origin”] url = https://github.com/schacon/simplegit-progit fetch = +refs/heads/*:refs/remotes/origin/如果想让git每次只拉取远程master分支,而不是所有分支,可以将引用规格那一行修改为: fetch = +refs/heads/master:refs/remotes/origin/master七、git clone代码库过程执行git clone后,拉取info/refs文件 => GET info/refs ca82a6dff817ec66f44342007202690a93763949 refs/heads/master确定HEAD引用,明确检出至工作目录的内容 => GET HEAD ref: refs/heads/master 以上说明完成抓取后需要检出master分支从info/refs文件中所提到的ca82a6提交对象开始 => GET objects/ca/82a6dff817ec66f44342007202690a93763949 (179 bytes of binary data)根据ca82a6提取的的父提交对象和树对象开始遍历整个完整版本库。在遍历过程中,若是未能直接找到(非松散对象)某些对象,会去替代版本库或某个包文件获取。八、git推送远端库过程为了上传数据至远端,Git 使用 send-pack 和 receive-pack 进程。 运行在客户端上的 send-pack 进程连接到远端运行的 receive-pack 进程。九、扩展知识9.1维护git gc —auto //整理松散对象并放置包文件,将多个包文件合并为一个大的包文件,移除与任何提交不相关的陈旧对象9.2数据恢复确定需要恢复的版本 git reflog 查看git默默记录的每一次你改变的HEAD的值。 git log -g 可以详细的查看引用日志中各个版本的信息,风方便确定要恢复的提交。 如下所示 commit 1a410efbd13591db07496601ebc7a059dd55cfe9 Reflog: HEAD@{0} Reflog message: updating HEAD third commit commit ab1afef80fac8e34258ff41fc1b867c702daa24b Reflog: HEAD@{1} Reflog message: updating HEAD modified repo.rb a bit创建用于恢复的临时分支$ git branch recover-branch ab1afef通过git fsck检查数据库的完整性(当reflog 也不存在需要恢复的版本)当引用日志所在目录.git/logs/ 被不小心清空时$ git fsck —full Checking object directories: 100% (256/256), done. Checking objects: 100% (18/18), done. dangling blob d670460b4b4aece5915caf5c68d12f560a9fe3e4 dangling commit ab1afef80fac8e34258ff41fc1b867c702daa24b dangling tree aea790b9a58f6cf6f2804eeac9f0abbe9631e4c9 dangling blob 7108f7ecb345ee9d0084193f147cdad4d29982939.3移除对象该操作使用须谨慎,会导致提交历史不被重写。应用场景,必须对已上库的某些文件(因文件太大或保密信息)进行彻底移除可以使用。定位出问题文件名 保密文件一般是已知的,若是误提交的文件较大需要删除,但又不知道是哪些文件,且又执行过git gc可以通过类似以下命令定位: $ git verify-pack -v .git/objects/pack-29…69 .idx | sort -k 3 -n | tail -3* dadf7258d699da2c8d89b09ef6670edb7d5f91b4 commit 229 159 12 033b4468fa6b2a9547a70d88d1bbe8bf3f9ed0d5 blob 22044 5792 4977696 82c99a3e86bb1267b236a4b6eff7868d97489af1 blob 4975916 4976258 1438 $ git rev-list —objects —all | grep 82c99a3 82c99a3e86bb1267b236a4b6eff7868d97489af1 git.tgz从过去所有树中移除这个文件 查看哪些提交对这个文件做过改动 $ git log —oneline —branches — git.tgz dadf725 oops - removed large tarball 7b30847 add git tarball 从7b30847之后的所有提交历史中完全移除该文件 $ git filter-branch —index-fileter ‘git rm —ignore-unmatch —cached git.tgz’ — 7b30847^… Rewrite 7b30847d080183a1ab7d18fb202473b3096e9f34 (1/2)rm ‘git.tgz’ Rewrite dadf7258d699da2c8d89b09ef6670edb7d5f91b4 (2/2) Ref ‘refs/heads/master’ was rewritten –index-filter 只修改暂存区或索引中的文件 –cached 需要从索引中移除,使得在运行过滤器是,并不会将每个修订版本检出到磁盘 –ignore-unmatch 如果尝试删除的模式不存在时,不提示错误 filter-branch 用于指定从那个提交以来的历史重新打包日志 执行上面操作,本地历史不在包含那个文件的引用,但是,引用日志和 .git/refs/original 通过 filterbranch选项添加的新引用中还存有对这个文件的引用,必须移除它们后重新打包数据库。 $ rm -Rf .git/refs/original $ rm -Rf .git/logs/ $ git gc彻底移除$ git prune –expire now $ git count-objects -v此文已由腾讯云+社区在各渠道发布获取更多新鲜技术干货,可以关注我们腾讯云技术社区-云加社区官方号及知乎机构号 ...

January 18, 2019 · 4 min · jiezi

如何在GitHub上大显身手?

推荐一篇良许大佬的文章,如何在github上大显身手。拥有自己的github,且有所贡献,这是一件很有意义的的事情,在面试上也是加分项哦,赶紧搞起来。转载至http://uee.me/aHAfN这推荐一个网站,收集了有趣、入门级的开源项目:https://hellogithub.com/码农朋友们都知道,gitHub是一个面向开源及私有软件项目的托管平台,上面托管了众多的优秀的项目,比如linux内核源码、git源码、机器学习框架tensorflow等等。当然,除了这些顶尖项目外,还有海量的高手开发的优秀项目。所有的这些项目,我们都可以为它贡献代码。那么,要如何为这些项目贡献代码呢?我们下面以实例来讲解。比如说,现在gitHub上有个很牛逼的项目githubTest,它的作者是Alvin,项目地址如下:https://github.com/yychuyu/githubTest现在Harry看到了这个项目,想要对它进行贡献代码。想要达到这个目的,Harry要完成下图的这些步骤:1. forkHarry在找到这个项目之后,点击右上角的「fork」按钮。稍等片刻后,就会在Harry的账号下克隆了一个一样的项目githubTest,包括文件,提交历史,issues,和其余一些东西。2. clone通过fork之后,Harry的账号下也有了githubTest这个项目,但还不能对它进行编译、修改(其实是可以修改,但是不建议)。这时,可以通过git clone命令,将这个项目clone到自己的电脑里。3. update a file & 4. commit接下来,Harry就可以大显身手了,可以自由对这个项目进行修改。但是,不建议在master分支直接修改,建议在master分支基础上切出一个dev分支,然后在dev分支上自由发挥。修改完之后,再将dev分支merge到master分支。5. push在自己的电脑上修改好代码之后,再使用git push命令将改动同步到自己的gitHub项目仓库里。通过这个操作后,就可以在代码仓库里看到自己的提交了。6. pull request接下来,就是向原作者Alvin提交你的代码了。首先点击文件列表上的「New pull request」。之后,gitHub会自动对源仓库分支及自己仓库分支代码进行比对,看看是否有冲突。如果它显示「Able to merge」的话,Harry就可以点击下面的「Create pull request」绿色按钮,进行代码提交。再之后,系统会要求你写一段注释,其实也可不写。但最好写一下,跟作者说明一下你改动了什么,为啥这么改。通过以上6步,原作者Alvin就会收到一个pull request,如下图:然后,Alvin可以点进去,看看Harry具体提交了一些什么修改。如果他觉得这个修改确实够niubility的话,它就可以点击「merge pull request」,将Harry的提交集成到自己的项目里。[图片上传中…(image-19e584-1547014948798-10)]至此,功德圆满,Harry顺利完成一次对项目githubTest的代码贡献。但是,这个项目实在太出众了,很多高手看到了并贡献了众多代码。比如现在Alvin自己提交了一个文件:现在原作者项目已经发生了改变,那Harry账号下的githubTest如何与原作者Alvin的项目保持同步呢?Harry需要做以下三步操作:1. fetch现在代码不同步了,我们要先把Alvin仓库的代码fetch到自己电脑的仓库下。注意,这是在自己电脑上操作,不是在github上操作。git fetch git@github.com:yychuyu/githubTest.git master:latest上面这条命令,git fetch 之后 的那部分,是原作者Alvin项目git地址,通过点击原项目「clone or download」按钮可以看到。再之后master:latest这部分,master是原项目分支,latest是自己项目分支。如果latest分支不存在的话,将自动创建。其实也可以将代码fetch到自己的master分支,但也不建议这么做。2. merge代码fetch到latest分支之后,再切到master分支,再使用git merge命令将最新代码合并到master分支。3. push现在,Harry电脑上的代码与原项目代码保持同步了。我们再使用git push命令,就可以将最新代码推到Harry账号下githubTest项目里以上的三个步骤具体操作过程如下图示。接下来,Harry就可以在此基础上,继续贡献自己的代码了。推荐阅读: IDEA热部署插件JRebel「 神器 」强大的系统清理工具 THANDKSEnd -一个立志成大腿而每天努力奋斗的年轻人伴学习伴成长,成长之路你并不孤单!

January 9, 2019 · 1 min · jiezi