导言
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命令。

文件在分支上删除.png

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
