1. git的结构
git区别于svn等版本控制工具的核心是每一个本地库并不仅仅保存远程的索引,而是保存远程所有的内容,每一个本地库都可以独立作为远程库使用。
git的结构和常用命令的操作对象如下图所示:
2. 常用的操作命令,具体操作可查看https://git-scm.com/book/zh/v2
git add : 将修改从工作目录保存到暂存区
git commit : 将修改从暂存区保存到本地仓库
git push : 将修改从本地仓库保存到远程仓库
git clone : 创建本地仓库,将远程仓库所有数据保存到本地仓库
git fetch : 将远程仓库的修改更新到本地仓库
git merge : 将一个分支合并到另一个分支
git pull :git fetch + git merge,首先将远程更新保存到本地仓库,然后对比本地分支和远程分支,假如没有冲突,就合并,否则提示冲突,等待解决
git branch : 创建分支
git checkout : 切换分支
git rebase : 换基,功能跟git merge类似,但是会清除记录,使得记录看起来更清晰。不推荐使用,因为可能会引起数据丢失
git stash:保存你修改的数据,此时你的工作库就跟远程的一样了
git patch : 将你的修改打补丁,可以保存起来,也可以给别人使用
git revert : 改变你的当前工作目录指向的commit,比如说一个库总共commit了3次,你现在想在第二次commit的基础上继续开发,你就可以使用这个命令改变head
git SubMoule add/update : 子目录的添加和更新,这种情况一般用于子目录是另一个库,但是我的项目需要引用它
3. git 文件目录
当我们使用git工具,会生成一个.git的隐藏文件夹,所有的操作都是保存在.git文件夹中,如图所示
假如有引用子目录,会在这里生成一个modules文件夹,点进去看其实就是另一个.git文件夹
详细可以看链接:https://blog.csdn.net/mayfla/article/details/78653396,https://blog.csdn.net/a19881029/article/details/42245955
我这里主要讲下重点的部分
(1)config文件,保存了远程和本地分支的数据
(2)refs文件夹保存了远程库和本地库的最新commitID,对应的文件夹heads和remotes
logs/refs文件夹保存了远程库和本地库的最新最新修改记录,对应的文件夹heads和remotes
(3)fetch和pull的区别
fetch会修改远程库的commitID和修改记录, 然后merge会修改本地库的commitID和修改记录
pull会同时修改远程库和本地库的commitID和修改记录
暂存的原理:
暂存其实就是一个index文件,他主要保存的是所有文件的索引
如图所示,可以通过git ls-files –stage来查看,第二列长度为40的HASH值对应 .git/objects文件夹中的文件,git使用前两位作为文件夹,后38位作为文件名
使用git commit命令时,git会在objects目录下生成一个commit类型的文件和多个tree类型的文件(取决于tree类型是否已存在)。commit文件中保存了当前版本的所有的文件状态,并有一个索引指向上一次提交。以此类推。
4. 创建分支,修改,合并到主干过程
(1)主干Master有3次更新,分别是a,b,c
(2)在c节点上开始创建分支Feature,然后切换到分支
(3)这个分支是在本地仓库创建的,将它push到远程,此时远程也会有这样一个分支
git push
(4)当你在这个分支上工作,创建了f,g两个commit,此时远程主干也有人提交了新的commit d和h
(5)此时你完成了你的工作,需要合并到主干,你需要首先在本地合并,这一步是将分支更新到最新,然后用于测试
切换到主干分支master,然后pull保证最新,再切换到分支feature,然后将主干合并到分支,测试,然后push
git checkout master
git pull
git checkout feature
git merge master
test the function
git push
此时本地和远程的库一致,对应的master和feature如下图所示
(6)此时分支Feature其实已经是最新的了,我们只需要把Master跟feature一样就行
切换到主干,主干合并分支,然后push
git checkout master
git merge featurer
git push
5.常用git工具
Fork操作(tortoiseGIt跟它操作类似):
git add : changes里面的stage和unstage就是保存到暂存和从暂存里面删除,如图
git commit : changes里面点击stage,然后右下角输入commit信息,然后点击commit
git push : 左边Branches里面选中对应的branch,右击push,或者直接点击左上角的push
git clone : 菜单栏选择File->Init New Respository
git fetch : 选中当前分支,点击菜单栏下方的fetch
git merge : 选中需要合并的源分支,然后选中目标分支,右击选中Merge into(比如将A合并到B,B是当前分支,然后选中A,右击Merge Into B)
git pull :类似git push,右击fast-forward pull
git branch : 点击右上角New Branch
git checkout : 左边Branches里面选中对应的branch,右击CheckOut
git stash:当你的分支有修改时,Changes里面会有提示,此时你可以点击菜单栏下方的Stash,然后保存,需要使用的时候点击左边的stashes里面选中你保存的,右击apply
git revert : 在All Commits页面,选中你需要切换的commit,右击reset 。。to here,然后选中mix或者hard
git patch : 再Changes页面里面选中修改的change然后右击Save as patch,此时你可以把change discard掉,去干别的事,也可以使用Reset..to here切换head,然后做别的事,使用patch,在菜单栏里面选中apply patch,此时要确保你的head一定要和保存patch时一致,否则会报错
git SubMoule add/update : 直接在最左边,Submodules右击
最重要的一点,merge的过程中出现conflict,如下
此时点击Merge,然后跳转如下
点击Revert
可以选择左边或者右边,假如需要合并,则2个都选中点击merge,如图
对比选择需要的,然后合并,最后push
6. 小提示
1. 在fork中,当对当前分支使用fetch命令后,再双击Remotes/origin里面对应的分支,相当于merge操作。此时相当于一个完整的pull操作,当然也可以先fetch,然后对比修改,没问题了直接再调用pull
2.当有时你不小心把你的一个文件或一个目录删掉了,你想从远程拉下来
打开命令行,定位到目录
一个文件 : git checkout a.cs
当前目录 : git checkout .
3. fork回退远程版本
选中你所需要的版本,右击,选择Reset to here,此时本地已经回退,然后点击push,选中force push,确认