Git (三)
Git 进阶命令
冲突
在 Git 的使用过程中,多个开发者一起开发项目难免会出现冲突;
冲突产生的原因在于:merge 在做合并的时候具有 自动合并能力 的:如果一个分支改了 A 文件,另一个分支改了 B 文件,那么合并后就是既改 A 也改 B,这个动作会自动完成;如果两个分支都改了同一个文件,但一个改的是第 1 行,另一个改的是第 2 行,那么合并后就是第 1 行和第 2 行都改,也是自动完成。
但是如果两个分支修改了同一部分内容,merge 的自动算法就无法做决定该选取哪个内容。这种情况 Git 称之为:冲突(Conflict)。
简单来说: 冲突产生的原因是 两个分支改了相同的内容,Git 无法确定应该以哪个为准。当 merge 的时候,Git 就会把问题交给你来决定。
解决
解决掉冲突(查看冲突文件的内容,然后确定保留哪一部分,修改文件) 然后 commit。
撤销和回退
在开发过程中,经常会使用 Git 的撤销和回退功能,例如我们撤销到上一个版本,或者撤销某次多余的提交。
git reset
git reset的作用是修改HEAD的位置,即将HEAD指向的位置改变为之前存在的某个版本。
reset 这个指令虽然可以用来撤销 commit ,但它的实质行为并不是撤销,而是移动 HEAD ,简单来说:它是用来重置 HEAD 以及它所指向的 branch 的位置的。
reset之前:版本1 ------ 版本2 ------- 版本3(HEAD/Master)
reset之后:版本1 ------ 版本2 (HEAD/Master)
git reset 有三个参数:
--hard:重置位置,并且清空工作目录的所有改动(完全退回);
--soft:重置位置,但保留工作目录和暂存区的内容,并把重置 HEAD 的位置所导致的新的文件差异放进暂存区(退回但是保留了改动的内容);
--mixed(默认):重置位置的同时,保留工作目录的内容,并清空暂存区。
git reset --hard HEAD^ 退回上一次提交;
HEAD 表示 HEAD^ 往回数一个位置的 commit ;
在 Git 中,有两个 偏移符号: ^ 和 ~。
^ 的用法:在 commit 的后面加一个或多个 ^ 号,可以把 commit 往回偏移,偏移的数量是 ^ 的数量。例如:master^ 表示 master 指向的 commit 之前的那个 commit; HEAD^^ 表示 HEAD 所指向的 commit 往前数两个 commit。
~ 的用法:在 commit 的后面加上 ~ 号和一个数,可以把 commit 往回偏移,偏移的数量是 ~ 号后面的数。例如:HEAD~3 表示 HEAD 指向的 commit往前数 3 个 commit。
另外还有一种语法 git reset --hard commit_id;
commit_id 就是 git log 显示的一长串字符串;
commit_idgit revert
增加一个新的提交,把之前提交的内容抹掉。例如之前你增加了一行代码,你希望撤销它,那么你就做一个删掉这行代码的提交;如果你删掉了一行代码,你希望撤销它,那么你就做一个把这行代码还原回来的提交。 Git 有一个对应的指令:revert。
git revert HEAD^
revert 和 reset 类似 ,与 reset 不同的是,revert 复制了那个想要回退到的历史版本,将它加在当前分支的最前端,修改的 commit 并没有在历史中消失掉,你的历史中会存在两条 commit :一个原始 commit ,一个对它的修改后 commit。
revert之前:版本1 ------ 版本2 ------- 版本3(HEAD/Master)
revert之后:版本1 ------ 版本2 ------- 版本3 ------- 版本4(HEAD/Master)
git checkout
我们知道 checkout 是 用来切换分支 、新建分支,其实它也有撤销的功能;
git checkout 分支名 是签出( checkout )指定的 commit;
它的本质,其实是把 HEAD 指向指定的 branch,然后签出这个 branch 所对应的 commit 的工作目录。所以 checkout 的目标也可以不是 branch,而直接指定某个 commit:
git checkout commit_id
另外, git checkout 也有撤销功能, 如果文件还在工作区,还没添加到暂存区,可以使用git checkout撤销,它的使用方式:
git checkout -- 文件名 的格式,通过「签出」的方式来撤销指定文件的修改
git checkout . 撤销所有文件的修改