git基本概念
- 工作区:就是你在电脑里能看到的目录,比如我们的项目文件夹就是一个工作区
-
版本库:工作区有一个隐藏目录
.git
,这个不算工作区,而是Git的版本库(暂存区+分支)
git常用命令
- git status:查看当前状态
- git log:查看提交记录
- git log --graph:查看分支图合并
- git reflog:查看近期所有操作提交记录
- git branch:查看本地仓库分支 git branch -a 查看所有分支
- git checkout [分支名]:切换分支
- git checkout -b [分支名] [远程分支]:基于某个远程分支新建分支并切换到该分支
- git branch -d [分支名]:删除某分支
- git merge [分支名]:分支进行融合
- git remote:查看远程库信息 -v 详细信息
- git tag:查看本地仓库所有标签
- git tag <name> <commitId>:默认HEAD打一个标签 可指定特定commitId -m '为标签添加注释'
- git tag -d <tagName>:删除某个标签
- git push -d origin <tagName>:删除远程标签
- git push --tags:将本地标签一次性推送到远程
- git push origin <tagName>:推送指定标签到远程
git diff 命令详解(用于比较两次修改的差异)
- 工作区和暂存区的差异:
git diff <filename>
- 暂存区和Git仓库(已经提交)的差异:
git diff --cached <commit> <filename>
- 工作区和Git仓库的差异:
git diff <commit> <filename>
git config 常用配置
-
配置邮箱和用户名
git config --global user.name \[NAME\] git config --global user.email \[EMAIL\]
-
配置命令别名
比如给 git status 设置别名 st: git config --global alias.st status
-
查看已有配置信息
git config [--system|global] --list 启用大小写敏感:git config --global core.ignorecase false
git merge VS git rebase
- git merge:合并分支(保留历史提交),产生新的融合提交记录
-
git rebase:变基&合并分支(丢弃原始提交,形成线性提交历史) 一个冲突一个冲突的解决 解决一个冲突之后
git add -u git rebase --continue
中途退出:
git rebase --abort
总结:
- 想要保存项目完整的历史,并且避免重写公共分支上的commit,使用git merge,缺点:多出很多不必要的提交
- 想要一个干净的、线性的提交历史,没有不必要的合并提交,使用 git rebase,缺点:修改提交记录
- 只要你的分支上需要 rebase 的所有 commits 历史还没有被 push 过,就可以安全地使用 git-rebase来操作。
git rebase 合并提交记录
前提:提交记录是线性的,并且没有push到公共分支
git rebase -i HEAD~3
- pick:保留该commit(缩写:p)
- reword:保留该commit,但我需要修改该commit的注释(缩写:r)
- edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)
- squash:将该commit和前一个commit合并(缩写:s)
- fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)
- exec:执行shell命令(缩写:x)
- drop:我要丢弃该commit(缩写:d)
修改指令(保留第一次提交 将下面两次提交合并到第一次提交中)
:wq保存之后重新修改提交信息
:wq之后合并提交完成
git reset VS git revert
-
git reset:版本撤回
- 回退所有内容到上一个版本 git reset HEAD^
- 回退a.js这个文件的版本到上一个版本 git reset HEAD^ a.js
- 将本地的状态回退到和远程的一样 git reset –hard origin/master
- 回退到某个版本 git reset 057d
-
git revert:撤消操作
- git revert HEAD~3:丢弃最近的三个commit,把状态恢复到最近的第四个commit,并且提交一个新的commit来记录这次改变。
总结:
- git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。
- 在回滚这一操作上看,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,但是git reset是之间把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入。
- git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。
使用场景
撤销修改
- 本地修改后未存储在暂存区时(git add),使用
git checkout -- file
撤销某文件的修改,撤销所有修改可以使用git checkout .
- 本地修改后已存储在暂存区时,使用
git reset HEAD <file>
,将暂存区的修改撤销掉,重新放回工作区,撤销工作区修改可以使用git checkout -- file
- 本地修改后提交到版本库(git commit),可以使用
git reset --hard HEAD^
,回退到上一个版本
储藏当前工作现场
- git stash:把当前工作现场“储藏”起来,等以后恢复现场后继续工作
- git stash list:查看有哪些储藏现场
- git stash apply:恢复现场,但是不删除stash
- git stash drop:删除stash
- git stash pop:恢复现场并删除stash
- git stash clear:清除所有储藏记录
$ git stash list
stash@{0}: WIP on dev: f52c633 add merge
两个分支提交相同代码时
- git cherry-pick <commit> :提交相同修改
删除远程分支
- git branch -d origin/hotfix/2.2.3 (删除本地)
- git push origin :hotfix/2.2.3 (远程分支也删除)
三路合并以及三路递归合并
三路合并
- 三路合并算法会找到合并的这两个提交的共同祖先
- 依据共同父祖先进行对比
三路递归合并
- git 会首先将 b 和 c 合并成一个虚拟的提交 x,这个 x 当作 e 和 d 的共同祖先。
- 而要合并 b 和 c,也需要进行同样的操作,即找到一个共同的祖先 a。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。