Git上手指南
(写在最前:这篇随笔是我在学习git时参考资料+实践出来的,其中一些问题是在实践中遇到的,希望对大家有帮助,还有很多不完整的地方。如果有什么错误的地方欢迎随时向我提出来)
在Git教程之前,我们先来了解Git
【Git是什么】
Git是目前世界上最先进的分布式版本控制系统。版本控制系统可以保留一个文件集合的历史记录,并能回到文件集合到另一个状态(历史记录状态)。另一个状态可以是不同的文件,也可以是不同的文件内容。在一个分布版本控制系统中,每个人都有一份完整的源代码(包括源代码所有的历史记录信息),而且可以对这个本地的数据进行操作。
【SVN和Git的区别】
SVN是集中式版本控制系统,版本库放在中央服务器,工作时使用的是自己的电脑。
Git是分布式版本控制系统,没有中央服务器,每台电脑就是一个完整的版本库。
【快速上手Git】
《下载windows客户端》
按照默认设置进行安装即可,在开始菜单里面找到 “ Git Bash”,如下:
如果没有找到,就在你的安装目录里找。打开后,弹出一个类似命令窗口的东西,如下
《查看/切换git所在目录》
用pwd命令查看你的git所在目录,一般情况下git初始目录在c:/users/Administrator,每当你初次打开bash,目录都会指向这里。
如果我的工程文件夹为: E:workspace,可以用cd /e/workspace切换到我希望的文件夹。用pwd查看我们所在的目录,如下:
《操作Git》
1)给Git添加用户
申请一个github账号,假设这个账号用户名:xxx 邮箱为:xxx@163.com
git config --global user.name "xxx"
git config --global user.email "xxx@163.com"
这个用户名就是我们的github账号。
注意:git config –global 参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然你也可以对某个仓库指定的不同的用户名和邮箱。
2)创建Git版本库
就是把项目文件夹初始化变成git仓库。 例如在/e/workspace 目录下,你的项目文件夹为testgit,使用命令:
mkdir testgit //创建目录
cd testgit //进入test目录
pwd //显示当前目录
git init //把这个目录变成git可以管理的仓库
这时候你当前testgit目录下会多了一个.git的目录,这个目录是Git来跟踪管理版本的,没事千万不要乱改这个里面的文件,否则,会把git仓库给破坏了。如果没有看到.git的目录,那是因为被隐藏了。在testgit目录下,选择“工具”——“文件夹选项”,打开“文件夹选项”窗口,再选择“查看”选项卡,在“高级设置中”选择“显示隐藏的文件...”,确定即可看到.git的文件夹。
3)把文件添加到版本库中
所有的版本控制系统,只能跟踪文本文件的改动,比如txt文件,网页,所有程序的代码等,Git也不列外,版本控制系统可以告诉你每次的改动,但是图片,视频这些二进制文件,虽能也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是知道图片从1kb变成2kb,但是到底改了啥,版本控制也不知道。
先看一下demo演示
我在版本库testgit目录下新建一个记事本文件 demo1.txt 内容如下:1111
第一步:使用命令 git add demo1.txt添加到暂存区里面去。
第二步:用命令 git commit告诉Git,把文件提交到仓库。(-m表示给这次提交进行备注,备注时建议写上名字和时间,方便查看)
现在我们已经提交了一个demo1.txt文件了,我们下面可以通过命令git status来查看是否还有文件未提交,如下:
现在继续来改下demo1.txt内容,比如我在下面添加一行2222内容,继续使用git status来查看下结果,如下:
上面的命令告诉我们 demo1.txt文件已被修改,但是未被提交的修改。
查看demo1.txt文件被修改的内容:git diff demo1.txt
可以看到demo1.txt文件内容从一行1111改成 二行 添加了一行2222内容。
知道了对demo1.txt文件做了什么修改后,就可以放心的提交到仓库了,提交修改和提交文件是一样的2步(第一步是git add 第二步是:git commit)。
4)版本回退
继续对demo.txt文件进行修改,再增加一行内容为3333,继续执行命令如下:
现在已经对demo.txt文件做了三次修改,查看历史记录:git log(显示从最近到最远的日志)
如果觉得显示的信息太多了,可以使用命令 git log –-pretty=oneline
版本回退操作
把当前的版本回退到上一个版本。可以用2种命令:
第一种:git reset –hard HEAD^ (回退到上上个版本:HEAD^^ 以此类推)
第二种:git reset –hard HEAD~100(回退到前100个版本用上面的方法肯定不方便,可以用这种)
未回退之前的readme.txt内容
如果想回退到上一个版本的命令如下操作:
此时demo1.txt中的内容如下如果想回退到上一个版本的命令如下操作:
还能通过,cat demo1.txt查看demo1中的内容
恢复
可以通过版本回退来恢复
git reset -head 版本后
通过如下命令即可获取到版本号:git reflog
增加内容3333的版本号是 e5ff1bc,现在可以用命令git reset –hard e5ff1bc来恢复了
《工作区和暂存区》
工作区:就是你在电脑上看到的目录,比如目录下testgit里的文件(.git隐藏目录版本库除外)。或者以后需要再新建的目录文件等等都属于工作区范畴。
版本库(Repository):工作区有一个隐藏目录.git,这个不属于工作区,这是版本库。其中版本库里面存了很多东西,其中最重要的就是stage(暂存区),还有Git为我们自动创建了第一个分支master,以及指向master的一个指针HEAD。
前面说的git提交文件到版本库有两步:
第一步:使用 git add 把文件添加进去,实际上就是把文件添加到暂存区。
第二步:使用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支上。
给demo1.txt文件再添加一行4444,新建一个test.txt文件,内容为test。
现在,用git add命令把2个文件添加到暂存区中,再git status查看状态
然后用git commit一次性提交到分支上
《Git撤销修改和删除文件》
1)撤销修改
现在再demo1.txt中新增一行5555,先通过命令查看:
在提交钱,突然发现添加的5555内荣有错,现在得恢复之前的版本,有2种方法修改:
第一:如果知道要删掉哪些内容,直接手动更改。再add添加到暂存区,最后commit
第二:按之前的方法直接恢复到上一个版本。git reset -hard HEAD^
除了上面2种方法,还可以在撤销前,用git status查看当前状态,git会告诉我们,git checkout --file可以丢弃工作区修改
使用命令:git checkout - demo1.txt把demo.txt文件在工作区做的修改全部撤销。这里有2种情况:
1、demo.txt自动修改后,还没放到暂存区,使用撤销修改就回到和版本库一模一样的状态。
2、demo.txt已经放入暂存区,接着又作了修改,撤销修改就会回到添加暂存区后的状态。
注意:命令git checkout — readme.txt 中的 — 很重要,如果没有 — 的话,那么命令变成创建分支了。
2)删除文件
在版本库testgit目录添加一个no.txt然后提交。
如果我想彻底从版本库中删掉了此文件的话,可以再执行commit命令 提交掉,现在目录是这样的:
可以看见no.txt文件不见了。只要没有commit前,都可以从版本库中恢复文件,方法如下:
使用命令 git checkout — no.txt
再来看一下testgit目录:
《远程仓库》
1)创建ssh免密码登录
你的本地Git仓库和github仓库之间的传输是通过SSH加密的,所以需要一点设置:
第一步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果有的话,直接跳过此如下命令,如果没有的话,打开命令行,输入如下命令:
ssh-keygen -t rsa –C “youremail@example.com” 运行后会让你输入什么东西,全部回车处理!如下所示:
id_rsa(锁)和id_rsa.pub(钥匙)。前一个文件叫私钥,后一个叫公钥,分别表示锁和钥匙。注意锁不能给别人,不然别人就可以冒充你了,你可以把钥匙给别人,这样别人就可以很方便地访问你而不需要密码。
登录github网站,点击头像旁的下拉菜单,点击setting按钮,选择SSH keys菜单项,然后点击New SSH key。这个时候将你的id_rsa.pub里的内容(用记事本打开)粘贴复制到key文本框中,然后给他取个名字,最后点OK。
2)添加远程库
已经在本地创建了一个Git仓库后,又想在github创建一个Git仓库,并且希望这两个仓库进行远程同步,这样github的仓库可以作为备份,又可以其他人通过该仓库来协作。
先登录github账号,“new reposity”
在Repository name填入testgit
,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库:
目前,testgit
仓库还是空的,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。
根据GitHub的提示,在本地的testgit
仓库下运行命令:
git remote add origin https://github.com/FightingSun/testgit.git
弹出一个窗口,输入github用户名和密码
这里可能不能顺利推送到远程。
如果提示出错信息:fatal: remote origin already exists.
解决办法如下:
1、先输入$ git remote rm origin
2、再输入$ git remote add
3、git remote add origin https://github.com/FightingSun/HelloWord.git就不会报错了
把本地库的内容推送到远程,使用 git push命令,实际上是把当前分支master推送到远程。
从现在起,只要本地文件修改了,先git add ,然后git commit 以后,就可以通过如下命令:
git push origin master
把本地master分支的最新修改推送到github上了,现在你就拥有了真正的分布式版本库了.
《如何从远程克隆》
假如远程库有新的内容了,我想克隆到本地来 如何克隆呢?
登录github后,创建一个新的仓库,名字叫testgit2如下:
现在,远程库已经准备好了,下一步是使用命令git clone克隆一个本地库了。如下所示:
接着在我本地目录下 生成testgit2目录了,如下所示:
《创建与合并分支》
在 版本回填退里,你已经知道,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。
首先,我们来创建dev分支,然后切换到dev分支上。如下操作:
git checkout 命令加上 –b参数表示创建并切换,相当于如下2条命令
git branch dev
git checkout dev
git branch查看分支,会列出所有的分支,当前分支前面会添加一个星号。然后我们在dev分支上继续做demo,比如我们现在在demo.txt再增加一行 8888.
查看demo.txt
现在dev分支工作已完成,现在我们切换到主分支master上,继续查看readme.txt内容如下:
现在我们可以把dev分支上的内容合并到分支master上了,可以在master分支上,使用如下命令 git merge dev 如下所示:
git merge命令用于合并指定分支到当前分支上,合并后,再查看readme.txt内容,可以看到,和dev分支最新提交的是完全一样的。
注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。
合并完成后,我们可以接着删除dev分支了,操作如下:
总结创建与合并分支命令如下:
查看分支:git branch
创建分支:git branch name
切换分支:git checkout name
创建+切换分支:git checkout –b name
合并某分支到当前分支:git merge name
删除分支:git branch –d name
《多人协作》
(说明:下面的截图路径不同是因为我再重新操作了一次)
当从远程库克隆时候,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且远程库的默认名称是origin。
- 要查看远程库的信息 使用 git remote
- 要查看远程库的详细信息 使用 git remote –v
1)推送分支
推送分支就是把该分支上所有本地提交到远程库中,推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:
使用命令 git push origin master
现在我github上demo.txt内容如下:
本地的demo.txt代码如下:
现在我想把本地更新的demo.txt代码推送到远程库中
使用命令:git push origin master
这种情况是因为我没有git add ,git commit所以大家一定不要忘了提交文件到当前分支上。
使用git push以后,应该是这样的
推送成功,现在来看看github上的变化:
github上也已经变化了,如果我们现在要推送到其他分支,比如dev分支上,使用命令 git push origin dev
一般情况下,那些分支要推送呢?
- master分支是主分支,因此要时刻与远程同步。
- 一些修复bug分支不需要推送到远程去,可以先合并到主分支上,然后把主分支master推送到远程去。
2)抓取分支
多人协作时,大家都会往master分支上推送各自的修改。现在我们可以模拟另外一个同事,可以在另一台电脑上(注意要把SSH key添加到github上)或者同一台电脑上另外一个目录克隆,新建一个目录名字叫testgit2
但是首先要把dev分支也要推送到远程去,如下
接着进入testgit2目录,进行克隆远程的库到本地来,如下:
使用命令:cd /e/project/testgit/testgit2
小伙伴A要在dev分支上做开发,就必须把远程的origin的dev分支到本地来,于是可以使用命令创建本地dev分支:git checkout –b dev origin/dev
然后小伙伴们就可以在dev分支上做开发了,开发完成后把dev分支推送到远程库。
小伙伴A已经向origin/dev分支上推送了提交,而我在我的目录文件下也对同样的文件同个地方作了修改,也试图推送到远程库时,如下:
推送失败,因为我的小伙伴最新提交的和我试图推送的有冲突,解决的办法也很简单,上面已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后在本地合并,解决冲突,再推送。
(如果此时进入vim模式,输入:q!回车即可退出来)
Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,其中<<<HEAD是指主分支修改的内容,>>>>> 3ec..f6 是指伙伴A修改的内容,我们可以找到=====隔开的两部分。碰到这种情况,git也不知道哪行内容是需要的,所以要自行确定需要的内容,手工修改demo.txt文件保留你想要的部分。修改后查看:
再git add 和git commit然后再git push上去就好了
多人协作的工作模式通常是这样:
-
首先,可以试图用
git push origin branch-name
推送自己的修改; -
如果推送失败,则因为远程分支比你的本地更新,需要先用
git pull
试图合并; -
如果合并有冲突,则解决冲突,并在本地提交;
-
没有冲突或者解决掉冲突后,再用
git push origin branch-name
推送就能成功!
如果git pull
提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream branch-name origin/branch-name
。
参考文章地址:http://blog.jobbole.com/78960/
2016-0-14 更新-------------------------------------------
进入vim查看状态的时候,首先Esc退出输入状态,然后Shift+; ,再输入 q! 或 wq! ( q! 不保存改动,wq! 是保存文件的写入修改)退出