一:起因
(0):最先听说的版本管理系统是svn,那是大学本科期间接触的了,当时也没有多想 —— 一个带我们的学长,告诉我们如何如何操作;
(1):研究生就开始接触GIT,当时也是仅仅了解几个常用的命令,仅仅能够使用简单的日常所需要的命令;也没有深入的系统的了解,现在终于停下匆忙的脚步,思考一番,打算在这里做一个简单的小结
(2):分布式版本管理神器--GIT —— 最初由Linus Torvalds编写,用作Linux内核代码的管理。在推出后,Git在其它项目中也取得了很大成功,尤其是在Ruby社区中。(来自百度百科)
二:基本知识小结
(0)GIT安装(本人是在Ubuntu下面操作的) —— sudo apt-get install git,Windows下的安装网上也有教程,在此不一一细说
配置 git: # 常用的命令都设置alias,尽量少敲键盘 git config --global alias.br branch git config --global alias.ci commit git config --global alias.co checkout git config --global alias.st status # 很好看地显示git log git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen (%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --" # 设置用户信息 git config --global user.name "Your Name" git config --global user.email [email protected] # 缺省使用颜色显示 git config --global color.ui true
(1)本地版本库的增(add)删(delete)操作 参考自 http://www.liaoxuefeng.com/wiki
1)创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录: $ mkdir learngit $ cd learngit $ pwd /Users/michael/learngit pwd命令用于显示当前目录。在我的Mac上,这个仓库位于/Users/michael/learngit。 第二步,通过git init命令把这个目录变成Git可以管理的仓库: $ git init Initialized empty Git repository in /Users/michael/learngit/.git/
2)一定要放到learngit目录下(子目录也行),因为这是一个Git仓库,放到其他地方Git再厉害也找不到这个文件。
添加文件到Git仓库,分两步:
第一步,使用命令git add <file>,注意,可反复多次使用,添加多个文件;
第二步,使用命令git commit,完成。
要随时掌握工作区的状态,使用git status命令。
如果git status告诉你有文件被修改过,用git diff file-name可以查看修改内容
3)HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区
版本库(Repository)
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
4)现在,你又理解了Git是如何跟踪修改的,每次修改,如果不add到暂存区,那就不会加入到commit中。
命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
又到了小结时间。
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。
(2)分支操作
创建分支:git branch <branchname>分支,git merge <branchname>合并分支到当前分支上(查看当前分支git branch);删除分支git branch -d <name>;切换分支git checkout <name>
因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。
小结Git鼓励大量使用分支:
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
注意:当Git无法自动合并分支时,就必须首先手动解决冲突(就是把冲突的两个文件的内容修改为一样的,也就是说两个文件同时修改了,但是修改的又不一样)。解决冲突后,再提交,合并完成。用git log --graph命令可以看到分支合并图。
$ git merge --no-ff -m "merge with no-ff" dev
因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
(3)分支的管理
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了;
例如:(假设master 和 dev已经存在) git branch dev_zyp(创建个人开发分支) --> git checkout dev_zyp(在个人开发分支上开发) --> git checkout dev(切换到dev分支,进行合并) --> git merge dev_zyp(把个人最新的开发结果合并到dev上) --> git branch -d dev_zyp( 删除 )
(4)来了新的紧急任务,但是原来的任务还没有完成,怎么办?
( 新的紧急任务来到 --> git stash(保存现场) --> git branch bug_zyp(创建,如(3)中步骤) --> 最后git branch -d but_zyp;;; 回到现场git stash pop)
修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。
首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支:
$ git checkout master Switched to branch 'master' Your branch is ahead of 'origin/master' by 6 commits. $ git checkout -b issue-101 Switched to a new branch 'issue-101' $ git checkout master Switched to branch 'master' Your branch is ahead of 'origin/master' by 2 commits. $ git merge --no-ff -m "merged bug fix 101" issue-101 Merge made by the 'recursive' strategy. readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) $ git branch -d issue-101 Deleted branch issue-101 (was cc17032).
太棒了,原计划两个小时的bug修复只花了5分钟!现在,是时候接着回到dev分支干活了!
(5)多人模式的开发
git push origin branch-name推送自己的修改;
如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
(6)远程仓库和本地仓库关联 或 克隆
小结 (要关联一个远程库,使用命令)git remote add origin [email protected]:path/repo-name.git --> (关联后,使用命令git push -u origin master第一次推送master分支的所有内容;)git push -u origin master --> git push origin master
1)首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库:
在Repository name填入learngit(你的本地仓库的名称),其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库:
在本地的learngit仓库下运行命令:
$ git remote add origin [email protected]:michaelliao/learngit.git
把上面的michaelliao替换成你自己的GitHub账户名;添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。
2)下一步,就可以把本地库的所有内容推送到远程库上:
$ git push -u origin master
把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master
分支关联起来,在以后的推送或者拉取时就可以简化命令
3)只要本地作了提交,就可以通过命令:
$ git push origin master
把本地master分支的最新修改推送至GitHub,现在,你就拥有了真正的分布式版本库!
(7) 上次我们讲了先有本地库,后有远程库的时候,如何关联远程库
现在是你的开发团队有一个公开的GitHub远程库,一个还有大部分功能的远程库了,你作为一个新的加入者,首先需要从远程库克隆一个到本地:
即远程库已经准备好了,下一步是用命令git clone克隆一个本地库:
$ git clone [email protected]:michaelliao/gitskills.git Cloning into 'gitskills'... remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0) Receiving objects: 100% (3/3), done. $ cd gitskills $ ls README.md