代码管理工具-Git基础介绍及常用技巧
前言:本文主要介绍git的原理、使用和一些技巧,目的在于使读者对git的了解不仅仅局限于简单的使用push、pull命令,而要做到知其然且知其所以然。当然,本文并不会深入去探讨诸如git的实现原理之类的深层次东西,毕竟它只是一个代码管理工具罢了,作为使用者,我们只要达到真正熟练使用的地步就够了,至于更深层次的东西,诸位有兴趣的可以自行学习研究。
另外,本文分支相关图片取自learngitbranching,这是个用游戏的方式,图文结合学习git分支的网站,相当nice,推荐大家去完整过一遍,相信对于git的理解会更上一层楼。
Git起源
git是由Linux的作者Linus花两周时间写出的分布式版本控制软件。在这之前,Linux社区使用BitKeeper作为版本控制系统,但是由于社区中有人试图破解BitKeeper的协议,这惹恼了BitKeeper的东家BitMover公司,于是BitMover决定收回linux社区的免费使用权。
在这样的背景下,Linus花了两周时间写出了git,在一个月内替换了BitKeeper,作为Linux的版本控制工具,并在后面不断完善,最终成为了现在代码版本控制的首选
基本概念
三种工作域:
- git目录(git direcdtory):即仓库(Repository),保存项目中所有版本和相关信息,是git存放数据和信息的地方
- 工作目录(work directory): 是对应项目的某个版本的文件集合,对应从 git 目录中解压出来的供用户进行操作和修改的数据和信息
- 暂存目录(staging area):用于记录下次commit时需要保存的文件列表
三种文件状态:
- committed:已提交状态,表示数据文件已经被保存至本地数据仓库中。
- modified:修改状态,表示文件已被修改,但是尚未被提交(保存)。
- staged:暂存状态,表示是被标记了的被修改文件,在下次提交时会将所有标记过的修改保存。
另外新增的文件为untracked file,未在git管理范围内,需要先通过git add添加到暂存目录,然后其状态会变为staged
如图所示,git分为远端和本地。远程远程服务器存储了仓库信息,而本地则是三种工作域都有。
Branch、HEAD和Commit tree
本地提交代码到远端的一般流程:
- git add,将修改保存到暂存区(stage area)
- git commit,将暂存区中的文件推送到本地分支,本地仓库更新
- git push,将本地仓库的更改推送到远程仓库,远程仓库更新
可以看到,想要更新代码,commit是必不可少的。每次commit都会生成一个工作目录的快照(前提是有修改),在git中,这些commit的快照数据使用树(tree)结构来管理,称为提交树(Commit Tree)或者工作树(Work Tree)。
Git 的分支(Branch),其实本质上仅仅是指向提交对象的可变指针。分支是git的核心所在,因为分支的存在,工作树才是工作树而不是工作"线"。可以将每个分支看作工作树的分叉,项目可以在不同分支上并行开发,然后在合适的时机又可以合并在一起,这都是分支的作用。
HEAD表示当前所处提交位置。通常来说,HEAD是指向某个分支的,当然也可以手动切换将HEAD指向工作树中的任意commit(这种情况称为HEAD分离)。
图中一共有c0-c4四个提交,main、bugFix和feature三个分支,三个分支分别指向C1、C3、C4三个提交,HEAD处于分离状态,指向C2
了解了以上的基础概念以后,让我们来探讨一下git分支相关内容。
Git分支
之前说了,分支的存在是为了并行开发,每一个分支都会指向一个具体的提交。需要多人协作的项目离不开对分支的操作。
通常来说,新建一个项目时默认分支为master,可以根据需要新建develop、release等分支。
下面介绍一些常见的git分支相关命令
- git commit。以当前提交为父节点生成新的子提交节点,并且当前HEAD/Branch会指向新生成的节点
- git branch。单独使用时查看所有分支,后面加一个branchName表示在当前节点创建名为branchName的新分支,git checkout -b branchName也能达到相同的效果,区别在于后者会将HEAD指向新创建的分支
- git checkout BRANCH/COMMIT。切换到对应的分支或者提交节点,之前有提过,直接切换到提交节点就是HEAD分离状态
- git merge BRANCH/COMMIT。将当前提交节点和指定提交节点合并并生成新的提交节点,新生成的节点有两个父节点。
- git rebase BRANCH/COMMIT。将当前分支所在节点及之前的节点中有且在另一分支/节点中所没有的节点全部按序复制一份到目标分支,然后将当前BRANCH/HEAD移到目标位置。
- git reset COMMIT.撤销commit到指定提交,与git branch -f CURRENT_COMMIT COMMIT效果是一样的。但是这种更改只能在本地体现,是不能同步到远程的
- git revert COMMIT。要想撤销能同步到远程,就得用到git revert COMMIT。此命令会通过新生成提交节点的方式撤销指定的提交节点
- git cherry-pick COMMIT_1 COMMIT_2 ... 。选取指定的一些节点按序rebase到当前分支
git merge 和 git rebase 的区别和抉择
git rebase:
- 优点:提交树呈线性,干净简单
- 缺点:修改了提交树的历史
git merge:
- 优点:提交记录顺序正确,不会造成迷惑
- 缺点:多分支时显得看起来很复杂
两者如何抉择,该使用哪条命令来合并,这取决于用户的习惯,如果对提交历史顺序的正确性有要求,就用git merge,否则使用git rebase
与远程仓库的交互
通常来说,开发的一般流程是在远程建立一个仓库,然后开发人员各自在本地clone仓库,新建自己的分支进行开发,开发完成后再推送到远程分支,再合并到主分支。
当我们clone远程仓库到本地时,会在本地复制一份仓库信息和工作目录
注意,本地多了一个origin/main的分支,这个分支叫做远程分支,它反映了你最近一次操作远程仓库的状态。远程分支比较特殊,不能像普通分支一样通过checkout、branch等命令直接操控,必须通过pull、push、fetch等命令与远端同步。
下面介绍一些常见的与远程仓库交互的命令:
- git clone Repository。将远程仓库克隆到本地,可通过git clone -b branchName Repository命令指定克隆的分支。
- git fetch,下载远程分支的最新状态到本地,只会更新本地的远程分支,不会更改HEAD和本地分支远程
有更新
使用 git fetch后
- git pull。可以视作 git fetch + git merge 的缩写。存在下列常见情况,远程分支有人提交了更新,自己本地也提交了更新,这时候就需要先拉取最新的代码
使用git pull,第一步是下载最新分支更改,即git fetch
..NET CORE 2.0的发布后,考虑到.NET CORE项目可以跨平台,准备把项目迁移到.NET CORE 环 ...
- 代码管理工具 --- git的学习笔记二《git的工作原理》
通过几个问题来学习代码管理工具之git 一.git是什么?为什么要用它?使用它的好处?它与svn的区别,在Mac上,比较好用的git图形界面客户端有 git 是分布式的代码管理工具,使用它是因为,它便 ...
- git代码管理工具-SourceTree 使用介绍
一.SourceTree 简单说明 SourceTree 是git 代码管理的可视化工具,可省去操作命令行的一个图形化工具,下载地址:https://www.sourcetreeapp.com/ 二. ...
- 使用代码管理工具(git)管理代码的常用指令合集
create a new repository on the command line echo "# test" >> README.md git init git ...
- 源代码管理工具 ——Git的介绍与简要教程
一.Github与Git (一)简介 GitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名GitHub. GitHub于2008年4月10日正式上线 ...
- 代码管理工具Git的安装及使用
一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以 ...
- java接口自动化(五) - 企业级代码管理工具Git的配置
1.简介 上一篇讲解完如何安装Git后,今天宏哥趁热打铁讲解一下Git的使用,要想使用Git,我们还需要做一些准备工作,首先你的拥有一个Git账号,所以如果你没有的话,就快速注册一个吧. 2.Git注 ...
- 项目代码管理工具Git的总结
在项目的开发中,代码的同步管理很重要,团队的几个人可以通过免费的github管理自己的开源项目代码,高效方便.下面说说,开发中经常用到的git指令操作,基于github平台. 0.配置提交者的账户和邮 ...
随机推荐
- automake的使用2
前言 如果你的入口文件main.c和依赖的文件不是在同一个目录中的,使用Autotools来管理项目的时候会稍微复杂一下. 在不同的目录下,项目会生成*.a文件的静态连接(静态连接相当于将多个.o目标 ...
- System.getenv和getProperty的区别
/** * System.getenv()是获取---环境变量(environment variables), * 系统层面的,好比我linux系统里的.bash_profile文件里面的变量 * 返 ...
- Markdown入门操作
Markdown基本操作 一. 字体 1. 标题 (1). 一级标题 "# + 标题名" (2). 其余类推 (最多支持6级标题) 加粗 " ** + 内容 + ** & ...
- 1.时任务XXL_Job框架踩过的坑
遇到的问题 问题1:执行器地址为空 原因-->执行器中 没有地址 解决方案-->输入地址:http://IP地址:端口 IP地址 端口 问题2:异常信息unknown code for r ...
- C语言杂谈
C语言程序处理过程 预处理:宏定义展开.头文件展开.条件编译,这里并不会检查语法 编译:检查语法,将预处理后文件编译生成汇编文件 汇编:将汇编文件生成目标文件(二进制文件) 链接:将目标文件链接为可执 ...
- 电源PCB布板的10个基本法则
电容模型 电容并联高频特性 电感模型 电感特性 镜象面概念 高频交流电流环路 过孔 (VIA) 的例子 PCB板层分割 降压式(BUCK)电源:功率部分电流和电压波形 降压式电源排版差的例子 电路等效 ...
- 给新手的最简单electron使用教程
我花了两个月闲暇翻译完了文档,大概是目前最完整最实时的中文文档了,有需要可以去看看学学:github传送门,大多数的需求阅读文档即可解决,实际上,翻译文档正是我入门一项未知事物时的最简单常用的法子. ...
- Linux 0.11源码阅读笔记-块设备驱动程序
块设备驱动程序 块设备驱动程序负责实现对块设备数据的读写功能.内核代码统一使用缓冲块间接和块设备(如磁盘)交换数据,缓冲区数据通过块设备驱动程序和块设备交换数据. 块设备的管理 块设备表 内核通过一张 ...
- 【Android开发】Bitmap的质量压缩法
public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputS ...
- Android开发小经验
1. TextView中的getTextSize返回值是以像素(px)为单位的, 而setTextSize()是以sp为单位的. 所以如果直接用返回的值来设置会出错,解决办法是 用setTextSiz ...