开发中关于Git那些事

如果你想精通Git,直接到Git官网把这本ProGit掌握已足以Pro Git

此文主要介绍一切开发中常用的git命令和一些配置技巧(诸如git别名配置,log打印技巧,版本回退以及分支管理等)。

后来我又写了篇主要介绍Git变基的文章《开发中关于Git那些事(Git Rebasing)》,有兴趣的可以看看。

1.简介

Git与SVN相比而言,Git的好处自然不用多说,Git完全分布式文件管理系统,加上其简单速度,可以高效管理类似 Linux 内核一样的超大规模项目。完全分布式的系统,让你可以在公交车上,火车上,家中,甚至在厕所都可以敲代码。何时何地你都可以敲代码,甚至不需要网络。好不好使,开不开心?换是SVN,SVN服务器挂了,全部人停止敲代码,停下来八卦去吧。

Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。这类系统(CVS,Subversion,Perforce,Bazaar 等等)每次记录有哪些文件作了更新,以及都更新了哪些行的什么内容。如同下图所示:

但是,Git 并不保存这些前后变化的差异数据。实际上,Git 更像是把变化的文件作快照后,记录在一个微型的文件系统中。每次提交更新时,它会纵览一遍所有文件的指纹信息并对文件作一快照,然后保存一个指向这次快 照的索引。为提高性能,若文件没有变化,Git 不会再次保存,而只对上次保存的快照作一连接。工作方式类似下图:

对比可以发现,Git高效也在情理之中。

现在再简单介绍一下Git管理下文件的三种状态。对于任何一个文件,只要在Git管理下,那么该文件只有三种状态:已修改(modified),已暂存(staged)和已提交 (committed)。

已修改(modified): 文件被修改,但是还没有提交保存(也就是没有使用git add,此时使用git status显示为红色)。

已暂存(staged): 已修改的文件放入下次要提交的清单中(使用了git add后的状态,此时使用git status显示为绿色)。

已提交(committed): 该文件已经被安全地保存在本地数据库中(使用了git commit后,此时使用git status已经不存在该文件的任何信息)。

具体可以参考下面两幅图来理解。

2.配置用户信息

user和email,--global参数全局配置,当然你也可以不加此参数,不同的项目用不同的用户名和邮箱。

3.配置全局别名

此配置在开发中相当重要,尤其是对于使用Terminal,习惯使用命令行的朋友,由于git不支持tab自动补全,每次想要看下工作目录 状态都要git status,相当耗时。除非你能确定你敲两个字母比六个字母用时少。

第一条:git status是开发中使用最多最频繁的,至于-s 是简洁输入(Give the output in the short-format)

第二条:此条也使用频繁,但是我在开发中直接使用第三条跳过。

第三条:配置git aci 因为这样直接跳过使用暂存区域,对于已经跟踪的文件,我不要再此次使用git add加入暂缓区,然后再git commit提交到本地数据库,为了方便省事,直接将两条命令合并为一条,使用git aci "提交说明" 即可。省不省事,用下自然知道。

第四条:这里是我自定义的log信息,当然,一会看完本文你也可以自己格式化成自己喜欢的log格式。可以先看下效果,下图所示:

自定义log

以后直接使用"git lg"即可,非常方便,显示简洁明了。

4.分支管理

关于实际开发中,独立开发的话其实两个分支完全够用,一个主分支(master),一个开发分支(develop)。多人的话就按功能模块和人员来具体新建分支即可。由于这边由我一人负责整个项目,那么分支的话,我就建立了一个develop分支,发布版本时切换到master处理即可。平时都在develop分支开发,如果此时发现线上版本有bug,那么只需要切换到master分支,修改bug,然后封版即可。处理好后切换到develop分支开发就可以了。当然最好还是把刚才在master修改bug的代码merge到当前的develop分支上。

还有一点使用技巧,也就是的灵活使用。当我们正在当前分支编代码,突然某人中断你的思路,提出某功能需修改且比较紧急,更烦人的是当前的代码已经开始编写,而且改动了好多文件,重要的是不想中途进行git commit提交,此时git stash就发挥作用了。

git stash可以执行多次,我们可以使用命令来查看清单。当然还有好多命令,可以使用来查看。

其实关于还有一个使用技巧,那就是如果当前修改了众多文件,突然又不想改了,想恢复到原来的样子。那么可能你会使用命令来取消所有的更改,但是有种情况并不好使,因为你除了修改文件,还添加了一些文件或则拖入了一些文件到工程目录下,此时使用然后再使用查看的时候,会发现工作区多出了尚未识别的文件(处于等待add的状态)。在这个时候,使用是再好不过了,因为这样将所有git控制下的文件,包括之前的目录,全部还原到之前的状态(也就是说把新增的文件也暂时隐藏起来)。如果想彻底删掉,那就再把所有stash的列表清空吧,直接看下,然后执行。

还有一点,关于在Git服务器上删除分支,本地使用依旧可以看到被删除的分支。好比你的代码托管到了开源中国(OSChina),你通过网站,在线删除分支,就会出现这种问题,稍微有点强迫症的自然受不了。此时可以使用使fetch之后删除没有与远程分支对应的本地分支。 当然也可以通过查看远程分支。使用命令显示如下:

我们可以看到分支origin/test 已经过期(stale),可以使用命令同样可以处理。

5.远程地址切换

如果想要切换远程地址,千万不要重新再初始化一个git代码仓库,使用git add重新添加。这样的好处只有一点,所有历史提交信息全部清空,不再保留,时文件变小,理所当然,历史记录全部清空了麽。如果确定不保留,也建议这样做,关键时,谁写的代码更改了哪些东西很重要呀,还是选择保留吧。使用下面的方法,一行代码搞定,并且保留了所有的commit记录。

6.查看某次提交修改的具体文件和内容方法一

或则

首先要列出最近的提交记录。

找到对应版本号,执行后可以看到本次提交之前的所有修改文件。

具体某次修改的内容(具体某次提交的内容和上次提交的内容进行比较)。

当然也可以这样,使用版本号,效果一样。

这样假如之前修改过具体某些内容,以后还需要修改的话,找起来真的很方便。比如说某些bug好久之后才发现,又要回头去修改,而修改总要找到对应的代码进行修改吧。那么通过这样几行命令就定位到具体文件和位置了,方便且节省时间。找代码有技巧,但是"找"终究还是很浪费时间。这也告诉我们,commit 提交命令很重要,需要认真写,不可为了省事而乱写。

方法二

直接使用或则

其中4e732dee为版本哈希值

方法三

或者

查看简洁文件变化

简洁文件变化

查看本地修改的内容,尚未进行commit

直接使用

7.忽略跟踪

git checkout . 清空所有更改

以下命令是我们在项目中已经添加了.gitignore 但是中途突然不想再跟踪某文件此时发现简单的在.gitignore文件中添加要忽略的文件是不起效的,因为该文件已经被track,我们还需要将其状态改为 未track(其实只需删除暂缓区文件然后将操作体检即可)

git rm --cached Podfile.lock 将Podfile.lock从暂缓区删除,不再跟踪

8.备份

备份的话好一些,每次新的版本打一次tag,查看起来还是挺方便。不过不用也行。我不爱使用这个。

9.版本回退

注意:开发中一般托管代码到远程代码仓库,比如Github或则OSChina,加入本地已经使用git push到远程代码仓库,在本地使用回退再push明显是不可行的。因为git reset直接回退到历史中的某个Hash值,但是使用git revert就不一样了。git revert将作为一次新提交(新的Hash值)来撤销某次更改而不是历史中的某个Hash值,此时再push到远程代码仓库情理之中。当然你嫌麻烦也可以使用git reset 后再使用强制 push 到远程代码仓库。

reset和revert区别:

• git reset 3c7bdf2 回到3c7bdf2,3c7bdf2之前的commit都会保留,3c7bdf2之后的修改都会被退回到暂存区。

• git revert 3c7bdf2 生成一个新的commit来撤销3c7bdf2,此次提交之前的commit都会被保留。

可以参考博客git revert和git reset的区别

10.日志

想回顾下提交历史,可以使用 git log 命令,其中有个--pretty 参数可以配置

自己可以试一下,这里附上参数说明,自己可以随意配置,当然log字体颜色也都是可以修改的,不再细述。

时间和提交者过滤

你一定奇怪作者(author)和提交者(committer)之间究竟有何差别,其实作者指的是实际作出修改 的人,提交者指的是最后将此工作成果提交到仓库的人。所以,当你为某个项目发去补丁,然后某个核心成员将你的补丁并入项目时,你就是作者,而那个核心成员就是提交者。我们会在第五章再详细介绍两者之间的细致差别。

11.忽略某些文件

文件 .gitignore 的格式规范如下:

• 所有空行或者以注释符号 # 开头的行都会被 Git 忽略。

• 可以使用标准的 glob 模式匹配。

• 匹配模式最后跟反斜杠(/)说明要忽略的是目录。

• 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。

所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。星号(*)匹配零个或多个任意字符;[abc] 匹配 任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);问号(?) 只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配 (比如 [0-9] 表示匹配所有 0 到 9 的数字)。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180122G0BT0Y00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

同媒体快讯

扫码关注云+社区

领取腾讯云代金券