关于git

Git,是一个分布式版本控制软件。最初本是为了更好的管理Linux内核开发而被林纳斯·托瓦兹开发,后来因为项目开发中版本控制的强烈需求,而git也日趋成熟,最终成为了一个独立的版本控制软件。

git使用方法

创建远程仓库

建立远程仓库,说得白话一点就是在代码托管服务器上给我分配一片可远程访问的空间。其实跟git的使用没有直接的关系,但是为了更好的说明问题,咱就稍微啰嗦下。

目前支持git的代码托管服务很多,名气最大的莫过于Github,其他还有GitLabBitbucketCSDN-CODEGit@OSC等等。我们先来说说为什么需要代码托管服务器,无论我们开发的是个人项目还是团队项目,从长远来看,将代码托管到远程服务器上都是比较好的选择。理由很容易想到:

  • 1、方便多人(有权限)共享,团队开发尤为重要;
  • 2、不怕更换电脑,公司和家里或出差,只要有电脑就可以访问;
  • 3、不怕硬盘损坏代码丢失;
  • 4、其他还有很多。

基于以上代码托管服务器,建立一个远程仓库非常简单,以Github为例,打开https://github.com 首页登录进去后,页面右上角有一个“+”图标,鼠标点上去就看到如图所示的样子:

New repository

点击红框标示的那个连接,然后填写关键信息,根据提示就创建好了。

创建本地代码库(init)

本地代码库,其实就是我们的代码目录,如果非要区别普通代码目录和git仓库目录,那就是基于git的代码目录里面会多一个.git的目录,这个目录一般是不可见的。如何将一个普通代码目录变成git工作目录,其实很简单。我们可以使用cmd、git bash或任何一个命令行工具,进入工作目录,然后运行下面这行代码就可以了:

git init

当本地仓库初始化好后,其实我们已经可以使用git工作了,比如将代码文件添加到版本记录,创建本地分支,合并本地分支代码等等。

绑定本地代码库与远程仓库(remote | clone)

如果仅仅使用git在本地捣鼓,那么我们上面提到的远程代码托管的优势就完全没有意义了,所以我们要把我们的本地仓库和远程仓库绑定起来,这里就要分情况了。

  1. 如果是现在本地已经开发的一个全新项目需要推送到远程仓库,你需要先这么做:

    git remote add origin https://github.com/username/project.git

  2. 如果是在别人已经开发过的仓库中继续开发,我们不需要预先建立并初始化本地仓库,直接执行下面这条命令就可以了:

    git clone https://github.com/username/project.git

查看仓库文件状态(status)

当我们已经拥有一个本地git仓库或对我们的项目进行了修改后,我们可能迫不及待的想看看我们项目中各个文件的当前状态,我们只需在git bash中执行:

git status

通常情况下,我们可能看到一堆红色标记的列表,包括以下信息:

  1. Changes to be committed:等待提交的更改
    • new file:新增文件
    • modified:有改动的文件
    • deleted:删除的文件
  2. Untracked files:未添加到版本记录的文件

如果是一个全新仓库,我们只能看到Untracked files项。

添加文件并提交到暂存区(add & commit)

当我们通过git status看到有红色文件列表,而且其中有我们想要保存到远程仓库中的文件时,我们可通过git add <filename>命令,将相应文件添加到暂存区,我们也可以通过git add .命令,添加所有新增或有更新的文件,但这里要注意删除的文件不会被添加。

添加删除的文件需要使用git add -u filename或git add -u .命令。

接下来我们还需要执行一个命令git commit,才能将添加的文件(变化)提交到暂存区。这个命令的用法也有几种,常见的是直接执行git commit -m 'log info',还有一种是执行git commit打开指定编辑器,编辑好日志后关闭编辑器即可,一般用于日志内容比较多的情况。

创建并切换分支(branch & checkout)

在实际开发过程中,我们需要考虑代码的稳定性,未经过测试的代码不能发布到线上环境。这就意味着我们如果我们一直在一个分支上开发代码是很危险的,一步留神就可能把有bug的代码提交到了远程仓库,造成不必要的麻烦,所以一般情况下使用版本控制器,我们都会使用它的分支功能。即开发分支、主干分支,当开发分支上的代码测试稳定后,再合并到主干分支,将主干分支提交到远程仓库,这样出错的概率就降低了很多。

使用git bash可以很方便的建立分支,我们只需执行git branch newbranch即可创建一个名为newbranch的分支,然后我们只需执行git checkout newbranch命令,即可将我们的工作环境切换到newbranch分支上。

还有一种更为简便的方法,可以直接使用checkout命令,完成创建并切换到分支:

git checkout -b newbranch

合并分支(merge)

前面我们提到了,当开发分支上的代码测试稳定后,我们就可以合并到主干分支上,并提交到远程仓库。那么如何合并两个分支的代码成了一个问题。难道要对比两个文件的差异,一行一行的copy代码?显然git不会这么笨,它是很智能的,我们只需简单的运行一条命令即可完成代码自动合并。我们设想开发分支(newbranch)将被合并到主干分支(master)上,那么首先我们要先将开发分支的代码提交到暂存区,然后切换到主干分支,最后执行合并操作,完整的操作流程大致如下:

git add .
git commit -m 'newbranch 上的变动内容'
git checkout master
git merge newbranch

但是,我们在合并代码的时候,特别是多人开发的时候,偶尔出现冲突(两个人同时改动了同一个地方)也是在所难免的,这种情况,我么恐怕就需要人肉解决下了。不过问题不大,git将文件冲突的地方都会以特殊的形式标明的。

# 冲突示例
<<<<<<< HEAD
aa  # 当前分支上的内容
=======
bb  # 被合并分支上的内容
>>>>>>> nb

将本地代码推送到远程仓库(push)

当开发分支上的代码都被合并到主干分支上,并且所有的冲突都解决好后,我们就可以将主干分支的代码推送到远程仓库,提供给别人使用了。这一步很简单:

git push origin master

还记得我们执行git remote add后面的origin吗?这里和那里是一样的哦,而最后那个master就是分支名称了。如果远程已经有该分支,便会先检查远程仓库在最近一次更新之后发生过更改,如果有会提示先进行更新代码,然后再提交。如果未变动过,本地代码则会直接提交至远程代码仓库。

将远程仓库中的代码更新到本地(pull & fetch)

然而,一般情况下,我们在执行git push之前,都会先更新一次远程仓库中的内容:

git pull origin master

这里我们需要注意一下,和git merge命令一样,pull命令是有可能导致代码冲突的。而pull命令从某种意义来讲实际和fetch+merge命令一样,这里就不再对fetch做进一步说明了。

比较代码差异(diff)

通常我们在开发过程中涉及的文件比较多,修改的地方也比较多,当我们需要提交代码的时候,往往想不起来我们修改了哪些内容,哪些问需被提交。这时候我们可能希望能查看一下在前次提交代码之后我们对本地仓库所做的改动,那么你可以这么做:

git diff

查看working tree和index file的差别,也可以:

git diff --cached

查看index file与commit的差别,还可以:

git diff HEAD

查看working tree和commit的差别。

diff命令的使用,大致就是这个样子,她们之间的细节差异,可以通过网络查找更详细的说明,也可以在实际使用中自己去观察,这里就不做赘述了。

代码回滚与日志(reset & log)

当我们的项目开发到一定阶段后,也许偶尔就发现该版本的升级存在问题,需要临时将项目恢复到上一个稳定版本。但是,人肉的将升级代码改回去,显然是不现实的,更科学的解决方法是使用git的reset命令:

git reset --hard commitId

将本地仓库代码回滚到commitId对应的版本,或者:

git reset --hard HEAD~number

将最近number次的提交进行回滚,number为一个整数。那么问题来了,当我们需要回滚到指定版本的时候,commitId从何而来?我们怎么知道哪个commit是最近的稳定版本?

说到这里,就该log命令出场了。我们可以使用log命令,查看仓库的提交历史,以及每个提交的更改日志,甚至更改的内容,其最基本的用法如下:

git log -2  # 查看最近两次的提交历史
git log  # 默认会输出所有的提交历史,最近的在最上面

我们可以根据日志内容,找到响应的稳定版本代码的commitId,然后再使用reset命令进行代码恢复。怎么样,是不是很强大?但是笔者要告诉你的是,reset和log命令非常强大,参数也比较多,特别是log命令,上面仅仅列举了最最基本的使用方法,如果读者还想了解更多,更深入的东西,还需要翻看更多,更全面的资料学习。由于笔者能力有限,且考虑到篇幅问题,就不再啰嗦了。

给代码库打标签(tag)

tag命令,是用来给我们的代码库打标签的。听起来可能有些不太理解,其实日常使用中,通常是用来添加版本标记。

git tag v1.0.0

表明在这里我们发布了1.0.0版本。这样就可以很方便的让我们回顾项目每个版本的样子,历史就是这样用血写成的。我们也可以通过tag命令查看已有的标签,只需要执行:

git tag

这样就行了。

打造自己的git命令

Git已然非常强大,而且git的命令也已经非常简洁明了。但是,开发者们往往希望使用工具的同时能保留自己的个性,希望能符合自己的操作习惯。比如笔者就嫌checkout命令太长了,虽然各种自动补全,但用起来还是觉得不顺手,那么有没有什么办法可以再简洁些呢?答案是肯定的。下面给大家列出笔者的缩写配置,当然也是曾经参考了很多网上大牛们的教程的。

git config --global alias.st status
git config --global alias.br branch
git config --global alias.co checkout
git config --global alias.ci commit

配置好后再输入git命令的时候就不用再输入一大段了,例如我们要查看状态,只需:

git st

是不是很方便?这里只列了一些最为简单的配置,以抛砖引玉,更多更高大上的配置,就待读者深入挖掘了。

总结

Git是一款非常强大的分布式版本控制工具,掌握git的使用,可以让我们在工作中如虎添翼。本文仅仅在笔者能力范围之内列举了最基本的使用方法,如有不当之处,欢迎读者朋友们热心指正。