开发工具——Git,开发者的贴心小棉袄

2017-04-10  本文已影响0人  coderanger

Git 是 linux内核创始人 Linus Torvalds 为了维护 linux 源码便利而开发的一款工具。发展到今天,已经成为全球通用的分布式版本控制系统。在 Git 中,每一份复制出来的库都可以独立使用和维护,并且,任意两个不同的库都可以合并。
GitHub 是一个开源库和私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,所以叫 GitHub。现在,开源代码几乎都是放在 GitHub 上。另外,还有从 GitHub fork 出去独立开发出的收费版叫 Gitlab,支持企业内项目的托管平台,相信用过的人一定明白有多便利。

简介

Git作者

git当前最新版本为:2.12.2,官网地址

Git 设计思想和原理

Git 版本控制系统中,其通过文件对象记录所有文件,并通过缓存所有历史和元数据,实现对代码版本的控制。

Git 中的对象类型

使用 git 命令操作过程中,你会经常遇到长度为40字符的串,像这样:


40字符长度串.png

你第一反应是,这些不就是 commit id 嘛~是的,没错,但不准确。其实它真正表示的是一个项目历史信息的文件对象,这个值是通过对文件内容进行 SHA1 哈希计算得到的,就像一个 md5 值唯一标识一个文件内容一样,任意两个不同的文件
SHA1 值一定不同。

每个文件对象包括三个部分:类型,大小,内容。有四种类型对象:blob、tree、commit、tag,每一种类型的对象你都可以通过 git show xxxx 命令查看详细信息。

每次提交都会给每个文件创建 blob 类型的对象,给每个目录创建 tree 类型的对象,最后创建一个 commit 对象用于指向根 tree 对象,因此,每个一个 “commit id” 就表示了一次提交的所有内容。

因此,上面举例的字符串实际上是指向 commit 类型的文件对象。从这些类型的定义或叫说明上也能看出,blob 类型是最基础的文件对象类型,而 tag 是记录某一个次重要节点的文件对象类型。

Git 如何存储对象

Git 中存在两种对象,一种是松散对象,一种是打包对象。

SHA1

SHA1(Secure hash algorithm),即安全的hash算法,用于计算文本的校验和,常作为摘要算法对签名进行校验。它的特点是计算出的SHA1值是不可逆性切不重复的,也就是根据SHA1值无法反解出原始内容,并且对于相同的内容,每次计算得到的SHA1都相同。正因为这样的特性,它常用于验证数据的完整性以及消息的验证。SHA1算法可以得到160位二进制数,也就是40位16进制数。我们做一个简单的实验。mac下通过这个命令可以安装一个sha1算法的工具:

brew install md5sha1sum

操作如下:

# A.txt:A:version 1
sha1sum A.txt
# result:
# 2d8954f9fbf90f6da74b728bf3dfe4ad459865fe  A.txt

Git 基本用法

git init

以当前目录为根目录,初始化一个新的仓库,实际这条命令主要创建一个名为 .git 的隐藏目录。

git根目录.png
git clone https://github.com/iThinkerYZ/GPUImgeDemo.git

从已有仓库中复制/拷贝一份到本地,因此我们需要知道一个项目的仓库地址,Git 支持多种协议,因此,这些 url 可以是ssh://、http(s)://,、git:// 等。一般情况,clone 下来的仓库根目录名就是 url 最后的文件名。例如上面就会得到名为
GPUImgeDemo 的目录。

git status

查看当前 Git 目录(.git)的状态,可以列举出所有已经修改文件的状态。

git branch

查看本地所有分支,*号表示所在分支,-r 参数可以指定查看远程的所有分支。

git checkout some-branch/some-tag/some-commit

切换分支,其实就是切换到某个 commit 对象(根节点)

git add some-file

创建指定修改文件内容的文件对象(SHA1),同时添加文件对象到暂存区。可以 add 一个文件,也可以通过","分隔添加多个文件,还可以通过"."来匹配本地的所有修改文件。

git commit -m 'xxxxx'

提交暂存区的修改到本地仓库,同时添加注释内容。可以使用 git commit -am 'xxxxx' 进行add和commit

git pull

拉取远程到本地,其实完整的命令是 git pull origin current-branch。不过需要注意,如果本地文件有修改,拉取的内容可能跟本地的内容有冲突需要处理一下。

git push

推送本地提交到远程仓库。完整的命令是 git push origin current-branch。注意,如果远程有更新而本地没有拉取,会阻止本地的 push 动作并提示。

git reset

重置 HEAD 部分的修改到指定状态,通常该命令结合3种参数使用,--soft/--mixed/--hard。--hard 将会删除本地所有修改但没有提交的记录。

git revert

回滚本地的代码到指定某个提交的状态,同时将回滚内容作为一个新的修改进行提交。效果跟
reset相同,但是跟 reset 不同点在于,reset 是直接删除某个提交记录,但是 revert 不会。

git merge some-branch

将某个分支内容与当前分支合并。

git rebase

将从开始 merge 的那个状态以来的所有提交,以补丁的形式一个一个重新达到目标分支上,看起来就像一条线一样的工作流。

git stash

暂存当前分支的所有修改到临时区域,保持 HEAD 为最后一次 commit 状态。

git show

显示某个git 对象的详细信息

git diff

对比工作区与暂存区内容的不同,方便对比做了哪些修改。一般,在 commit 内容前最好检查一下,确保没有问题。

git tag

展示本地所有的 tag,另外,也可以通过 git tag new-tag 来新建一个 tag,通过 git tag -d some-tag 来删除本地的 tag。通过命令 git push --tag(s) 来推送本地更新的 tag 到远程仓库。一般,我们会在发版前更新 tag 作为稳定版本。

Git 中级用法

.gitignore

开发中,经常需要忽略一些文件的修改,既不追踪,也不会被加入到暂存区中,即保证 git commit、git add、git status 命令都不会处理这些文件的变化,保证高效完成版本文件管理。.gitignore文件就是用于解决这个问题。该文件需要手动创建和添加(有的git系统会自动创建并且是初始化好的),并加入现文件来告诉 Git 系统会略哪些文件。

GitHub 官方提供了各种语言对应项目的通用.gitignore模板,大家可以直接复用。
点这里

该文件的存放位置决定该目录及其子目录使用的忽略文件,因此,可以针对不同目录定制对应的.gitignore文件,当然了,一般做法是只在根目录(与 .git 目录同级)保存一份。

rebase

由于 git 是分布式的版本控制系统,因此少不了要处理不同并行分支合并的场景。在初级用法中简单介绍了该命令。
与 merge 的主要区别:merge 最终将合并的结果作为一次新的commit提交,当前分支修改以及已经提交的部分作为历史保留,rebase 首先将当前分支的提交以补丁的形式缓存,然后更新本地分支到最新,最后将缓存的补丁依次合到当前分支,最终分支历史看起来就像没有经过合并一样。
当遇到冲突的时候,rebase 命令会被暂停,等待冲突解决,解决玩冲突后,你只需要 git add 而无需 git commit,直接执行 git rebase --continue 继续处理;另外,任何时候,开发者都可以执行 git rebase --abort 命令终止 rebase 的动作,然后恢复至 rebase 开始前的状态。

rebase 除了让 Git 系统自动完成合并外,还可以交互式的进行。git rebase -i origin/master,输入命令后如下图:


交互式rebase.png

图中表示当前分支的暂存区只有一次提交,并且格式满足:

(action) (partial-sha) (short commit message)

pick对应的是 git 将采用并合并这次提交,如果用 squash 表示与上一个提交合并为一次提交,如果 为 edit,则当 git 处理到此次提交之后,返回命令行让你对提交进行修改,比如将提交拆分为多个等。最后,如果不采用任何一个 action 而是直接把某次提交删除,那么 git 就会直接从历史中移除该提交。

stash

git stash
git stash apply
git stash pop
git stash list
git stash pop stash${id}
git stash clear

上一篇 下一篇

猜你喜欢

热点阅读