Repository git
使用GIT管理一个项目的时候,就须要一个仓库(repository)用于存放GIT对项目管理所必需要保存的各类文件,使用 git init 命令建立一个新的仓库。GIT会在当前目录下建立一个.git文件夹,用做仓库。而后,当你使用GIT记录每一次代码改动的时候,GIT就会把须要的信息都放到这个文件夹下面。
github
Commit 算法
每当你完成一个改动(change)的时候,就能够commit一下,记录当前项目的状况(snapshot)。每个commit包含以下信息:
- commit-id(sha-id):这是一个经过sha-1算法算出来的一个id,它不仅做为每一个commit的惟一识别码,也能够用来验证保存的代码是否损坏。因此在GIT在管理代码的时候,若是发生代码损坏,能够颇有效的检测到。
- author:做者
- date: 日期时间
- log messge:一段做者对代码改动的文字描述。
- change-id:若是是和repo、gerrit一块儿使用的话,repo会加上这个信息,以便在整个代码系统中识别同一个改动的多个版本。
用代码管理软件管理代码的时候,有个理念就是:每次改动提交之后,整个项目都应该是能够工做的。因此,每次commit最好都能是这样的的改动,虽然这不是必须的,可是这样对项目总体质量的提升颇有好处。
在GIT使用中,一个change开发的常见工做流程大概是这样的:
- 新建一个工做分支(topic branch)
- 做一些代码改动
- 查看当前状态(很经常使用!):git status 查看当前branch以及那些文件有改动;git diff 查看目前为止的详细的改动状况。
- git add xxx 将这些改动暂时归档。在不少时候,一个change包含的东西并很多,咱们在作到一半的时候一般也须要暂时保存一些东西。使用git add会将指定的文件的现有改动暂时保存下来(这个暂时归档的地方,GIT称它为staging area,能够认为是一个临时的snapshot。顺便说一下HEAD,在GIT中,HEAD老是指向项目当前状态最近的一次正式的snapshot。)。git add . 会将全部改动暂时归档。
- git reset xxx 将某个文件从staging area中移出来。git reset 不带参数的时候,就是将staging area中全部的文件移出。
- 查看staging area中的详细改动:git diff --cached
- 继续写代码,git add xxx 将新的改动归档。
- 当你发现你的改动很是不合理,想要取消这些改动的时候:git checkout xxx 将某个文件恢复到修改以前(最后一次snapshot)。git checkout . 会恢复全部的文件到修改以前的状态,很方便的功能,但使用的时候必定注意,不要让本身的心血付诸流水。
- 重复上面的步骤,直到你认为你的改动已经能够做为一个有效的change,那你就能够执行 git commit 来将当前的改动真正的保存下来。记得在commit message里面写上适当的描述信息,这样在查看代码历史的时候,就能方便的知道每一个change都干了些什么。
- 有时候,你commit之后,你还发现还有须要修改的地方(特别是让别人review的话,commit以后须要屡次改动也是很常见的事情),那么你就重复上面的步骤,不过在最后commit的时候加上 --amend 参数,这样,它就会将目前的修改内容添加到最近的一次commit。若是忘记/误用了 --amend 参数的时候怎么办呢?只要在编辑commit message的时候把内容所有清空,保存退出,GIT就会放弃此次commit。
- 根据状况,将这个改动合并(merge)回原来的主分支
Tag
在git中,每个commit都是一个项目当时的snapshot,tag的做用就是给commit打上标签。好比你当项目进行到某一点,你以为能够发布(release)一下,那你就能够在这个位置作一个标记,打一个tag,一个发布点就被明确的标示出来了,这样能够方便的对项目的状况进行管理。我一般把它理解为某个commit的别名。GIT对项目的版本管理一般就是在这里体现的。因为tag一般是用于项目发布管理的,因此一般是项目管理人员来使用它。
查看tag状况:git tag
新建一个tag:git tag <tagname> <commitid>
删除一个tag:git tag -d <tagname>
查看帮助:git tag -h 服务器
Branch
GIT最方便的莫过于本地分支(branch)的使用了。就开发来说,你须要尝试你的各类想法,就发布项目来讲,不一样的
branch可让你有效的管理各个版本软件的发布以及维护。这里只说说开发。
查看
branch:
git branch命令就能够查看本地当前的全部
branch。经常使用的参数有:
-r 查看远程(remote)的branch
-a 查看(本地+远程)全部branch
-v 查看
branch的时候显示每一个
branch的最后一个commit信息
跳转到一个
branch:
你任什么时候候只能在某一个branch上面,或者某一个特定的snapshot。
git checkout branchname 跳转到某一个branch
git checkout sha1/tag 跳转到某个指定的snapshot,这是你不在任何一个branch上面。
新建一个
branch:
git branch newbranch 从项目当前所在的commit建立一个branch
git checkout sha1/tag -b newbranch 从某一个指定的snapshot建立一个新的branch,并跳转到新建的branch
git checkout remote_branch -b newbranch 以某个远程branch最新的一个snapshot为基础建立一个新的branch,注意这不会影响远程
branch,由于他的实质和上面实际上是同样的。
那么咱们该如何使用
branch呢?首先,你要知道GIT是个分布式的代码管理工具,在你没有和远程代码仓库交流的时候,你的任何改动都是本地的,不用担忧影响到远程代码仓库。而你只要不刻意去破坏你本地的仓库,那么,就大胆的使用
branch吧,作各类尝试。任什么时候候你有一个新的想法,在本地建一个
branch尽情的去尝试,很快你就会喜欢上这东西的。
若是是个多人协做项目的话,一般你的工做并不仅是改动一个地方,那么当你完成了某一个change正在等待review的时候,你就能够新起一个branch,接着就开始你的另外一个change了。
Merge
有了分支你就能够尽情的作各类尝试,为所欲为的写代码。但咱们一般是有一个主干分支,而后咱们把每一个成熟的改动的合并(merge)到咱们的主干,这样,项目才真正有效的在前进。这个工做流程就完美的解决了多人协做开发项目的问题:由于每一个人都是在本身的本地工做区进行修改,互不影响,在完成后将本身的成果放进主仓库(某个remote repository)就能够了,最坏的状况就是可能会有些代码冲突,但代码冲突一般并非什么很难解决的问题:毕竟在分配任务的时候就会有大体进行安排,因此通常是不会有什么没法解决的冲突。
说到merge的话,不少时候有人就会和rebase搞混。虽然两个命令的功能都是把两个branch合并起来,可是仍是有很大差异的。
rebase主要用于以下情形:在多人协做的项目中,当你完成了一个改动之后,你发现别人已经在远端主代码仓库添加了不少改动了,这时候极可能会有代码冲突,或者已经有代码冲突,那这时候,你就须要把你当前的工做branch更新到最新的状态,而后解决代码冲突,而后再提交你的change。这时候,你就:
- 从远端获取最新的代码
- git rebase xxx 更新你当前的branch到最新状态,而后把你的代码改动放在最上面
- 向远端提交代码
而merge的话,就只是简单的将两个branch合并,若是出现GIT没法处理的冲突的时候,那么就先采起上面的步骤,而后在merge。在Android的工做环境中,咱们一般是不须要使用merge这个操做的,这个操做是在gerrit里面完成review之后,点merge按钮来完成的。
查看历史
最经常使用的查看项目历史(其实是某个分支的历史)的命令就是git log,常见用法以下:
- git log 查看项目从当前位置(最近一个snapshot)以前的历史记录。能够这么来理解:当你在某个branch上面的时候,这个snapshot就是当前分支的最新的一个comit,当你不在一个branch上面的时候,就是当前状况下最新的那个commit。
- git log shaid/tag 同上,不过指定了snapshot的位置
- git log file_name 同上上,不过查看的是特定文件相关的改动记录
- git log branch 查看特定branch的历史记录
- git log branch file_name 同上,不过查看的是特定文件相关的改动记录
- git log --no-merges 因为GIT在进行merge的时候,会自动生成一个merge的commit,但其实这个commit自己是没有内容的,--no-merges这个参数的做用就是在查看log的时候忽略这种commit。
这个命令能够知足大部分须要查询历史记录的状况,但有时候,你须要一个更强大的工具,那就是GITK。在当前branch下面,使用gitk命令,就可使用gitk查看当前项目状态以前的历史记录。它是一个有界面的工具,基本上是一目了然的,因此我也不过多的介绍,花几分钟去试试它吧。
Remote
GIT既然是分布式代码管理工具,那么就必然涉及到远程的交互了。GIT和远端的交互能够经过常见的HTTP、HTTPS,在比较正式的项目中,一般是基于SSH的GIT协议。
以github.com为例,上面支持3种方式:
在Android系统的管理中,因为和服务器的交互都是封装在repo这个工具里面,因此,一般是不须要用到remote操做的。因此只简单说一下:
git remote 查看当前已添加的远程服务器
git remote -v 同上,不过显示更详细的信息
git remote -h 查看帮助
其余
.gitignore
在开发一个项目的时候,有时候总会有些项目无关的文件,好比bin文件夹下面的内容,通常是不须要用GIT管理起来的。这时候,你就把这些文件的信息写到.gitignore里面,而后,把.gitignore的改动使用GIT管理起来,这样,GIT在查询状态的时候,就会忽略在.gitignore里面提到的文件。
color & alias
GIT能够给各个命令的输出结果加上适当的颜色以提升视觉识别度,只须要简单的配置便可。若是你嫌有些GIT命令太长,每次打完太麻烦,不要紧,有办法,添加别名。
所以我一般会在个人/etc/gitconfig文件中加入以下的内容:
[color]
ui = auto
[alias]
st = status
cm = commit
cma = commit --amend
br = branch -v
cp = cherry-pick
co = checkout
df = diff
dfc = diff --cached
如何使用alias:以第一个为例,当我想用git status的时候,我打git st就能够了。
小结
GIT的功能很丰富,上面说的这些不过是一些经常使用的功能而已,要想把每一个细节都说清楚的话,还远远不够。想要用好GIT,还须要在实际运用中进行实践和进一步学习。