本文适合总觉得git操作不够顺滑,被各种分支问题搞得焦头烂额的Java业务开发同学。
如果是git的初学者,建议搜索下git其他入门教程,这方面资料很多,非常推荐git init一个新项目,然后本地操作,边操作边观察工作区、暂存区、本地仓库和远程仓库的变化,这样就能很快上手。
由于IDEA git插件的便捷,平时简单的git操作或者查看操作都依赖可视化菜单即可,如非情怀,没必要非要命令行。但是各种分支操作等复杂操作,还是建议使用命令行,这样一是比较靠谱,二是能对git的处理逻辑更加了解,更容易举一反三。
下面介绍都是博主自己的经验而已,基于git版本为2.23.0,如果你的本地环境是git 1.x的话,结果会有些差异。
常见的git系统构成:
- Working Directory: 工作区
- Staging Area: 暂存区
- Repository(Local): 本地仓库
- Repository(Remote): 远程仓库
1.查看信息
命令行操作
- git log --> 查看当前分支的git日志。
- git log --oneline --> 单行形式查看当前分支的git日志。
- git reflog --> 查看本地的提交变更历史,并且提交是不区分在哪个分支提交的。常用于恢复本地的错误操作。
注:
- git log只显示当前分支所有提交过的版本信息,不包括已经被删除的 commit 记录和 reset 的操作
- git reflog显示本地所有分支的操作记录,包括提交,回退的操作
- git remote -v --> 查看远程仓库地址。
- git status --> 查看当前git的状态。非常有用的命令。
IDEA可视化操作
- 查看文件变更历史,等同于git show。
除了在暂存区的文件,在工作区的文件同样可以在右键菜单Git中找到"show history"
- 查看暂存区代码本次修改信息,等同于git diff。
- 查看文件在相比其他分支的版本/之前版本的改动,和第1个操作在同一级目录,对应菜单名分别为:Compare with和Compare with Branch
- 查看文件的每一行最后的修改人,等同于git blame。
2.单次提交操作
命令行操作
- git add . --> 将所有变化提交到暂存区。
注:由于git插件会默认将新增文件增加到暂存区,所以日常开发git add是不需要手动操作。
- git rm [filename] --> 删除工作区的文件,并将删除放到暂存区。
- git rm --cached [filename] --> 停止追踪暂存区的文件,文件会保留在工作区。
注:上面两条rm指令敲错的话也不会有问题,用错场景的话,会有反馈提示的。但不建议不指定文件名直接用"."代替,容易误操作。
- git commit --amend --> 将暂存区的改动添加到最新一次commit,并可修改最新一次commit的注释内容。
- git commit --amend --no-edit --> 将暂存区的改动添加到最新一次commit,但并不修改最新一次commit的注释内容。
注:以上两条指令常用于代码已经提交后的重新修改。要注意的是,执行后的最新节点的commitid会发生变化。
IDEA可视化操作
- 提交代码,等同于git commit。
可以选择多个文件,也可以单选。
- 取消代码修改,等同于git revert。
和第1个操作在同一级目录,"Commit"的下面
- 选择一个提交或者多个提交,合并到当前分支等同于git cherry-pick。
3.分支操作
命令行操作
- git branch --> 列出所有本地分支;-r 列出所有远程分支;-a列出所有本地和远程分支。
- git switch [branch_name] --> 切换分支;branch_name改为"-",切换到上一个分支。
- git checkout -b [new_branch_name] --> 基于当前分支创建新的分支。
- git branch -d [branch-name] --> 删除分支。
4.撤销
命令行操作
- git stash --> 将暂存区的代码缓存到栈中。
- git stash list --> 显示栈中所有缓存。
- git stash pop --> 将栈中的最近一次保存pop到暂存区中。
- git stash apply --> 恢复栈中所有的保存。
- git stash clear --> 清空缓存代码的栈。
注:git stash指令主要用于切换到突发事情,需要保留现场的时候进行使用。
- git reset --soft [commitId] --> 将HEAD指针指向commitId,并将commitId(不含)之后的提交放入暂存区。
- git reset [commitId] --> (省略了--mixed,因为--mixed是默认的参数)将HEAD指针指向commitId,不改变工作区,即将commitId(不含)之后的提交变成待提交的状态)
例如:git reset HEAD^ --> 将本地仓库的最新一条commit撤销,并将最新的修改变成待提交的状态。
- git reset --hard [commitId] --> 将本地仓库的[commitId](不含)之后的提交直接删除。
- git reset --hard [old_branch_name] --> 将当前分支还原成同old_branch_name一样的分支(此时一般不加--soft等其他参数,因为会出现HEAD指针已经移动到目标提交,又多了份提交在工作区或暂存区)
注:
- 如果有远程仓库的话,想要将远程仓库的代码与本地git reset的代码保持一致的话,需要执行git push -f。如果是公用分支的话,要注意执行git push -f的前提是保证你的强制覆盖不会删除别人的代码。
- 上面两个命令中,[commitId] 可以替换为HEAD。对于前者,可以取消追踪暂存区的追踪;对于后者,可以直接抛弃暂存区的修改。
- git revert [commitId] --> (省略了--edit,因为--edit是默认的参数)新建一个提交,用来还原指定commitId的变动。
注:
- --edit可替换成--no-edit,这样可以跳过编辑commit信息。
- --edit可替换成--no-commit,这样可以让撤回的提交放到暂存区,不进行提交,用户自行手动提交。
- git revert -m 1 [commitId] --> 保留merge中主干分支的修改部分,还原其余部分(commitId为merge的节点commitId)。如果1改为2,则保留merge中非主干分支的修改部分,这种操作很少见。
注:
相较于git reset ,git revert不会改变项目历史,对那些已经发布到共享仓库的提交来说这是一个安全的操作(git reset会把历史上某个提交及之后所有的提交都移除掉了)
- git rebase -i [commitId] --> 修改最近的提交。例如:git rebase -i HEAD~2 --> 合并最近的两次提交
执行这个命令后会跳到一个vi编辑器,修改每一行的第一个单词会有不同的效果:
pick:保留该commit(缩写:p)
reword:保留该commit,但需要修改该commit的注释(缩写:r)
edit:保留该commit, 但要停下来修改该提交(不仅仅修改注释)(缩写:e)
squash:将该commit和前一个commit合并(缩写:s)
fixup:将该commit和前一个commit合并,但不要保留该提交的注释信息(缩写:f)
drop:丢弃该commit(缩写:d)
exec:这个比较特殊,可以新增一行单独写。执行shell命令(exec之后的部分)(缩写:x)
注:完整命令是 git rebase -i [startpoint] [endpoint] --> 修改区间内的提交,区间前开后闭。
5.远程同步
命令行操作
- git pull --> 拉取代码等同于git fetch和git merge。
- git pull --rebase --> 拉取代码等同于git fetch和git rebase。
注:实际上git pull的真正命令形式是这样的:
git pull <远程主机名> <远程分支名>:<本地分支名>
只不过我们在当前分支从默认远程主机拉取代码的时候,忽略了后面的参数
- git push 本地分支推送到远程仓库的对应分支。
- git push -f --> 强行推送,即时有冲突也会被覆盖。
注:同git pull一样,实际上git push的真正命令形式是这样的:
git push <远程主机名> <本地分支名>:<远程分支名>
参考:
- https://git-scm.com/book/zh/v2/Git-工具-高级合并
- https://www.runoob.com/git/git-tutorial.html
- https://github.com/alibaba/fastjson/issues/2346