导言
git之所以复杂,是维护了本地分支,本地主干。远程分支,远程主干,以及工作区和暂存区之间的关系。
- 工作区:在idea中实际上是创建文件,但未add,此时文件是
红色的
。 - 暂存区:在idea中文件进行add,但是没有commit,此时文件是
绿色的
。 - 分支/主干:在idea中进行commit,此时文件是
白色的
。
在本地中,因为是公用了一套代码,两个分支,所以工作区和暂存区的内容在各个分支中是共享的。
但若是代码提交到分支上,那么主干上看不到提交到分支的代码。实际上主干和分支是两个指针。若是分支代码版本是新的,那么如下图所示:
我们若checkout(切换分支)到master,是看不到dev最新commit的代码的。
而实际上我们合并分支时,只是将master指针指向dev节点上,完成了快速合并。(故在dev分支上进行merge(合并))。
注:合并分支时,项目中 不能存在 只add(即idea绿色文件)的文件。
理论
每次提交Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。
HEAD
严格来说不是指向提交,而是指向master
,master才是指向提交的,所以,HEAD
指向的就是当前分支。
上面的是什么意思呢?
每次提交,master
分支都会向前移动一步,这样,随着你不断提交,master
分支的线也越来越长
当我们创建新的分支,例如
dev
时,Git新建了一个指针叫dev
,指向master
相同的提交,再把HEAD
指向dev
,就表示当前分支在dev
上:
不过,从现在开始,对工作区的修改和提交就是针对
dev
分支了,比如新提交一次后,dev
指针往前移动一步,而master
指针不变:
假如我们在dev
上的工作完成了,就可以把dev
合并到master
上。Git怎么合并呢?最简单的方法,就是直接把master
指向dev
的当前提交,就完成了合并:
所以Git合并分支也很快!就改改指针,工作区内容也不变!
合并完分支后,甚至可以删除dev
分支。删除dev
分支就是把dev
指针给删掉,删掉后,我们就剩下了一条master
分支:
真是太神奇了,你看得出来有些提交是通过分支完成的吗?
1. 文件初创
1.1. 新建文件
1.2、查询文件状态
命令:git status
1.3. 将文件保存到暂存区
命令:git add 文件名,再次使用git status查询状态。
1.4.将文件保存到当前分支(本地仓库)
命令:git commit -m '注释'
1.5. 查询文件修改的内容
命令:git diff 文件名
使用git status查询状态,使用git diff 文件名 查询差异。
git提交文件只要两步:
- 使用
git add
把文件添加进去,实际上就是把文件(工作区)添加到暂存区。- 使用
git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支上。
2. 文件回退
2.1. 查询分支日志
命令:git log
可以查询当前分支的提交日志。可以使用q
退出。
2.2. 分支回退版本
命令:git reset --hard HEAD^
那么如果要回退到上上个版本只需把HEAD^
改成 HEAD^^
。是将当前分支上的文件回退一个版本。
回退git reset --hard HEAD
是回退暂存区的文件。
2.3. 获取版本号
命令:git reflog
若是我们将客户窗口关闭(git log命令失效),或者回退到某个版本。那么需要该命令获取版本号。
2.4. 分支回退指定版本
命令:git reset --hard 版本号
(注意无空格)
2.5. 文件撤销
命令:git checkout -- 文件名
【注意有空格,注意 -- 】
需要注意的是:
- 未
add
命令,可以还原;- 已经执行
git add
命令,无论是否被commit
均无法还原;
总结:文件恢复的办法:
第一:如果我知道要删掉那些内容的话,直接手动更改去掉那些需要的文件,然后add
添加到暂存区,最后commit
掉。
第二:我可以按以前的方法直接恢复到上一个版本。使用git reset --hard HEAD^
;或者git reset --hard 版本号(注意无空格)。__
第三:git checkout -- 文件名
,可以将工作区还原。
3. 文件删除
将文件手动删除之后,使用git status
查询状态:
此时,有两种策略:(1)文件还原;(2)文件在当前分支上删除;
3.1 文件还原
命令:git checkout -- 文件名
,因为只是在工作区做出的修改,所以可以撤销操作。
3.2 分支上删除
命令:先执行add
命令,而后执行commit
命令。
4. 分支的创建和合并
4.1 分支的创建
git checkout
命令加上 –b参数,表示创建并切换,相当于如下2条命令
git branch dev
(创建分支)
git checkout dev
(切换分支)
git branch
(查看所有分支):
4.2 多分支之间操作
在dev
分支上修改TestSort.java
文件,使用git diff 文件名
命令查询差异。
add+commit命令将工作区文件合并到dev分支上。
切换分支:命令:git checkout 分支名。并未在当前分支上查询到修改的信息。
4.3 分支合并
命令:git merge -d 分支A
。将分支A合并到当前分支。
Fast-forward
信息,Git告诉我们,这次合并是“快进模式”,也就是直接把fenzhi1
指向dev
的当前提交,所以合并速度非常快。可以查看文件中,已经含有了dev
分支的修改内容。
4.4 分支删除
命令:git branch -d 分支A
。将分支A删除。
查看分支:git branch
创建分支:git branch name
切换分支:git checkout name
创建+切换分支:git checkout –b name
合并某分支到当前分支:git merge name
删除分支:git branch –d name
5. 分支冲突
5.1 冲突的产生
在dev分支
上,对TestSort.java
文件进行修改。然后提交到当前分支。
通过命令:git checkout 分支名
切换分支后,查看分支内容。
在master
分支上修改同一个文件,然后提交到分支上。
以上是合并冲突的准备工作
此时,在将dev
分支上代码合并到主干(master)上时,出现版本冲突。
于是我们开始检查冲突的代码:Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,其中<<<HEAD是指主分支修改的内容,>>>>>dev是指dev上修改的内容。
我们修改冲突代码后,将其重新放入暂存区,然后提交到master主干上。
通常合并分支时,git一般使用”Fast forward”模式,在这种模式下,删除分支后,会丢掉分支信息,现在我们来使用带参数 –no-ff来禁用”Fast forward”模式。首先我们来做demo演示下:
- 创建一个dev分支。
- 修改readme.txt内容。
- 添加到暂存区。
- 切换回主分支(master)。
- 合并dev分支,使用命令 git merge –no-ff -m “注释” dev
- 查看历史记录
分支策略:首先master主分支应该是非常稳定的,也就是用来发布新版本,一般情况下不允许在上面干活,干活一般情况下在新建的dev分支上干活,干完后,比如上要发布,或者说dev分支代码稳定后可以合并到主分支master上来。
6. (精华)多人协作
当你从远程库克隆时候,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且远程库的默认名称是
origin
。
6.1 查询远程仓库
要查看远程库的信息 使用 git remote
要查看远程库的详细信息 使用 git remote –v
6.2 数据推送
命令:git push 远程服务器名 远程分支名
,将信息push到远程仓库。
那么一般情况下,那些分支要推送呢?
master分支是主分支,因此要时刻与远程同步。
一些修复bug分支不需要推送到远程去,可以先合并到主分支上,然后把主分支master推送到远程去。
6.3 抓取分支:
命令:git push origin dev
小胖将信息push到远程dev分支上
小伙伴要在dev分支上做开发,就必须把远程的origin的dev分支到本地来,于是可以使用命令创建本地dev分支:git checkout –b dev origin/dev
现在小伙伴们就可以在dev分支上做开发了,开发完成后把dev分支推送到远程库。
小胖将TestSort.java
修改的内容推送到远程。
小悠也想对TestSort.java
这个文件信息修改。于是:
由上面可知:推送失败,因为我的小伙伴最新提交的和我试图推送的有冲突,解决的办法也很简单,上面已经提示我们,先用
git pull
把最新的提交从origin/dev
抓下来,然后在本地合并,(手动)解决冲突,再推送。
因此:多人协作工作模式一般是这样的:
首先,可以试图用git push origin branch-name
推送自己的修改;
如果推送失败,则因为远程分支比你的本地更新早,需要先用git pull
试图合并。
如果合并有冲突,则需要解决冲突,并在本地提交。再用git push origin branch-name
推送。
7. 应用实战(idea版本)
7.1 idea文件和git版本的关系
7.2 场景1
git使用场景:
开发过程中,忘记将主干上的代码pull(远程分支下拉命令)或者merge(本地主干下拉命令)。且开发到一半时(已存在大量“蓝色/绿色”文件),此时再想pull或者merge时候。出现
解决方案1:
如果你想保留刚才本地修改的代码,并把git服务器上的代码pull到本地(本地刚才修改的代码将会被暂时封存起来)
git stash
git pull origin master
git stash pop
解决方案2:
如果你想完全地覆盖本地的代码,只保留服务器端代码,则直接回退到上一个版本,再进行pull:
git reset --hard
git pull origin master
文章参考:https://www.cnblogs.com/replaceroot/p/9825760.html
http://www.admin10000.com/document/5374.html