基本概念
- 工作区:就是你在电脑里能看到的目录。
- 暂存区:英文叫stage, 或index。一般存放在 ".git"目录下。
- 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
日常使用
修改文件
第一次修改 -> git add -> 第二次修改 -> git commit
你看,我们前面讲了,Git管理的是修改,当你用git add命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。
BUG分支
修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。
git stash #可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作
git stash pop #恢复工作现场,同时删除stash
git stash apply+git stash drop #恢复工作现场,删除stash
git stash apply stash@{0} #如果有多次提交,则使用选择要恢复的工作现场
推送分支
如果推送的远程分支不存在,则会被新建。如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull
拉取分支
git pull #取回远程主机某个分支的更新,再与本地的指定分支合并。
git fetch #更新git remote 中所有的远程repo所包含分支的最新commit-id,不会自动合并。
创建与合并分支
切换分支:git checkout <name> 如果带--<name>,这说明是回滚文件
创建+切换分支:git checkout -b <name>
解决冲突
git diff <file> # 比较当前文件和暂存区文件差异 git diff --staged # 比较暂存区和版本库差异 git diff --cached # 比较暂存区和版本库差异
git diff HEAD -- file # 比较的是工作区中的文件与版本库中文件的差异
撤销修改
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout --file。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,
第一步用命令git reset HEAD <file>,就回到了场景1
一种是将自修改后还没有被放到暂存区,撤销修改就回到和版本库(HEAD)一模一样的状态;
一种是将已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
适用于已将文件添加至暂存区,还未进行commit操作时,可以把暂存区的修改撤销掉
版本回退
- git log和git log --pretty=oneline #查看git提交的日志
- git reset --hard HEAD^或git reset --hard HEAD~1或git reset --hard commitId #版本回退指令,HEAD表示当前版本,^表示上一个版本,^^表示上上一个版本,依次类推,或者HEAD~1表示上一个版本 HEAD~2表示上上一个版本,依次类推
- git push -f #强制推送覆盖远程分支
执行如上指令后,远程分支将会被还原到制定的commitId上。需注意:如果该分支也有其他成员参与开发,并且其他成员本地代码分支上有此前你需要撤销的commitId,则其他成员提交代码时,会将你已经在远程代码分支上撤销完成的代码重新提交上去,造成最终代码撤销失败,如果要避免此问题,可以尝试git revert指令。
git revert #同样也是版本回退,但与git reset的区别是它每操作一次会重新提交一个commitId,这样就避免了多人开发同一分支时引起的覆盖问题
git revert --abort #终止此次revert操作
git reset --mixed #还原 HEAD、Index # 默认参数
git reset --hard #还原 HEAD、Index、Working Directory
git标签
什么是标签及标签的作用
发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。
标签操作
git tag <tagname>:用于新建一个标签,默认为HEAD,也可以指定一个commit id;
git tag <tagname> <commitID>:指定一个commit id新建标签;
git tag -a <tagname> -m "blablabla...":可以指定标签信息;
git push origin <tagname>:可以推送一个本地标签;
git push origin --tags:可以推送全部未推送过的本地标签;
git tag -d <tagname>:可以删除一个本地标签;
git push origin :refs/tags/<tagname>:可以删除一个远程标签。
解决IDEA LF和CRLF转换error设置
git config --global core.autocrlf input
#拒绝提交包含混合换行符的文件
git config --global core.safecrlf true