为了账号安全,请及时绑定邮箱和手机立即绑定

Git使用

标签:
Git

集中化版本控制系统

集中化版本控制系统(Centralized Version Control Systems,简称CVCS),用于记录某个时间点对项目做了哪些修改,包括增加、删除等。如CVS、SVN等,都是集中化版本控制系统。集中化版本控制系统有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的开发者通过客户端连接到该服务器,并且可以从该服务器获取数据,修改记录,或者提交更新。集中化版本控制系统实现效果如下:

webp

屏幕快照 2018-11-26 下午3.53.45.png

集中化版本控制系统使用比较方便,但是其缺点也是比较明显的。如果集中管理的服务器故障,那么在服务器故障期间内,任何人都无法提交更新,也就无法协同工作。如果服务器硬盘发生损坏,又没有做恰当的备份,虽然发生的几率非常小,但是一旦发生,项目的所有数据都将丢失,包括项目源数据和变更历史。为了解决集中化版本控制系统的缺点,于是就有了分布式版本控制系统。

分布式版本控制系统

分布式版本控制系统(Distributed Version Control System,简称DVCS),最出名的就是Git。在分布式版本控制系统中,客户端从服务器并不只是提取最新版本的文件快照,而是把代码仓库完整的镜像下来,包括整个项目的提交历史。这样一来,即使服务器发生故障,使用任何一个镜像都可以快速的恢复。分布式版本控制系统的实现效果如下:

webp

image

Git分支模型

版本控制系统通常都会支持分支。分支可以使开发者从主线版本脱离出来,来做一些其他尝试性的工作。在部分版本控制系统中,比如SVN,新建分支需要完全创建一个源代码目录的副本。这在一些大型项目中,该过程会耗费几分钟,甚至更久的时间。

Git可以很快的创建一个分支,时间通常在几秒钟之内,这也是Git为何如此流行的一个原因。这里再介绍一个Git和其他版本控制系统的区别。很多版本控制系统记录的是文件的变化,比如两次提交之间,SVN就是记录了两次提交的不同,也就是文件变化。Git记录的不是文件变化,而是一些列不同时刻的文件快照。

Git新建一个分支,其实就是新建了一个指针,指针指向了某一时刻的提交。比如使用git branch新建一个分支:

git branch testing

实际上是新建了一个指针,该指针指向当前所在的提交对象,如下图:

webp

image

新建了testing指针,testing指针和master指针指向了同一个提交对象 f30ab。

之后加入切换到了testing分支,然后对testing分支做了修改和提交,testing指针会随之向后移动,但是master指针是不会改变的,如下图:

webp

image

testing指针已经改变,但是master指针并没有随之移动。这正是分支的意义所在。

上面图片中出现了HEAD指针,简单介绍下HEAD指针。Git中的HEAD指针指向的是当前的分支。拿上图举例,如果当前在master分支,那么HEAD指向的就是master,如果当前在testing分支,那么HEAD指向的就是testing。

Git命令

配置用户信息

使用Git之前需要首先配置个人信息,包括个人的用户名和电子邮件地址。每次Git提交时,都会引用用户名和电子邮件,说明是谁提交了更新。配置用户信息的命令:

// 配置用户名git config --global user.name "Test"// 配置用户电子邮箱git config --global user.email 123456@qq.com

文本编辑器

当Git需要用户输入一些额外的信息时,会自动调用一个外部的编辑器给用户使用。默认会使用操作系统指定的默认编辑器,比如说Vi或者Vim。如果想设置成其他的编辑器,可以通过git config来设置,命令如下:

// 配置编辑器为emacsgit config --global core.editor emacs

当然,在设置之前也可以查看当前的编辑器,命令如下:

// 查看所有的config配置git config --list// 查看user.name的配置git config user.name// 查看当前的编辑器git config core.editor

差异分析工具

在提交代码、合并代码、解决冲突时,需要用到差异分析工具。差异分析工具也是可以设置的,命令如下:

// 配置差异分析工具为vimdiffgit config --global merge.tool vimdiff

Git可以理解vimdiff、gvimdiff、opendiff等工具的输出信息。

新建git仓库

Git中有仓库(repository)的概念,所有的文件应该都在仓库中。可以通过两种方式新建仓库:在本地新建仓库和从远程服务器clone一个仓库。

在本地新建仓库

在本地新建仓库非常容易,只需要在对应的目录下使用git init命令即可。命令如下:

// 新建一个git仓库git init

新建仓库之后,后续就是向仓库中添加文件,并提交。添加、提交的命令之后再介绍。

从远程克隆一个仓库

从远程克隆仓库使用的是git clone命令,比如:

// 从远程服务器clone一个git仓库,会在当前目录下新建Blogs文件夹git clone https://github.com/acBool/Blogs.git

当然,clone时也可以指定本地仓库的名字,命令如下:

// 本地仓库会被命名为myBloggit clone https://github.com/acBool/Blogs.git myBlog

查看当前文件状态

Git仓库下的文件有已修改、未修改、已暂存、未跟踪几种状态,使用status命令可以查看当前文件的状态,命令如下:

// 查看当前文件状态git status

git status命令输出的信息可能有些冗余,可以使用-s参数得到一个更为简介的信息:

// 查看当前文件状态,信息更为简洁git status -s

添加文件到git仓库

新建仓库后,可以向仓库中添加文件。但是添加的文件处于未被跟踪的状态,如果要改变文件为跟踪状态,需要使用git add命令,如下:

// 将hello.c的状态改为跟踪状态git add hello.c

如果add之后的参数是文件夹,会递归的跟踪该目录下的所有文件:

// 会递归的将Tempdir目录下的所有文件改为跟踪状态git add Tempdir

忽略文件

通常情况下,总会有一些文件没必要让Git来管理,也不希望这些文件总是出现在未跟踪文件列表,比如说一些日志文件,或者变异过程中生成的临时文件。这种情况下,可以创建.gitignore文件,在.gitignore文件中列出要忽略的文件即可。比如:

// 忽略所有以.a或者.o结尾的文件*.[oa]// 忽略所有以~结尾的文件*~// 忽略所有以.a结尾的文件*.a// 除了lib.a文件,使用!取反!lib.a// 忽略TODO文件,而不是TODO文件夹/TODO// 忽略build文件夹下的所有文件build/

查看文件做了哪些修改

使用git diff命令可以查看文件做了哪些修改,实际上就是和原来的文件做对比,命令如下:

// 查看未暂存的文件做了哪些更新git diff// 查看已暂存的文件做了哪些更新git diff --cached// 查看已暂存的文件做了哪些更新git diff --staged

其中,git diff --staged和git diff --cached的功能是一样的。

提交更新

提交的命令是 git commit,命令如下:

// 如果只输入git commit,会弹出文版编辑器让输入这次提交的信息git commit// 加上-m参数,直接输入此次提交的信息git commit -m 'add file'

移除文件

从Git中移除某个文件,使用的命令是git rm,命令如下:

// 移除a.test文件git rm a.test

需要注意的是,移除之后,还需要使用commit命令来此次的操作提交。另外,移除后,本地磁盘上的a.test文件也会被删除。

如果只想移除仓库中的a.test文件,而保留本地磁盘上的a.test文件,该如何操作呢?实际上,这样的应用场景是存在的,比如说忘记加.gitignore文件,将一些不必要的文件加入到仓库中,这时候就会有这样的问题。我们想把仓库中没用的文件删除,但是本地还想要保留,git对这种情况是支持的。命令如下:

// 从仓库中移除a.test,但保留在本地磁盘git rm --cached a.test

重命名文件

Git中重命名文件可以使用mv命令,如下:

// 将a.test文件重命名为b.testgit mv a.test b.test

查看提交日志

使用git log命令可以查看一个仓库的提交日志,命令如下:

// 默认不带参数,会按照提交时间列出所有的更新,包括提交人昵称,邮箱,最新的提交在最上面git log// 显示每次提交的差异,即具体更新了哪些内容git log -p// 显示最近两次提交的差异,限制了日志数量git log -p -2// 显示每次提交简略的统计信息git log --stat

撤消对文件的修改

如果不小心改了一个文件,但是不想修改该文件,也不想把修改过的文件放入暂存区,提交,Git提供了撤消修改文件的命令:

// 撤消修改文件.DS_Storegit checkout -- .Ds_Store

将文件从暂存区移除

当想将一个文件从暂存区移除时,可以使用reset命令,如下:

// 将.DS_Store文件从暂存区移除git reset HEAD .DS_Store

目前为止,我们所介绍的命令都是和本地仓库相关,提交、添加等,操作的都是本地仓库,那么,如何和远程仓库交互呢?如何将本地仓库的修改推送到远程仓库呢?

从远程仓库拉取

从远程仓库中获取数据,可以使用git fetch或者git pull命令,如下:

// 从远程仓库test拉取数据,需要注意的是,使用这种方式拉取的数据,并不会合并到本地仓库
// 还需要手动add、commit之后,才会合并到本地仓库
git fetch test// 从远程仓库test拉取数据,这种方式拉取的数据,会尝试合并到本地仓库
git pull test

推送到远程仓库

推送到远程仓库使用git push命令即可,如下:

// 推送到远程仓库testgit push test

运行完这条命令后,可能会让输入用户名和密码,以验证是否有推送的权限。

添加远程仓库

添加远程仓库使用的命令是git remote add命令,如下:

// 添加一个远程仓库,远程仓库的url是https://github.com/***/***,远程仓库的名称是testgit remote add test https://github.com/***/***

移除远程仓库

移除远程仓库使用git remote remove命令即可:

// 移除远程仓库testgit remote remove test

重命名远程仓库

重命名远程仓库使用rename命令,命令如下:

// 把远程仓库a重命名成bgit remote rename a b

查看Git标签

Git提供了标签的功能,可以在某些重要的节点增加标签,比如版本上线,可以打上标签。查看已有标签的命令是:

// 会列出所有的标签git tag// 只列出v1.1.0的标签git tag -l 'v1.1.0'

创建Git标签

创建Git标签使用-a命令,如下:

// 创建标签,标签名为v1.4,标签信息为 version 1.4git tag -a v1.4 -m 'version 1.4'

创建Git分支

Git中默认的分支名是master。Git中的master分支并不是一个特殊的分支,master分支和其他的分支没有什么区别。之所以大多数仓库都有master分支,是因为git init命令默认创建的分支是master。

Git创建分支的命令很简单,如下:

// 新建一个testing分支git branch testing

注意,这种方式只会新建一个testing分支,但是并不会切换到testing分支下。

另外介绍一下Git中的HEAD指针,HEAD指针指向当前所在的本地分支,可以将HEAD指针理解成当前分支的别名。默认是master分支,则HEAD指向的是master分支;如果切换到testing分支下,则HEAD指向的是testing分支。

分支切换

Git中分支切换使用checkout命令,如下:

// 切换到testing目录下git checkout testing

此时HEAD指针也指向了testing分支。另外需要注意的是,切换分支时,工作目录也会对应的改变。

另外一种切换分支的方式是:

// 这种方式适用于不存在testing分支的情况git checkout -b testing

上述命令实际上是两条命令的简写:

// 新建testing分支git branch testing// 切换到testing分支git checkout testing

分支合并

分支合并使用的是git merge命令,假设现在的工作目录是master,想要合并testing分支,则命令如下:

// 将testing分支合并到master分支git merge testing

分支删除

在合并完testing分支之后,可能testing分支对我们来说已经没有用了,这时可以将testing分支删除,删除命令如下:

// 删除testing分支git branch -d testing

冲突标示

在合并分支时,不可避免的会出现冲突,出现冲突后git会标示出来,大概如下:

<<<<<<< HEAD:index.html
  <div id="footer">contact : email.support@github.com</div>
  =======  <div id="footer">
   please contact us at support@github.com  </div>
  >>>>>>> iss53:index.html

======号上面是HEAD分支,也就是当前分支的内容,======号下面是合并分支,这里是iss53分支的内容。出现冲突的原因是两个分支对同一个文件的同一行做了修改,这种情况下需要解决手动解决冲突。

分支管理

查看当前分支列表

使用git branch命令可以查看当前的分支列表,如下:

// 查看当前分支列表git branch

列出的分支列表中,如果某个分支名前有*号,表示该分之是目前所处的分支,也就是HEAD所指向的分支。

查看每个分支最后的一条提交信息

使用git branch -v命令,能够看到每个分支最后的提交信息,如下:

git branch -v
查看已合并到当前分支的分支

使用git branch --merged命令,可以查看当前有哪些分支已经合并到当前分支了,如下:

git branch --merged
查看未合并到当前分支的分支

使用git branch --no-merged,可以查看当前有哪些分支没有合并到当前分支,如下:

git branch --no-merged

推送本地分支

可以使用git push (remote) (branch) 来将本地分支推送到远程仓库分支,命令如下:

// 推送本地的testing分支到远程origin仓库的testing分支git push origin testing// 推送本地的testing分支到远程origin仓库的somebranch分支git push origin testing:somebranch

跟踪远程仓库分支

当clone一个仓库时,Git通常会在本地自动创建一个master分支,该master分之跟踪的是origin/master,即远程仓库origin的master分支。当然,也可以跟踪其他的分支,命令格式是:git checkout -b [branch] [remotename]/[branch],针对该命令,git提供了--track的快捷方式,命令如下:

// 在本地新建一个serverfix分支,该分支跟踪的是远程仓库origin的serverfix分支git checkout --track origin/serverfix// 该命令和上面所表达的含义一样git checkout -b serverfix origin/serverfix

当然,也可以将本地分支的名字和远程分支的名字设置成不一样,命令如下:

// 在本地新建一个sf分支,该分之跟踪的是远程仓库origin的serverfix分支git checkout -b sf origin/serverfix

可以设置本地分支跟踪某一个远程分支,也可以修改本地分支正在跟踪的远程分支,使用的参数是-u或者--set-upstream-to,命令如下:

// 设置当前本地分支跟踪远程仓库origin的serverfix分支git branch -u origin/serverfix// 设置当前分支跟踪远程仓库origin的serverfix分支git branch --set-upstream-to origin/serverfix

查看所有本地分支正在跟踪的远程分支

使用git branch -vv命令,可以查看所有本地分支正在跟踪的远程分支,而且会列出本地分支是否领先,或者落后远程分支,命令如下:

// 查看本地分支正在跟踪的远程分支git branch -vv

拉取远程分支

拉取远程分支可以使用git fetch命令或者git pull命令。两者的区别是:git fetch命令拉取下来的数据,不会修改工作目录中的内容,需要用户自己合并,也就是使用git merge命令。而git pull相当于将这两个命令合并成一个命令,先git fetch,然后git merge。

删除远程分支

删除远程分支使用的命令如下:

// 删除远程仓库origin的serverfix分支git push origin --delete serverfix

变基

在Git中整合分支除了merge之外,还有一种方法就是变基(rebase)。看下面的例子:

webp

image

该分之从C2开始产生了分叉,目前有master分支和experiment分支,使用git merge命令,当然可以将experiment分支和master分支合并。前面介绍过,使用merge命令,实际上是将两个分支的最新快照C3、C4以及二者的最近祖先C2进行了三方合并,合并结果进行了一次新的提交,效果如下:

webp



作者:acBool
链接:https://www.jianshu.com/p/31537b9580c5


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消