- 前言
- Git
- 基础 Git 命令
- 不常用但很重要的命令
- Git 提交规范
- 我的 Git 使用经验
- SSH 操作
- 推荐 Blog
本文由 简悦 SimpRead 转码, 原文地址 juejin.im
人生是一场难得的修行, 不要轻易交白卷 —- 胡歌
前言
日常开发中,VsCode 我使用自带的源码管理工具结合 GitLens ;IDEA 使用自带的图形化界面 Git 插件。
当前命令基于 Git 2.20.1,系统 MacOs 10.14.5
Git


WorkSpace 工作空间
你在开发工具看到的就是工作空间。
Index 暂存区
数据暂存的地方,当你 git commit 只会把暂存区中的内容添加本地仓库形成 history
Repository 本地仓库
本地仓库,记录文件的修改差异。git commit 的时候会基于修改的内容形成一个 hash , Head (指针) 指向提交的记录。只有提交本地的仓库的内容才不会丢失,都是可以找回来的。
Remote 远程仓库
众多本地仓库内容的汇集地。

有的时候呢,命令太多,记不住命令的时候,可以查看帮助信息。
git cmomit --helpgit add --help复制代码
基础 Git 命令
掌握 Git 基础命令, 日常开发基本就没有问题。
git initgit addgit commitgit diffgit pushgit remotegit pullgit clonegit rmgit fetchgit mergegit checkoutgit statusgit branchgit log复制代码
创建本地仓库 - git init
# 在一个文件夹中,初始化仓库,会生成一个 .git 文件夹,其中包含版本管理的全部信息git init复制代码
添加文件到暂存区 - git add
# 暂存工作空间所有改变git add -A# 暂存多个文件git add <file>...git add thing.jsgit add thing.js remote.js复制代码

提交 - git commit
# 将暂存区的内容提交本地仓库git commit -m <message>git commit -m "提交信息"# git 提交有规范约束,当你填写错误的时候,可以用这个命令修改提交信息git commit --amend -m <message>git commit --amend -m "修改上次提交的备注信息"复制代码
比较文件不同 - git diff
# 比较所有文件的不同git diff <files>git diff thing.jsgit diff thing.js remote.js复制代码
基于容易明白提交的差异,我习惯用 GitLens 查看。


推送 - git push
推送到指定分支 (没有追踪关系也可以推送)
# 将本地分支推送至远程分支,分支不存在会创建git push <origin> <localbranch>:<remotebranch>git push origin master:ceshigit push origin master:master将指定分支推送到远程分支复制代码
多个远程仓库推送
当有多个远程库的时候,用来指定默认的远程仓库及对应的分支git push -u origin master:master用来推送到默认的远程仓库的分支git push复制代码
推送标签
git push origin <tag_name>git push origin vjail-2.1.1复制代码
将远程仓库拉取合并本地仓库 - git pull
同步追踪关系的分支
# 在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。# 比如,在git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系# 也就是说,本地的master分支自动”追踪”origin/master分支Git也允许手动建立追踪关系。git branch --set-upstream master origin/nex复制代码
同步指定分支的合并,有追踪关系的
git pull <remote> <remotebranch>:<branch>将远程dev与本地master合并git pull origin dev:master将远程dev合并到当前分支git pull origin dev复制代码
同步指定分支的合并,没有追踪关系
拉取远程的更新git fetch合并远程的分支到当前分支git merge -m "合并ceshi->master" origin/ceshi复制代码
管理追踪的远程仓库 - git remote
查看关联远程库
git remoteoriginorigin2复制代码
查看详细信息
git remote -v# fetch 代表你有拉取远程更新合并到本地,push 代表你有权限推送本地更新到远程origin https://gitee.com/zhangpanqin/jail_git_study.git (fetch)origin https://gitee.com/zhangpanqin/jail_git_study.git (push)origin2 https://gitee.com/zhangpanqin/jail_git_study2.git (fetch)origin2 https://gitee.com/zhangpanqin/jail_git_study2.git (push)复制代码
关联远程库
git remote add [shortname] [url]git remote add origin https://gitee.com/zhangpanqin/jail_git_study.gitgit fetch关联远程库之后,使用git fetch 将远程库的信息拉取下来不更新复制代码
克隆 - git clone
git clone https://gitee.com/zhangpanqin/jail_git_study.git在当前目录下创建jail_git_study,代码在jail_git_study复制代码
从工作空间删除 - git rm
删除文件, 会丢失与之有关的暂存区内容, 工作空间也会删除
git rm thing.js复制代码
删除文件夹, 会丢失与之有关的暂存区内容, 工作空间也会删除
git rm -r -f delete复制代码
删除远程仓库文件,不会丢失暂存区内容,文件会存在工作空间
git rm -r --cached thing.js复制代码
拉取远程仓库的更新 - git fetch
git fetch <remote> <remotebranch>从远程仓库拉取仓库信息,不进行别的操作复制代码
合并 - git merge
将指定本地分支合并到当前分支
git merge <branchname># 将 dev 分支合并到当前分支git merge dev复制代码
将远程仓库修改合并到本地
git fetchgit merge -m "将远程仓库的更新合并到当前分支" origin/ceshi复制代码
合并分支,去掉多余的提交记录
# GitLens 有对应的操作git merge --squash dev2复制代码
检出 - git checkout
撤销修改
git checkout -- thing.js一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和本地仓库一模一样的状态;一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。总之,就是让这个文件回到最近一次git commit或git add时的状态。复制代码
切换分支
# 一般不用命令,开发工具自带图形化界面# 将当前分支检出新分支 dev 并切换到dev,这个从当前最新提交检出git checkout dev# 有的时候我们需要从某个提交记录来进行检出,修改git checkout 1cb9718c58565fe95cfe9ea650ecc0f08e3978ef复制代码
切换并创建分支
# 一般不用命令,开发工具自带图形化界面git checkout -b <branchname>git checkout -b bug_102复制代码
查看文件状态 - git status
# 一般不用命令,开发工具自带图形化界面# 查看所有文件状态git status# 查看单个文件状态git status thing.js# 查看多个文件状态git status thing.js remote.js复制代码
分支 - git branch
查看分支
# 一般不用命令,开发工具自带图形化界面git branch复制代码
- 创建分支
# 一般不用命令,开发工具中操作git branch <branchname>git branch bug_103复制代码
- 删除本地分支
# 当前分支如果没有合并的话,会提示删除不了git branch -d <branchname># 强制删除分支git branch -D <branchname>git branch -d bug_103复制代码
日志 - git log
查看所有的提交日志
# 一般不用命令,开发工具中操作git log复制代码
查看具体文件的日志
# 一般不用命令,开发工具中操作git log thing.js remote.js复制代码
不常用但很重要的命令
重置 - git reset
改变指针位置,暂存区,工作区,听着挺吓人的,做操作之前建议 git commit 下,将所有的内容都添加到版本记录中,这样不管什么时候的内容,你做了什么操作,都是可以找回那时的内容的
# 改变指针到指定位置,指定位置的暂存区和当前暂存区共存,# 工作空间没有暂存的也不会丢失,安全操作,不会丢失内容git reset --soft# 改变指针到指定位置,指定位置的暂存区内容和当前位置的暂存区内容回归到工作空间,#工作空间没有暂存的也不会丢失,安全操作,不会丢失内容git reset --mixed# 改变指针到指定位置,暂存区清空和工作区改变到指定位置时的内容,# 没有暂存的内容会丢失,慎用此操作git reset --hard重置最一次提交git reset --soft HEAD~1重置两次的提交git reset --soft HEAD~2复制代码
重置到 commitid
# GitLens 自带操作图形化界面操作git reset --soft <commitid>复制代码
git revert
代码回滚,只会操作对应提交记录改变的文件。比如说 hash 123456 操作修改了 demo.js thingjs.js, 你使用 git revert 只会是这两个文件回滚代码了,别的文件不会受到影响。
git revert -e b8607ad7161b024e6eab17c1270b5fa6e5971bec复制代码
git stash
有的时候代码不想提交,但是不得不更新线上的代码,可以先通过 git stash 储藏当前代码,然后 git pull 之后再应用储藏。
VsCode 使用 GitLens 和自带版本管理工具都可以操作。

变基 - git rebase
将当前分支变基到 branch
将当前分支变基到指定分支git rebase <branch>git rebase dev复制代码
git rebase 和 git merge 区别在于提交记录不分叉。
合并多个提交
将多个commit合并到commitid上 控制台打印如下命令git rebase -i commitid编辑文件pick eecc30a 11 =》pick eecc30a 11pick c6e3cb3 12 =》s c6e3cb3 12pick 4aec63e 13 =》s 4aec63e 13保存退出:wq修改合并之后commit的message注意:保存退出之后没有弹出修改日志 尝试如下命令git add -agit rebase --continue复制代码
打标签 - git tag
版本发布了,打个标签做标识,出现 bug 比较方便检出对应的分支进行修复。
查看某个标签信息
git show <tagname>复制代码
在当前分支打 tag
git tag <tagname>git tag vjail-2.0.0在某个提交点打tag,用-a指定标签名,-m指定说明文字 ,commitidgit tag -a v0.1 -m "version 0.1 released" 1094adb复制代码
删除 tag
git tag -d <tagname>git tag -d vjail-2.0.0复制代码
推送 tag
git push origin vjail-2.0.0复制代码
忽略文件版本控制
忽略未加入版本控制的文件
将路径加入到.gitignore,并将.gitignore提交复制代码
忽略已加入版本控制的文件 (远程库文件存在)
1、取消版本控制的文件git update-index --assume-unchanged 文件或者文件夹2、将取消版本控制的文件加入版本控制git update-index --no-assume-unchanged 文件或者文件夹复制代码
Git 提交规范
参考 Angular 团队提议的《AngularJS Git Commit Message Conventions》
格式如下
<type>(<scope>): <subject> 必须填写空一行<body> 选填空一行<footer> 选填复制代码
不管是哪一个部分,任何一行都不得超过 72 个字符
- type 类型有如下,只能从一下列表选择
build:影响生成系统或外部依赖性的更改feat:新功能(feature)fix:修补 bugdocs:文档(documentation)style: 格式(不影响代码运行的变动)refactor:重构(即不是新增功能,也不是修改 bug 的代码变动)test:增加测试chore:构建过程或辅助工具的变动ci:更改 CI 配置文件和脚本perf:提高性能的代码更改
scope影响范围subject是 commit 目的的简短描述,不超过 50 个字符bodyBody 部分是对本次 commit 的详细描述,可以分成多行footer只有两种情况写 footer- 不兼容变动
- 关闭 JIRA 的 Issue,格式
Fixes #PROJECT-1,有三个触发词Resolves解决Fixes修复Closes关闭
例子 1
feat($browser): onUrlChange event (popstate/hashchange/polling)Added new event to $browser:- forward popstate event if available- forward hashchange event if popstate not available- do polling when neither popstate nor hashchange availableBreaks $browser.onHashChange, which was removed (use onUrlChange instead)复制代码
例子 2
fix($compile): couple of unit tests for IE9Older IEs serialize html uppercased, but IE9 does not...Would be better to expect case insensitive, unfortunately jasmine doesnot allow to user regexps for throw expectations.Closes #392Breaks foo.bar api, foo.baz should be used instead复制代码
我的 Git 使用经验
本地的 master 和 dev 分支不会用于日常开发。
当需要开发一个需求的时候,我会先将本地 dev 与远程进行更新。然后从 dev 检出一个新的分支进行开发。
新分支上开发,如果提交了多次提交记录,我会使用 git rebase 合并多余的提交记录,保持提交记录简洁。 切换到 dev 分支,与远程仓库同步,然后将新分支合并到 dev 分支。再 推送远程分支。
每个分支只会对应一个需求,不会多个需求都在同一个分支开发。开发一个需求,合并之后,会删除临时分支。
SSH 操作
GitHub 上的教程很详细了,就不列了。
HOST githubhostname github.comIdentityFile ~/.ssh/id_rsa_user2@email.com复制代码
