本文主要学习命令
- git config:配置相关信息
- git clone:复制仓库
- git init:初始化仓库
- git add:添加更新内容到索引中
- git diff:比较内容
- git status:获取当前项目状况
- git commit:提交
- git branch:分支相关
- git checkout:切换分支
- git merge:合并分支
- git reset:恢复版本
- git log:查看日志
git介绍
注:这一部分摘自 实验楼
同生活中的许多伟大事件一样,Git 诞生于一个极富纷争大举创新的年代。1991年,Linus创建了开源的Linux,并且有着为数众多的参与者。虽然有世界各地的志愿者为Linux编写代码,但是绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-2002年间)。在这期间,所有的源代码都是由Linus手工合并。因为Linus坚定地反对CVS和SVN,这些集中式的版本控制系统(集中式和分布式我们会在接下来的内容讲解)不但速度慢,而且必须联网才能使用。虽然有一些商用的版本控制系统,比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。
不过,到了2002 年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是整个项目组启用了一个商业版本的分布式版本控制系统 BitKeeper 来管理和维护代码。BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。安定团结的大好局面在2005年被打破,开发BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,原因是Linux社区牛人聚集,开发Samba的Andrew试图破解BitKeeper的协议,这么干的其实也不只他一个,但是被BitMover公司发现了,于是BitMover公司收回了Linux社区的免费使用权。这就迫使Linux开源社区( 特别是Linux的缔造者 Linus Torvalds )不得不吸取教训,只有开发一套属于自己的版本控制系统才不至于重蹈覆辙。
他们对新的系统制订了若干目标:速度 、 简单的设计 、 对非线性开发模式的强力支持(允许上千个并行开发的分支)、完全分布式、有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)。自诞生于 2005 年以来,Git 日臻成熟完善,迅速成为最流行的分布式版本控制系统,在高度易用的同时,仍然保留着初期设定的目标。它的速度飞快,极其适合管理大项目,它还有着令人难以置信的非线性分支管理系统,可以应付各种复杂的项目开发需求。2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。
历史就是这么偶然,如果不是当年BitMover公司威胁Linux社区,可能现在我们就没有免费而超级好用的Git了。
Linus一直痛恨的CVS及SVN都是集中式的版本控制系统,而Git是分布式版本控制系统,集中式和分布式版本控制系统有什么区别呢?
先说集中式版本控制系统,版本库是集中存放在中央服务器的,而大家工作的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始工作,工作完成,再把自己的修订推送给中央服务器。这类系统,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。
那分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有"中央服务器",每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。
在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当"中央服务器"的电脑,但这个服务器的作用仅仅是用来方便"交换"大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
许多这类系统都可以指定和若干不同的远端代码仓库进行交互。籍此,你就可以在同一个项目中,分别和不同工作小组的人相互协作。你可以根据需要设定不同的协作流程,比如层次模型式的工作流,而这在以前的集中式系统中是无法实现的。
下载和打开 (windows 下)
msysgit是 windows版的Git,点击下载。
然后进行默认安装,完成后,在开始菜单里面找到 "Git --> Git Bash",点击打开,如下所示
Git 全局配置
在命令行输入:
$ git config --global user.name "enwa"
$ git config --global user.email chaoen.hu@radiomics.cn
执行了上面的命令后,会在用户目录(C:/users/en)下建立一个叫.gitconfig 的文件(该文件为隐藏文件,需要使用ls -al查看到). 内容一般像下面这样,可以使用cat查看文件内容:
因为Git是分布式版本控制系统,需要填写用户名和邮箱作为一个标识。
注意:git config --global 参数,有了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然你也可以对某个仓库指定的不同的用户名和邮箱。
创建仓库
英文名repository,你可以简单的理解一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改,删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻还可以将文件"还原"。
使用的命令
cd 转到目录;pwd 用于显示当前的目录; ls -la 列出当前目录下所有文件和目录(包含隐藏的,文件名前面带 . 如.gitconfig)
注,命令行可以使用Tab键补全,与linux 终端有点像像,盘符显示挂在根目录下,home目录就是用户目录
mkdir 新建一个文件夹
新建一个仓库
例如:在F:\ www 目录下新建一个EnwaGit仓库,过程如下
(1)新建一个文件夹,并转到其下
$ cd F:/www
$ mkdir EnwaGit
$ cd EnwaGit/
$ pwd
/f/www/EnwaGit
(2)进入到代码目录,创建并初始化Git仓库
$ git init
(注,./是当前目录,../是上一级目录,.git 是隐藏文件夹".git", 试试ls 看看与 ls –al的区别,好吧,这里有点白痴了)
目录下会有一个名叫.git 的目录被创建,这意味着一个仓库被初始化了。可以进入到.git目录查看下有哪些内容。
(注,显示隐藏文件夹才能看到)
使用仓库EnwaGit
概念
工作区:就是你在电脑上看到的目录,比如目录下EnwaGit里的文件(.git隐藏目录版本库除外)。或者以后需要再新建的目录文件等等都属于工作区范畴。
版本库,又称本地代码库(Repository):工作区有一个隐藏目录.git,这个不属于工作区,这是版本库。其中版本库里面存了很多东西,其中最重要的就是本地的缓存区,还有Git为我们自动创建了第一个分支master,以及指向master的一个指针HEAD。
具体来说,使用Git提交文件到本地代码库(版本库)有两步:
第一步:是使用 git add 把文件添加进去,实际上就是把文件添加到本地的缓存区。
第二步:使用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支上。
git的基本流程如下:
创建或修改文件
使用git add命令添加新创建或修改的文件到本地的缓存区(Index)
使用git commit命令提交到本地代码库
(可选,有的时候并没有可以同步的远端代码库)使用git push命令将本地代码库同步到远端代码库
创建或修改文件
在EnwaGit文件夹下,即工作区,新建一个enwa.txt 内容如下:嗯,哇,
同理,再新建一个readme.txt 内容如下:this is test
此时可以使用git status命令查看当前git仓库的状态:
可以发现,有2个文件处于untracked状态,下一步我们就需要用git add命令将他们加入到缓存区(Index)。
用git add命令将他们加入到缓存区(Index)
$ git add enwa.txt readme.txt
然后再次执行git status就会发现新的变化:
你现在为commit做好了准备,你可以使用 git diff 命令再加上 --cached 参数,看看缓存区中哪些文件被修改了。进入到git diff --cached界面后需要输入q才可以退出:
$ git diff --cached
如果没有--cached参数,git diff 会显示当前你所有已做的但没有加入到索引里的修改。
如果你要做进一步的修改, 那就继续做, 做完后就把新修改的文件加入到缓存区中。
例如:此时输入 git diff 返回空,但是我们给readme.txt 添加一行'hello world'。再输入git diff,如下图,工作区和缓冲区的有不同,就需要再执行git add 把最新版的加入缓冲区
当所有新建,修改的文件都被添加到了缓存区,我们就要使用git commit提交到本地仓库:
使用git commit提交到本地仓库
$ git commit -m "add 2 files"
需要使用-m添加本次修改的注释,完成后就会记录一个新的项目版本。除了用git add 命令,我们还可以用下面的命令将所有没有加到缓存区的修改也一起提交,但-a命令不会添加新建的文件。
$ git commit -a -m "add 2 files"
再次输入git status查看状态,会发现当前的代码库已经没有待提交的文件了,缓存区已经被清空。
en@DESKTOP-6DCERIO MINGW64 /f/www/EnwaGit (master)
$ git status
On branch master
nothing to commit, working tree clean
至此,我们完成了第一次代码提交,这次提交的代码中我们创建了2个新文件。
Clone一个仓库
为了得到一个项目的拷贝(copy),我们需要知道这个项目仓库的地址(Git URL). Git能在许多协议下使用,所以Git URL可能以ssh://, http(s)://, git://. 有些仓库可以通过不只一种协议来访问。
在github.com上提供了一个名字为gitproject的供大家测试的公有仓库,这个仓库可以使用下面方式进行clone:
$ git clone https://github.com/shiyanlou/gitproject
clone操作完成后,会发现当前目录下多了一个gitproject文件夹,这个文件夹里的内容就是刚刚clone下来的代码。由于当前`gitproject仅是测试项目,里面仅有一个README.md文件。
$ cd gitproject/
(master)$ ls
README.md
分支与合并
Git的分支可以让你在主线(master分支)之外进行代码提交,同时又不会影响代码库主线。分支的作用体现在多人协作开发中,比如一个团队开发软件,你负责独立的一个功能需要一个月的时间来完成,你就可以创建一个分支,只把该功能的代码提交到这个分支,而其他同事仍然可以继续使用主线开发,你每天的提交不会对他们造成任何影响。当你完成功能后,测试通过再把你的功能分支合并到主线。
分支
一个Git仓库可以维护很多开发分支。现在我们来创建一个新的叫enwa_branch的分支:
$ git branch enwa_branch
运行git branch命令可以查看当前的分支列表,以及目前的开发环境处在哪个分支上:
$ git branch
enwa_branch
* master
enwa_branch分支是你刚才创建的,master分支是Git系统默认创建的主分支。星号标识了你当工作在哪个分支下,输入git checkout 分支名可以切换到其他分支:
$ git checkout enwa_branch
Switched to branch 'enwa_branch'
切换到enwa_branch分支,切换完成后,先编辑里面的一个文件,再提交(commit)改动,最后切换回 "master"分支:
# 修改文件enwa.txt
$ echo "update" >> enwa.txt
# 查看当前状态
$ git status
# 添加并提交enwa.txt的修改
$ git add enwa.txt
$ git commit -m "update enwa.txt"
# 查看enwa.txt的内容
$ cat enwa.txt
# 切换到master分支
$ git checkout master
(乱码是因为不支持中文显示,我没有设置)
查看下enwa.txt中的内容会发现刚才做的修改已经看不到了。因为刚才的修改时在enwa_branch分支下,现在切换回了master分支,目录下的文件都是master分支上的文件了。
现在可以在master分支下再作一些不同的修改:
# 修改文件readme.txt
$ echo "update again">> readme.txt
# 查看当前状态
$ git status
# 添加并提交readme.txt的修改
$ git add readme.txt
$ git commit -m "update readme.txt on master"
# 查看readme.txt的内容
$ cat readme.txt
这时,两个分支就有了各自不同的修改,分支的内容都已经不同,如何将多个分支进行合并呢?
可以通过下面的git merge命令来合并enwa_branch到主线master:
# 切换到master分支
$ git checkout master
# 将experimental分支合并到master
$ git merge -m 'merge enwa_branch to master' enwa_branch
-m参数仍然是注释信息。
由于两个branch修改了两个不同的文件,所以合并时不会有冲突,执行上面的命令后合并就完成了。
如果有冲突,比如两个分支都改了同一个文件,则合并时会失败。首先我们在master分支上创建enwa2.txt并提交:
然后切换到分支,修改enwa2.txt并提交:
切换到master进行合并:
合并失败后先用git status查看状态,:
上面的内容也可以使用git diff查看,先前已经提到git diff不加参数可以显示未提交到缓存区中的修改内容。
可以看到冲突的内容都被添加到了enwa2.txt中,
我们使用notepad++编辑这个文件,去掉git自动产生标志冲突的<<<<<<等符号后,根据需要只保留我们需要的内容后保存,
然后使用git add enwa2.txt和git commit命令来提交合并后的内容,这个过程是手动解决冲突的流程。
当我们完成合并后,不再需要分支时,可以使用下面的命令删除:
$ git branch -d enwa_branch
git branch -d只能删除那些已经被当前分支的合并的分支. 如果你要强制删除某个分支的话就用git branch –D
撤销一个合并
如果你觉得你合并后的状态是一团乱麻,想把当前的修改都放弃,你可以用下面的命令回到合并之前的状态:
$ git reset --hard HEAD^
# 查看file3的内容,已经恢复到合并前的master上的文件内容
$ cat file3
快速向前合并
还有一种需要特殊对待的情况,在前面没有提到。通常,一个合并会产生一个合并提交(commit), 把两个父分支里的每一行内容都合并进来。
但是,如果当前的分支和另一个分支没有内容上的差异,就是说当前分支的每一个提交(commit)都已经存在另一个分支里了,git 就会执行一个"快速向前"(fast forward)操作;git 不创建任何新的提交(commit),只是将当前分支指向合并进来的分支。
日志
1.查看日志
git log命令可以显示所有的提交(commit):
$ git log
如果提交的历史纪录很长,回车会逐步显示,输入q可以退出。
git log有很多选项,可以使用git help log查看,例如下面的命令就是找出所有从"v2.5"开始在fs目录下的所有Makefile的修改:
$ git log v2.5.. Makefile fs/
Git会根据git log命令的参数,按时间顺序显示相关的提交(commit)。
2.日志统计
如果用--stat选项使用'git log',它会显示在每个提交(commit)中哪些文件被修改了, 这些文件分别添加或删除了多少行内容,这个命令相当于打印详细的提交记录:
$ git log --stat
3.格式化日志
你可以按你的要求来格式化日志输出。--pretty 参数可以使用若干表现格式,如oneline:
$ git log --pretty=oneline
或者你也可以使用 short 格式:
$ git log --pretty=short
你也可用medium,full,fuller,email 或raw。如果这些格式不完全符合你的需求,你也可以用--pretty=format参数定义格式。
--graph 选项可以可视化你的提交图(commit graph),会用ASCII字符来画出一个很漂亮的提交历史(commit history)线:
$ git log --graph --pretty=oneline
4.日志排序
日志记录可以按不同的顺序来显示。如果你要指定一个特定的顺序,可以为git log命令添加顺序参数。
按默认情况,提交会按逆时间顺序显示,可以指定--topo-order参数,让提交按拓扑顺序来显示(就是子提交在它们的父提交前显示):
$ git log --pretty=format:'%h : %s' --topo-order --graph
你也可以用 --reverse参数来逆向显示所有提交日志。
参考:http://blog.csdn.net/free_wind22/article/details/50967723 和 实验楼