本文由 简悦 SimpRead 转码, 原文地址 juejin.im

人生是一场难得的修行, 不要轻易交白卷    —- 胡歌

前言

日常开发中,VsCode 我使用自带的源码管理工具结合 GitLens ;IDEA 使用自带的图形化界面 Git 插件。

当前命令基于 Git 2.20.1,系统 MacOs 10.14.5

Git

开发工具之 Git 篇 - 图1开发工具之 Git 篇 - 图2

WorkSpace 工作空间

你在开发工具看到的就是工作空间。

Index 暂存区

数据暂存的地方,当你 git commit 只会把暂存区中的内容添加本地仓库形成 history

Repository 本地仓库

本地仓库,记录文件的修改差异。git commit 的时候会基于修改的内容形成一个 hash , Head (指针) 指向提交的记录。只有提交本地的仓库的内容才不会丢失,都是可以找回来的。

Remote 远程仓库

众多本地仓库内容的汇集地。

开发工具之 Git 篇 - 图3

有的时候呢,命令太多,记不住命令的时候,可以查看帮助信息。

  1. git cmomit --help
  2. git add --help
  3. 复制代码

基础 Git 命令

掌握 Git 基础命令, 日常开发基本就没有问题。

  1. git init
  2. git add
  3. git commit
  4. git diff
  5. git push
  6. git remote
  7. git pull
  8. git clone
  9. git rm
  10. git fetch
  11. git merge
  12. git checkout
  13. git status
  14. git branch
  15. git log
  16. 复制代码

创建本地仓库 - git init

  1. # 在一个文件夹中,初始化仓库,会生成一个 .git 文件夹,其中包含版本管理的全部信息
  2. git init
  3. 复制代码

添加文件到暂存区 - git add

  1. # 暂存工作空间所有改变
  2. git add -A
  3. # 暂存多个文件
  4. git add <file>...
  5. git add thing.js
  6. git add thing.js remote.js
  7. 复制代码

开发工具之 Git 篇 - 图4

提交 - git commit

  1. # 将暂存区的内容提交本地仓库
  2. git commit -m <message>
  3. git commit -m "提交信息"
  4. # git 提交有规范约束,当你填写错误的时候,可以用这个命令修改提交信息
  5. git commit --amend -m <message>
  6. git commit --amend -m "修改上次提交的备注信息"
  7. 复制代码

比较文件不同 - git diff

  1. # 比较所有文件的不同
  2. git diff <files>
  3. git diff thing.js
  4. git diff thing.js remote.js
  5. 复制代码

基于容易明白提交的差异,我习惯用 GitLens 查看。

开发工具之 Git 篇 - 图5开发工具之 Git 篇 - 图6

推送 - git push

推送到指定分支 (没有追踪关系也可以推送)
  1. # 将本地分支推送至远程分支,分支不存在会创建
  2. git push <origin> <localbranch>:<remotebranch>
  3. git push origin master:ceshi
  4. git push origin master:master
  5. 将指定分支推送到远程分支
  6. 复制代码

多个远程仓库推送
  1. 当有多个远程库的时候,用来指定默认的远程仓库及对应的分支
  2. git push -u origin master:master
  3. 用来推送到默认的远程仓库的分支
  4. git push
  5. 复制代码

推送标签
  1. git push origin <tag_name>
  2. git push origin vjail-2.1.1
  3. 复制代码

将远程仓库拉取合并本地仓库 - git pull

同步追踪关系的分支
  1. # 在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。
  2. # 比如,在git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系
  3. # 也就是说,本地的master分支自动”追踪”origin/master分支
  4. Git也允许手动建立追踪关系。
  5. git branch --set-upstream master origin/nex
  6. 复制代码

同步指定分支的合并,有追踪关系的
  1. git pull <remote> <remotebranch>:<branch>
  2. 将远程dev与本地master合并
  3. git pull origin dev:master
  4. 将远程dev合并到当前分支
  5. git pull origin dev
  6. 复制代码

同步指定分支的合并,没有追踪关系
  1. 拉取远程的更新
  2. git fetch
  3. 合并远程的分支到当前分支
  4. git merge -m "合并ceshi->master" origin/ceshi
  5. 复制代码

管理追踪的远程仓库 - git remote

查看关联远程库
  1. git remote
  2. origin
  3. origin2
  4. 复制代码

查看详细信息
  1. git remote -v
  2. # fetch 代表你有拉取远程更新合并到本地,push 代表你有权限推送本地更新到远程
  3. origin https://gitee.com/zhangpanqin/jail_git_study.git (fetch)
  4. origin https://gitee.com/zhangpanqin/jail_git_study.git (push)
  5. origin2 https://gitee.com/zhangpanqin/jail_git_study2.git (fetch)
  6. origin2 https://gitee.com/zhangpanqin/jail_git_study2.git (push)
  7. 复制代码

关联远程库
  1. git remote add [shortname] [url]
  2. git remote add origin https://gitee.com/zhangpanqin/jail_git_study.git
  3. git fetch
  4. 关联远程库之后,使用git fetch 将远程库的信息拉取下来不更新
  5. 复制代码

克隆 - git clone

  1. git clone https://gitee.com/zhangpanqin/jail_git_study.git
  2. 在当前目录下创建jail_git_study,代码在jail_git_study
  3. 复制代码

从工作空间删除 - git rm

删除文件, 会丢失与之有关的暂存区内容, 工作空间也会删除
  1. git rm thing.js
  2. 复制代码

删除文件夹, 会丢失与之有关的暂存区内容, 工作空间也会删除
  1. git rm -r -f delete
  2. 复制代码

删除远程仓库文件,不会丢失暂存区内容,文件会存在工作空间
  1. git rm -r --cached thing.js
  2. 复制代码

拉取远程仓库的更新 - git fetch

  1. git fetch <remote> <remotebranch>
  2. 从远程仓库拉取仓库信息,不进行别的操作
  3. 复制代码

合并 - git merge

将指定本地分支合并到当前分支
  1. git merge <branchname>
  2. # 将 dev 分支合并到当前分支
  3. git merge dev
  4. 复制代码

将远程仓库修改合并到本地
  1. git fetch
  2. git merge -m "将远程仓库的更新合并到当前分支" origin/ceshi
  3. 复制代码

合并分支,去掉多余的提交记录

  1. # GitLens 有对应的操作
  2. git merge --squash dev2
  3. 复制代码

检出 - git checkout

撤销修改
  1. git checkout -- thing.js
  2. 一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和本地仓库一模一样的状态;
  3. 一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
  4. 总之,就是让这个文件回到最近一次git commitgit add时的状态。
  5. 复制代码

切换分支
  1. # 一般不用命令,开发工具自带图形化界面
  2. # 将当前分支检出新分支 dev 并切换到dev,这个从当前最新提交检出
  3. git checkout dev
  4. # 有的时候我们需要从某个提交记录来进行检出,修改
  5. git checkout 1cb9718c58565fe95cfe9ea650ecc0f08e3978ef
  6. 复制代码

切换并创建分支
  1. # 一般不用命令,开发工具自带图形化界面
  2. git checkout -b <branchname>
  3. git checkout -b bug_102
  4. 复制代码

查看文件状态 - git status

  1. # 一般不用命令,开发工具自带图形化界面
  2. # 查看所有文件状态
  3. git status
  4. # 查看单个文件状态
  5. git status thing.js
  6. # 查看多个文件状态
  7. git status thing.js remote.js
  8. 复制代码

分支 - git branch

查看分支
  1. # 一般不用命令,开发工具自带图形化界面
  2. git branch
  3. 复制代码
  • 创建分支
  1. # 一般不用命令,开发工具中操作
  2. git branch <branchname>
  3. git branch bug_103
  4. 复制代码
  • 删除本地分支
  1. # 当前分支如果没有合并的话,会提示删除不了
  2. git branch -d <branchname>
  3. # 强制删除分支
  4. git branch -D <branchname>
  5. git branch -d bug_103
  6. 复制代码

日志 - git log

查看所有的提交日志
  1. # 一般不用命令,开发工具中操作
  2. git log
  3. 复制代码

查看具体文件的日志
  1. # 一般不用命令,开发工具中操作
  2. git log thing.js remote.js
  3. 复制代码

不常用但很重要的命令

重置 - git reset

改变指针位置,暂存区,工作区,听着挺吓人的,做操作之前建议 git commit 下,将所有的内容都添加到版本记录中,这样不管什么时候的内容,你做了什么操作,都是可以找回那时的内容的

  1. # 改变指针到指定位置,指定位置的暂存区和当前暂存区共存,
  2. # 工作空间没有暂存的也不会丢失,安全操作,不会丢失内容
  3. git reset --soft
  4. # 改变指针到指定位置,指定位置的暂存区内容和当前位置的暂存区内容回归到工作空间,
  5. #工作空间没有暂存的也不会丢失,安全操作,不会丢失内容
  6. git reset --mixed
  7. # 改变指针到指定位置,暂存区清空和工作区改变到指定位置时的内容,
  8. # 没有暂存的内容会丢失,慎用此操作
  9. git reset --hard
  10. 重置最一次提交
  11. git reset --soft HEAD~1
  12. 重置两次的提交
  13. git reset --soft HEAD~2
  14. 复制代码

重置到 commitid
  1. # GitLens 自带操作图形化界面操作
  2. git reset --soft <commitid>
  3. 复制代码

git revert

代码回滚,只会操作对应提交记录改变的文件。比如说 hash 123456 操作修改了 demo.js thingjs.js, 你使用 git revert 只会是这两个文件回滚代码了,别的文件不会受到影响。

  1. git revert -e b8607ad7161b024e6eab17c1270b5fa6e5971bec
  2. 复制代码

git stash

有的时候代码不想提交,但是不得不更新线上的代码,可以先通过 git stash 储藏当前代码,然后 git pull 之后再应用储藏。

VsCode 使用 GitLens 和自带版本管理工具都可以操作。

开发工具之 Git 篇 - 图7

变基 - git rebase

将当前分支变基到 branch
  1. 将当前分支变基到指定分支
  2. git rebase <branch>
  3. git rebase dev
  4. 复制代码

git rebase 和 git merge 区别在于提交记录不分叉。

合并多个提交
  1. 将多个commit合并到commitid 控制台打印如下命令
  2. git rebase -i commitid
  3. 编辑文件
  4. pick eecc30a 11 =》pick eecc30a 11
  5. pick c6e3cb3 12 =》s c6e3cb3 12
  6. pick 4aec63e 13 =》s 4aec63e 13
  7. 保存退出
  8. :wq
  9. 修改合并之后commitmessage
  10. 注意:保存退出之后没有弹出修改日志 尝试如下命令
  11. git add -a
  12. git rebase --continue
  13. 复制代码

打标签 - git tag

版本发布了,打个标签做标识,出现 bug 比较方便检出对应的分支进行修复。

查看某个标签信息
  1. git show <tagname>
  2. 复制代码

在当前分支打 tag
  1. git tag <tagname>
  2. git tag vjail-2.0.0
  3. 在某个提交点打tag,用-a指定标签名,-m指定说明文字 ,commitid
  4. git tag -a v0.1 -m "version 0.1 released" 1094adb
  5. 复制代码

删除 tag
  1. git tag -d <tagname>
  2. git tag -d vjail-2.0.0
  3. 复制代码

推送 tag
  1. git push origin vjail-2.0.0
  2. 复制代码

忽略文件版本控制

忽略未加入版本控制的文件
  1. 将路径加入到.gitignore,并将.gitignore提交
  2. 复制代码

忽略已加入版本控制的文件 (远程库文件存在)

  1. 1、取消版本控制的文件
  2. git update-index --assume-unchanged 文件或者文件夹
  3. 2、将取消版本控制的文件加入版本控制
  4. git update-index --no-assume-unchanged 文件或者文件夹
  5. 复制代码

Git 提交规范

参考 Angular 团队提议的《AngularJS Git Commit Message Conventions》

格式如下

  1. <type>(<scope>): <subject> 必须填写
  2. 空一行
  3. <body> 选填
  4. 空一行
  5. <footer> 选填
  6. 复制代码

不管是哪一个部分,任何一行都不得超过 72 个字符

  • type 类型有如下,只能从一下列表选择
    • build:影响生成系统或外部依赖性的更改
    • feat:新功能(feature)
    • fix:修补 bug
    • docs:文档(documentation)
    • style: 格式(不影响代码运行的变动)
    • refactor:重构(即不是新增功能,也不是修改 bug 的代码变动)
    • test:增加测试
    • chore:构建过程或辅助工具的变动
    • ci:更改 CI 配置文件和脚本
    • perf:提高性能的代码更改
  • scope 影响范围
  • subject 是 commit 目的的简短描述,不超过 50 个字符
  • body Body 部分是对本次 commit 的详细描述,可以分成多行
  • footer 只有两种情况写 footer
    • 不兼容变动
    • 关闭 JIRA 的 Issue,格式Fixes #PROJECT-1,有三个触发词
      • Resolves 解决
      • Fixes 修复
      • Closes 关闭

例子 1

  1. feat($browser): onUrlChange event (popstate/hashchange/polling)
  2. Added new event to $browser:
  3. - forward popstate event if available
  4. - forward hashchange event if popstate not available
  5. - do polling when neither popstate nor hashchange available
  6. Breaks $browser.onHashChange, which was removed (use onUrlChange instead)
  7. 复制代码

例子 2

  1. fix($compile): couple of unit tests for IE9
  2. Older IEs serialize html uppercased, but IE9 does not...
  3. Would be better to expect case insensitive, unfortunately jasmine does
  4. not allow to user regexps for throw expectations.
  5. Closes #392
  6. Breaks foo.bar api, foo.baz should be used instead
  7. 复制代码

我的 Git 使用经验

本地的 master 和 dev 分支不会用于日常开发。

当需要开发一个需求的时候,我会先将本地 dev 与远程进行更新。然后从 dev 检出一个新的分支进行开发。

新分支上开发,如果提交了多次提交记录,我会使用 git rebase 合并多余的提交记录,保持提交记录简洁。 切换到 dev 分支,与远程仓库同步,然后将新分支合并到 dev 分支。再 推送远程分支。

每个分支只会对应一个需求,不会多个需求都在同一个分支开发。开发一个需求,合并之后,会删除临时分支。

SSH 操作

GitHub 上的教程很详细了,就不列了。

GibHub ssh 指南

  1. HOST github
  2. hostname github.com
  3. IdentityFile ~/.ssh/id_rsa_user2@email.com
  4. 复制代码

推荐 Blog