[TOC]
本文是参考廖雪峰老师的Git资料再加上我自己对Git的理解,记录我的Git学习历程,作下此文是为以后学习,工作,开发中如果遇到问题可以回过头来参考参考。因为水平有限,难免会有出错的地方,欢迎指正。
廖雪峰老师讲Git讲的通俗易懂,对小白很友好。认认真真花上两天时间去整理,会有所收获的。
廖老师的个人网站传送门:
官方话:Git是一个免费的开源分布式版本控制系统,旨在快速高效地处理从小型到大型项目的所有事务。
它能自动帮我记录每次文件的改动,还可以让同事协作编辑,这样就不用自己管理一堆类似的文件了,也不需要把文件传来传去。如果想查看某次改动,只需要在软件里瞄一眼就可以。
直接在官网上去下载。下载完成后,随便在某个文件下右键如果有Git Bash Here就安装成功。安装后,还要在命令行输入
$git config --global user.name "你的名字"
$git config --global user.email "你的邮箱"
global表示全局,这台机器所有的Git仓库都会使用这个配置。允许单个仓库使用其他的名字和邮箱。
Mac也可以像Windows一样,按上面的步骤安装。
也可以直接从AppStore安装Xcode,Xcode集成了Git,不过默认没有安装,你需要运行Xcode,选择菜单“Xcode”->“Preferences”,在弹出窗口中找到“Downloads”,选择“Command Line Tools”,点“Install”就可以完成安装了。
本地仓库是对于远程仓库而言的。本地仓库 = 工作区 + 版本区。
以我使用最频繁的git命令为例,即提交到github为例。
以前不熟悉git命令的时候,我提交项目到github上都是直接在网页上直接拉取文件提交上去的。有点羞耻。
提交一个文件,有时候我们会提交很多次,在提交历史中,这样就产生了不同的版本。每次提交,Git会把他们串成一条时间线。如何回溯到我们提交的上一个版本,用git reset --hard + 版本号即可。版本号可以用git log来查看,每一次的版本都会产生不一样的版本号。
回溯之后,git log查看一下发现离我们最近的那个版本已经不见了。但是我还想要前进到最近的版本应该如何?只要git reset --hard + 版本号就行。退一步来讲,虽然我们可以通过git reset --hard + 版本号,靠记住版本号来可以在不同的版本之间来回穿梭。
但是,有时候把版本号弄丢了怎么办?git reflog帮你记录了每一次的命令,这样就可以找到版本号了,这样你又可以通过git reset来版本穿梭了。
场景1:在工作区时,你修改了一个东西,你想撤销修改,git checkout -- file。廖雪峰老师指出撤销修改就回到和版本库一模一样的状态,即用版本库里的版本替换工作区的版本。
场景2:你修改了一个内容,并且已经git add到暂存区了。想撤销怎么办?回溯版本,git reset --hard + 版本号,再git checkout -- file,替换工作区的版本。
场景3:你修改了一个内容,并且已经git commit到了master。跟场景2一样,版本回溯,再进行撤销。
如果你git add一个文件到暂存区,然后在工作区又把文件删除了,Git会知道你删除了文件。如果你要把版本库里的文件删除,git rm 并且git commit -m "xxx".
如果你误删了工作区的文件,怎么办?使用撤销命令,git checkout --就可以。这再次证明了撤销命令其实就是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
分支,就像平行宇宙,廖雪峰老师如是说。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
在没有其他分支插进来时,只有一个master主分支。每次你git push -u origin master 提交就是增加一条时间轴,master也会跟着移动。
创建一个other的分支,通过other提交,虽然时间轴向前走了,但是主分支master还在原来的位置。
理论分析完,看一下命令怎么写。
创建分支other,切换到other分支。
git branch other
git checkout other
查看当前所有分支
git branch
* other
master
当前的分支会有一个*
用other提交
git add ./xxx/
git commit -m "xxx"
other分支完成,切换回master
git checkout master
此时,master分支上并没有other的文件,因为分支还没有合并。
合并分支
git merge other
合并完成之后,就可以在master分支上查看到文件了。
删除other分支
git branch -d other
我由此想到,在以后工作中,应该是一个开放小组共同开发一个项目,组长会创建很多分支,每一个分支可以交给一个人去开发某一个功能,一个小组共同开发而且不会相互干扰。谁的功能完成了,可以由组长合并一下完成了的分支。哦,完美!
假如有这样一种情况,分支other已经commit了,但是此时指针指回master时,并且master没有合并,而是git add / commit 提交了。这样,就产生了冲突,主分支master文件内容与other分支的内容不一样。合并不起来!所以,
修改文件的内容,让其保持一致。
git add git commit 提交。
分支合并了。
git log --graph 查看分支合并图
git branch -d other 删除分支,任务结束。
git merge --no-ff other 禁用Fast forward模式,因为使用Fast forward模式,删除分支后,分支历史信息会丢失。Git的实现原理,点这里:深入理解Git的实现原理
廖雪峰老师提到,工作中每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。但如果你手上有分支在工作中,你的上级要你改另外的分支的BUG。
你要把现在正在工作的分支保存下来,git stash,把当前工作现场“存储”起来,等以后恢复后继续工作。当你解决BUG后,git checkout other回到自己的分支。用git stash list查看你刚刚“存放”起来的工作去哪里了。
此时你要恢复工作:
总结:修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场
产生上图的冲突时,
廖雪峰老师的总结:多人协作的工作模式通常是这样:
推送自己的修改;
如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
如果合并有冲突,则解决冲突,并在本地提交;
没有冲突或者解决掉冲突后,再用git push origin
推送就能成功!
git rebase 把分叉的提交历史“整理”成一条直线,看上去更直观.缺点是本地的分叉提交已经被修改过了。
最后在进行git push -u origin master
rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。
比如一个APP要上线,通常在版本库中打一个标签(tag),这样,就确定了打标签的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。
Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针。
tag其实就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。比如tag v2.1就是把历史上的一个版本的东西叫做v2.1
步骤:
忽略文件原则:忽略操作系统自动生成的文件,比如缩略图等;忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。