Git是一种分布式版本控制工具,现阶段比较流行的版本控制工具主要分为:集中式版本控制工具盒分布式版本控制工具。
集中式版本控制工具:SVN和CVS为代表
集中式版本控制系统(每次都得从SVN服务器数据中心去拿数据):
分布式版本控制系统:
在Windows上安装Git工具:
msysgit是Windows版的Git,从http://msysgit.github.io/下载,然后按默认选项安装即可。
安装完成后,在开始菜单里找到"Git"->"Git Bash",蹦出一个类似命令行窗口的东西,就说明Git安装成功!
安装完成后,还需要最后一步设置,在命令行输入:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
创建版本库:
什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以"还原"。
首先,我们需要创建一个空目录在合适的目录下(为了避免出现一些识别问题,在Windows下面最好使用英文的文件名命名,别使用中文字符):
然后,通过git init初始化这个目录,让这个目录成为Git可以管理的仓库(初始化完成后,你可以发现该文件夹下会出现一个.git的文件夹):
为了下面的讲价更加方便,所以我们用一个.txt的文件来作为演示的例子。
我们创建一个文件 "Git2Test1.txt",这个文件一定建立在初始化后的文件夹或者该文件夹的子文件夹下(Git2),
添加文件到版本库:
如果我们想把这个文件"Git2Test1.txt"成功的添加到一个Git仓库中,我们只需要两步:
- git add Git2Test1.txt (先把文件通过命令 add添加到仓库,可反复多次使用,添加多个文件)
-
Git commit -m "new1" (然后通过命令 commit 提交到仓库,
简单解释一下git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
嫌麻烦不想输入-m "xxx"行不行?确实有办法可以这么干,但是强烈不建议你这么干,因为输入说明对自己对别人阅读都很重要。实在不想输入说明的童鞋请自行Google,我不告诉你这个参数。
)
文件版本回退:
在文件Git2Test1.txt中添加一行内容,通过 git status查看当前文件的状态,通过 git diff file可以看到文件有什么变化,查看修改后文件的变化
在执行第一步git add之后,在执行第二步git commit之前,我们再运行git status看看当前仓库的状态:
在执行完第二步git commit之后,我们再运行git status看看当前仓库的状态:
通过 git log 可以查看文件在仓库中有几个版本(2338c....eeaa9b代表的是commit id的版本号,在git中用 HEAD表示当前的版本,上一个版本就是HEAD^ 上上个版本就是HEAD^^,如果是上100个版本可以用 HEAD~100):
通过 git reset --hard HEAD^命令回到之前的版本,
如果我又想回到new2, 可以通过 git reset --hard commit id (前几位数)这个版本:
要是我们不知道 commit id号了,又想回到某个版本怎么办呢? 可以通过git reflog 查看log的历史版本
工作区和暂存区
到这大家一定会有一定的疑惑关于版本回退和HEAD这块,如果我们想弄清楚这块,那我们就需要了解一个新的概念:工作区和暂存区
工作区(Working Directory):就是你在电脑里能看到的目录,比如我的Git2文件夹就是一个工作区:
版本库(Repository):工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
分支和HEAD的概念我们以后再讲。
前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
俗话说,实践出真知。现在,我们再练习一遍,先对readme.txt做个修改,比如加上一行内容:
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
然后,在工作区新增一个LICENSE文本文件(内容随便写)。
先用git status查看一下状态:
$ git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: readme.txt
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# LICENSE
no changes added to commit (use "git add" and/or "git commit -a")
Git非常清楚地告诉我们,readme.txt被修改了,而LICENSE还从来没有被添加过,所以它的状态是Untracked。
现在,使用两次命令git add,把readme.txt和LICENSE都添加后,用git status再查看一下:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: LICENSE
# modified: readme.txt
#
现在,暂存区的状态就变成这样了:
所以,git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。
$ git commit -m "understand how stage works"
[master 27c9860] understand how stage works
2 files changed, 675 insertions(+)
create mode 100644 LICENSE
一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是"干净"的:
$ git status
# On branch master
nothing to commit (working directory clean)
现在版本库变成了这样,暂存区就没有任何内容了:
:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。
:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令,第二步按场景1操作。
:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。
:
场景2:
Git 文件的删除
如果被删除的文件已经被commit,我们只是从工作区间中将文件删除 (rm的命令,我们还能通过git checkout 的命令将文件恢复到最新的版本)
如果被删除的文件已经被commit,我们从git区间去删除文件,(git rm file,被删除的文件将不能恢复)
Git创建远程库(关联到GitHub)
步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:
$ ssh-keygen -t rsa -C "youremail@example.com"
你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。
如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
步:登陆GitHub,打开"Account settings","SSH Keys"页面:
然后,点"Add SSH Key",填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容
要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git;
关联后,使用命令git push -u origin master第一次推送master分支的所有内容;
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;
分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在,也就是有没有联网都可以正常工作,而SVN在没有联网的时候是拒绝干活的!当有网络的时候,再把本地提交推送一下就完成了同步,真是太方便了!
从远程仓库克隆到本地仓库
要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。
Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。
Git 分支的基本使用:
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
工作区是干净的,刚才的工作现场存到哪去了?用git stash list命令看看
修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。