git命令行(2)

1、父提交的表示方法

1.HEAD引用

在.git/HEAD目录下存在一个HEAD文件,其记录着当前工做区对应的SHA1。若是当前工做区从某个分支检出(checkout),那么这个HEAD文件中的引用最终执行分支对应的SHA1,若是处于分离头状态(不对应分支,从某个commit检查),那么这个HEAD文件中保存的就是检出的commit SHA1。
git命令行(2)git

若是咱们直接使用git checkout master分支,那么HEAD的值为ref: refs/heads/master。指向.git/refs/heads/master文件,其内容就是m6对应的SHA1。
若是咱们使用git checkout ${m4.sha1} ,那么HEAD的值为 ${m4.sha1}
所以HEAD引用就是当前工做区对应的提交的SHA1vim

2.父提交的表示方法

可使用~(波浪号)和^号表示父提交,但含义会略有不一样。
</br>
^表示父提交的第几个提交,后面若是跟数字就是表示第几个父提交
例如上图中当前的工做区HEAD指向m10提交。那么HEAD^和HEAD^1相同都是指向m9。HEAD^^指向m8,而HEAD^2则是没有意义的,由于m10只有一个父提交就是m9。HEAD^^^指向是m7,HEAD^^^2指向d2(HEAD^^指向m8,后面的^2表示m8的第二个父提交)。分析^的时候若是^号后面没有数字则和^1等价,表示第一个父提交,若是存在数字就表示第几个父提交。
tips:若是^后面的形式如:^{commit},^{tree},^{blob},则表示当前对象的提交、树、blob对象。
</br>
~表示法:波浪号表示父提交的层次关系。那么HEAD~和HEAD~1相同都是指向m9。HEAD~ ~指向m8,而HEAD~2和HEAD~\~是彻底等价的。HEAD~\~\~指向是m7,HEAD~3和其等价。所以d2就能够表示为HEAD~2^2(HEAD~2指向m8,后面的^2表示m8的第二个父提交),所以若是存在数字表示父提交的父提交的父提交...(数字就是几层父提交)bash

所以当咱们使用git log命令的时候,能够打印部分父提交。
git log --oneline HEAD~8..HEAD~5编辑器

3.git reflog

当咱们对任何的分支修改(commit、pull、push)的时候,在.git/logs/refs目录都会记录变动状况,所以彻底不用担忧提交记录丢失的状况。.git/logs/refs/heads记录本地分支的变动记录,.git\logs\refs\remotes记录远程分支在本地的变动状况。
当咱们使用git reflog命令的时候就会显示HEAD引用的变动状况。
git命令行(2)
一样能够经过git reflog master查看master分支的变动状况。
reflog表示法:HEAD@{1},表示HEAD引用以前的第一个变动。ide

git reset --hard HEAD@{1}。若是新拉取的代码有问题,可是拉取以前的代码不肯定是否有问题,须要把代码回滚到拉取以前的代码,那么就能够执行这个命令测试

2、修改提交

本地提交代码的时候常常会出现须要更改提交、修改注释的状况,下面的几个命令能够实现修改提交。命令行

1.git commit

git commit --amend能够方便的修改当前说起的注释。当执行这个命令的时候会弹出vim编辑器编辑注释信息(只修改提交注释信息)。3d

2.git reset

git reset命令能够把当前分支重置到某个提交。其选项有三个:日志

  • --hard:把工做区、暂存区的内容也重置到该提交
  • --mixed:默认选项,把暂存器的内容重置到该提交,可是保留当前工做区的内容
  • --soft:工做区、暂存器保留原来的内容,分支的引用重置到某个提交

3.git revert

若是咱们的提交已经push到远程仓库上,别人已经pull下来了,若是你想删除某次提交,reset就不能使用了,而是使用revert命令,revert即对某次提交产生一个副作用的提交。code

git revert HEAD~3 -----建立一个提交,回滚最近的第四次提交
git revert  master~5..master~2  ---回滚某个范围的提交

4.git rebase

git rebase能够对当前没有push的提交进行更改,设想一下一个功能你能够本地进行了屡次提交,可是push的时候你想把这些提×××并成一个,就可使用git rebase命令编辑提交。
假设咱们须要对以下m9-m13的提交编辑。
git命令行(2)
场景一:把这些提交并成一个提交
git命令行(2)
使用squash命令和上一个提×××并,而后从新修改提交日志

场景二:删除某个提交
删除某个提交直接把该提交对应的行去除或者使用remove命令。若是存在合并冲突,而后解决冲突。

git命令行(2)
根据git命令行的提示,解决完冲突之后运行git add添加冲突的修改。

场景三:修改某个提交的日志:
使用edit命令或者reword命令修改,最好使用reword命令,这样rebase就能够之间弹出修改日志的vim编辑器,而不用git 弹出git commit --amend提示。

3、分支标签命令

1.git branch

使用branch命令能够管理分支。

$ git branch                ------显示本地分支
$git branch -a            -------显示本地和远程分支
$git branch xxxbranchName -------建立分支名xxxbranchName的分支,此时HEAD的引用仍然是指向原来的分支
$git branch -d xxxbranchName   ---删除某一个分支,若是该分支的修改没有合并,那么删除失败
$git branch -D xxxbranchName -----强制删除分支

2.git tag

使用tag命令能够管理标签。标签和分支的区别是,标签是不能够修改的。若是要修改必须基于该标签拉出一个分支修改

$git tag -------------展现全部的tag
$git tag xxxtagName ---------------新建xxxtagName的标签
$git tag -d xxxtagName ---------删除xxxtagName的标签

3.git checkout

checkout命令能够检出某个提交或者分支。

$git checkout SHA-1           ----------检出某个SHA-1对应的提交
$git checkout xxxbranchName -------------咱们使用git branch xxxbranchName的时候只是新建了这个分支,须要执行该命令切换到该分支
$git checkout HEAD^               -----检出到HEAD的第一个父提交
$git checkout -b xxxbranchName -------------新建xxxbranchName并检出到该分支

当咱们checkout除分支外的其余SHA-1都会提示咱们处于detached HEAD状态,此时.git/HEAD文件里面的内容就是SHA-1
git命令行(2)
此时若是在分离头上作的修改和提交想合并到其余分支须要用到merge和rebase等命令

4、合并命令

1.git merge

merge命令能够合并两个多个提交,并生成一个新的提交。当前分支始终是目标分支。
假设历史记录以下,且当前分支为master:

A---B---C topic
     /
    D---E---F---G master

而后运行 "git merge topic",将会产生一个新的提交H,其中H的父提交是C和G。

A---B---C topic
     /              \
    D---E---F---G---H master
$ git merge fixes enhancements 能够合并多个分支到当前分支
$git merge 8b9612d76178416c06da3b76cfab2945ddc98347    ----合并某个提交

合并中冲突的处理:

$ git merge feture1
Auto-merging gameoflife-deploy/pom.xml
CONFLICT (content): Merge conflict in gameoflife-deploy/pom.xml
Automatic merge failed; fix conflicts and then commit the result.

merge命令能够一次性把全部冲突的文件合并,而后提示用户合并冲突去解决。解决完冲突之后,须要运行git add命令把文件添加到暂存区。继续执行git merge --continue命令编辑新生成的提交的log信息。而后merge完成。

2.git rebase

rebase命令除了能够更改提交之外,同时能够合并代码,不过和merge命令有些不一样。
假设历史记录以下,且当前分支为topic:

A---B---C topic
         /
 D---E---F---G master

那么运行git rebase master的时候,其提交以下:

A'--B'--C' topic
                        /
    D---E---F---G master

其中A'、B'、C'和A、B、C已经不是同一个提交(其tree对象不是同一个,父提交也不是同一个),可是其修改的内容是相同的。
rebase命令合并的时候从两个分支(或者提交)公共的父提交开始变基。
整体变基命令用的很少,并且场景比较复杂(能够查看其help文档)。慎用

3.merge和rebase的区别

一、merge命令会产生一个合并提交,而变基不会。变基命令的提交树会比较清晰,merge存在各类合并,看着比较混乱。
二、工做流不一样,对于merge命令其合并是全部提交一次合并好,而后解决冲突,而变基命令只能一个提交一个提交的解决冲突。

merge:merge的时候把待合并的全部commit一次合并好,只显示一次冲突,解决完冲突之后运行一次git merge --continue就行。
rebase:  工做流程大概以下:
             commit =nextNeedMergeCommit()
              while(merge(commit)==confict)
                            {
                                resoveConfilec();
                                    rebaseContinue();
                                    commit =nextNeedMergeCommit()
                            }

4.Fast-forward快进式合并

在合并的时候常常会遇到快进式合并,那么什么是快进式合并么?
假设存在以下的场景:

A---B---C topic
         /
 D---E           master
那么咱们执行git merge topic命令的时候,其结果就是快进式合并以下:
D---E --- A---B---C          master

而若是执行git merge topic --no-ff 非快进式提交,测试以下的结果以下:

A---B---C
         /              \
D---E --------------M          master

会多产生一个提交M,其父提交为E和C。

5.git cherry-pick

可使用cherry-pick摘取每一个提交的内容,并合并当前分支
假设历史记录以下,且当前分支为topic:

A---B---C topic
         /
 D---E---F---G master

假设咱们指向合并A、B到master分支,那么就可使用cherry-pick命令

$git cherry-pick topic~2 topic~1
          A---B---C topic
         /
 D---E---F---G-----A'---B' master

若是出现合并冲突,一样须要处理冲突,而后使用git cherry-pick --continue命令继续

6.git如何追踪冲突

当出现冲突的时候:

  • .git/MERGE_HEAD 记录合并进来的提交的SHA1值。
  • .git/MERGE_MSG包含当解决冲突之后执行git commit后默认的消息日志
  • git的索引(暂存区)里面每一个冲突文件的三个副本:合并基础、“咱们的”版本和“他们的版本”。给这三个副本分配了各自的编号一、二、3.
  • 冲突的版本(合并标记和全部内容)不存储在暂存区内。

可使用git ls-files -u命令查看冲突的文件。
git命令行(2)

相关文章
相关标签/搜索