欢迎关注公众号“燕小书”,回复:“技术交流”进微信技术交流群,公众号会陆续发布优质文章。

规范

开篇刚开始我们就要提一下规范的git习惯,并做持续更新。规范的习惯,让我们更加专业

如何维护commit

commit 规范

  1. 'feat', // 新功能(feature)
  2. 'fix', // 修复bug
  3. 'upd', // 更新某功能
  4. 'refactor', // 重构
  5. 'docs', // 文档(documentation)
  6. 'chore', // 构建过程或辅助工具的变动
  7. 'style', // 格式(不影响代码运行的变动)
  8. 'revert', // 撤销commit
  9. 'perf', // 性能优化
  10. 'test', // 测试(单元、集成测试)

保持commit提交记录的有效率

  1. 1. 当我们提交代码到本地仓库的时候,经常会遇到重复提交的情况。
  2. 场景:
  3. 刚刚commit完毕,发现描述信息有误,需要修改一下描述信息再次提交;
  4. commit信息没有错,但是修改了一下代码的格式,最后也需要重新提交。
  5. 这样无非在分析(仓库管理工具gitlab)提交记录增加了混淆度,
  6. 因此我们可以在提交到暂存区后使用git commit --amend ,这个命令的
  7. 作用是对上一次commit描述进行修改,因此就解决了重复commit的问题。
  8. 2.如果git commit --amend后,你git pull origin daily/0.0.1发现提示
  9. `fatal: refusing to merge unrelated histories`
  10. 解决: git pull origin daily/0.0.1 --allow-unrelated-histories
  11. 但是正常情况下,都是在自己的分支上开发的,也就不会出现远程仓库领先于自己仓库
  12. 的情况,所以也就没有必要再次执行命令:git pull origin daily/0.0.1
  13. 3.撤回commit的命令:
  14. git reset --soft commitID 绿
  15. git reset --mixed commitID
  16. git reset --hard commitID
  17. 每一次的commitId肯定是不同的,所以再次commit然后git push时会报错:
  18. hint: Updates were rejected because the tip of your current branch is behind
  19. hint: its remote counterpart. Integrate the remote changes (e.g.
  20. hint: 'git pull ...') before pushing again.
  21. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
  22. 解决: 可以 git push --force
  23. stage/index > working/directory如下
  24. git reset HEAD readme.txt 暂存区》工作区
  25. git checkout readme.txt 撤销工作区的更改
  26. 。。。。。。。

增删某条commit

  • 删除中间某一条commit ``` 1.git log获取commit信息

2.git rebase -i (commit-id)

commit-id 为要删除的commit的下一个commit号

3.编辑文件,将要删除的commit之前的单词改为drop

4.保存文件退出大功告成

5.git log查看

  1. <a name="xRsHI"></a>
  2. #### 摘commit命令
  3. git cherry-pick commitId 将某一条commit合并到当前所在分支<br />[http://www.ruanyifeng.com/blog/2020/04/git-cherry-pick.html](http://www.ruanyifeng.com/blog/2020/04/git-cherry-pick.html)
  4. <a name="UwV6s"></a>
  5. ## 准备工作
  6. 当你领到一台新电脑或者已有电脑重装系统了,你需要做哪些,来使用git。
  7. 1. 生成ssh秘钥
  8. windows+R输入命令ssh-keygen -t rsa -C "[asdf@163.com](mailto:asdf@163.com)"<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/5363336/1657705096317-64fb72f6-2c8e-490c-be01-84d1c46768f2.png#clientId=u5eb2d68d-254f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=198&id=uc1dbb91d&name=image.png&originHeight=396&originWidth=674&originalType=binary&ratio=1&rotation=0&showTitle=false&size=25930&status=done&style=none&taskId=u89328283-bc1d-4d62-8bf5-0a6d48d2dea&title=&width=337)<br />问题:我们需要的是公共秘钥,如果没有 .pub后缀的文件<br />原因:隐藏了已知文件类型的扩展名<br />解决:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/5363336/1657705110725-bd423ec1-739a-4e24-9e07-9270f1e01254.png#clientId=u5eb2d68d-254f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=314&id=uf4997c99&name=image.png&originHeight=628&originWidth=840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=83463&status=done&style=none&taskId=u402512ed-53a4-4ad0-a13e-50bbf491100&title=&width=420)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/5363336/1657705124871-66d0ef1e-506d-43d7-826a-c0d297f55006.png#clientId=u5eb2d68d-254f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=307&id=udd4db5a2&name=image.png&originHeight=614&originWidth=458&originalType=binary&ratio=1&rotation=0&showTitle=false&size=45831&status=done&style=none&taskId=u308ba36e-94a4-4814-a72b-ac095f0e204&title=&width=229)
  9. 2. 登录github新建ssh key<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/5363336/1657705137631-31c558d7-1e46-4970-8e28-5ccf7c7c3165.png#clientId=u5eb2d68d-254f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=286&id=u4a240cc0&name=image.png&originHeight=571&originWidth=1279&originalType=binary&ratio=1&rotation=0&showTitle=false&size=70801&status=done&style=none&taskId=u207aff62-70ca-4c03-b9ab-0e996b1fc3b&title=&width=639.5)
  10. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/5363336/1657705150387-74ee664d-ff2c-45bc-bed2-46790868e906.png#clientId=u5eb2d68d-254f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=286&id=u4c380ba2&name=image.png&originHeight=571&originWidth=1279&originalType=binary&ratio=1&rotation=0&showTitle=false&size=58501&status=done&style=none&taskId=u448fbd05-5832-488a-b34a-5beb15f308d&title=&width=639.5)
  11. 3. 验证ssh

本地新建文件夹右键Git Bash Here git init git config user.name ‘github名字’ git config user.email ‘github绑定的邮箱’ 本地仓库与远程仓库建立连接: git remote add origin git@github.com:China_forrest/learngit.git
git remote -v 查看连接情况 git remote rm origin 断开与远程仓库的连接
把远程仓库源代码拉取到本地 git pull origin master 这里的master指的是远程仓库的分支名 然后yes 验证成功后,就会把远程分支master分支的代码拉取到我本地的文件夹, 同时在本地创建一个master分支 建立本地分支与远程分支的连接 git branch —set-upstream-to origin daily/0.0.1 第一次推送的时候git push -u origin 分支名

  1. 至此新的电脑或新的系统:本地仓库重新建立了与远程仓库的连接
  2. <a name="KscrI"></a>
  3. #### 从远程库拉代码之git clone和git pull的区别
  4. 1.是否是需要本地是一个仓库

git clone 不需要本地仓库(.git文件夹) 在本地仓库文件夹内生成一个新的文件夹alibaba git pull 需要先初始化本地文件夹为一个本地仓库(有.git文件夹) 直接将远程仓库文件夹内的文件拷贝到本地仓库(文件夹) ``` git clone
image.png
git pull
image.png
2.切换分支(仅限于刚拉下代码的时候)
git clone git远程仓库已有的分支可以直接进行切换
image.png
git pull 不能直接切换远程仓库 已有的分支
image.png
3.推送远程库

  • git clone 直接指定分支可以推动到远端

    1. git chekcout -b dev
    2. git push --set-upstream origin dev
  • git pull 先指定源 ``` git remote add origin git@github.com:rdmclin2/learngit.git,远程库的名字叫origin git pull origin master // 或者可以这样 git merge master 将master分支合并到当前分支

git push -u origin ‘分支名’

  1. <a name="ZeblE"></a>
  2. ## 知道
  3. 关于git命令我们仅仅知道,git add,git commit, git push,是不能满足团队协作开发的。本文将对git命令作出系统的总结。
  4. <a name="KNQ4u"></a>
  5. ## 团队协作
  6. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/5363336/1657705310531-f0c01813-c578-448e-937e-4e3a946f30f5.png#clientId=u5eb2d68d-254f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=150&id=u2b1c7835&name=image.png&originHeight=300&originWidth=828&originalType=binary&ratio=1&rotation=0&showTitle=false&size=82137&status=done&style=none&taskId=u8c8adab0-92aa-4f5a-a8c7-1541c621baf&title=&width=414)
  7. - 首先,可以试图使用git push origin branch-name 推送自己的修改
  8. - 如果推送失败,则因为远程分支比你的本地分支更新,需要用git pull试图合并
  9. - 如果合并有冲突,则解决冲突,并在本地提交;
  10. - 没有冲突或者解决冲突后,再用git push origin branch-name 推送就能够成功
  11. - 如果git pull 提示 "no tracking information",则说明本地分支和远程分支的链接关系没有创建,用git branch --set-upstream branch-name origin/branch-name
  12. 注意:不要直接在迭代分支上写代码:比如我们这次的迭代分支是dev,那么在dev上checkout出自己的开发分支,一个功能完成后提交MR到dev上,有其他同学来review,有问题的地方进行整改,全部ok后合并入dev。等dev也稳定之后合并入master.
  13. <a name="h0Fnw"></a>
  14. ## 关联本地和远程分支
  15. - 第一种,远程分支如dev,本地分支如dev,<br />用git branch --set-upstream dev origin/dev
  16. - 第二种,本地分支创建分支如dev,用git push -u origin dev,将本地分支上传到远程仓库,并关联起来,如果远程分支没有dev分支,会自动创建。
  17. - 第三种,抓取远程分支并在本地建立关联的分支,<br />用git chekcout -b local-branchname origin/remote_branchname
  18. <a name="IS7sD"></a>
  19. ## Commit提交规范
  20. 根据[angular规范](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit-message-format)提交commit,这样history看起来更加清晰,还可以自动生成changelog。
  21. ```javascript
  22. <type>(<scope>:<subject>)
  23. <BLANK LINE>
  24. <body>
  25. <BLANK LINE>
  26. <footer>

(1)type
提交commit 的类型,包括以下几种

  • feat:新功能
  • fix:修复问题
  • docs:修改文档
  • style:修改代码格式,不影响代码逻辑
  • refactor:重构代码,理论上不影响现有功能
  • pref:提升性能
  • test:增加修改测试用例
  • chore:修改工具相关(包括但不限于文档、代码生成等)
  • deps:升级依赖
    (2)scope
    修改文件的范围(包括但不限于doc,middleware,proxy,core,config)
    (3)subject
    用一句话清楚的描述这次提交做了什么
    (4)body
    补充subject,适当增加原因、目的等相关因素,也可以不写
    (5)footer
  • 当有非兼容修改时可以在这里描述清楚
  • 关联issue,如Close #1, Close #2 ,#3
  • 如果功能点有新增或这修改的,还需要关联 chair-handbook和chair-init的MR,如chair/doc!123

示例:

  1. 1 fix($compile) : couple of unit test for IE9
  2. 2
  3. 3 Older IEs serialize html html uppercased, but IE9 does not ...
  4. 4 Would be better to expect case insensitive,unfortunately jasmine does
  5. 5 not allow to user regexps for throw expectations.
  6. 6
  7. 7 Document change on chair/doc!123
  8. 8
  9. 9 Cloes #392
  10. 10 Breaks foo.bar api, foo.baz should be used instead

具体查看文档点这里
提交Merge Request
如果你有仓库的开发者权限,而且希望贡献代码,那么你可以创建分支修改代码提交MR,让负责人review代码合并到主干。

  1. //先创建开发分支开发,分支名应该有含义,避免使用update、tmp之类的
  2. $ git checkout -b branch-name
  3. //开发完成后跑下测试是否通过,必要时需要新增或修改测试用例
  4. $ npm run test
  5. //测试通过后提交代码,message建下面的规范
  6. $ git add . //git add -u 删除文件
  7. $ git commit -m "fix(role):role.use must xxx"
  8. $ git push origin branch-name

提交后就可以在gitlab创建MR了。
由于谁也无法保证过了多久之后还记得多少,为了后期回溯历史的方便,请在MR时确保提供一下信息。

  1. 需求点(一般关联issue或者注释都算)
  2. 升级原因(不同于issue,可以简述一下为什么要处理)
  3. 框架测试点(可以关联到测试文件,不用详细描述,关键点即可)
  4. 关注点(针对用户而言,可以没有,一般是不兼容更新等,需要额外提示)

指令集合

  1. 设置
  2. git config --global user.name 'Your Name'
  3. 全局设置用户名 "--global"代表所有仓库使用这一配置
  4. 全局设置邮箱
  5. git config --global user.email "email@example.com"
  6. .gitignore 编写
  7. git config --global alias. <new order> order为命令设置别名
  8. $ git config --global alias.st status 告诉Git,以后st就表示status,下面列一些常用设置
  9. $ git config --global alias.co checkout
  10. $ git config --global alias.ci commit
  11. $ git config --global alias.br branch
  12. $ git config --global alias.unstage 'reset HEAD' 撤销暂存区修改
  13. $ git config --global alias.last 'log -1' 显示最近一次提交
  14. $ git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" 简直丧心病狂!
  15. 如果要修改别名,当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中,可以直接修改

基本操作

  1. git init 初始化一个git 仓库
  2. git add <file> 添加文件到仓库,可以多次add 如:git add readme.txt
  3. git reset HEAD <file> 从暂存区撤销一个add
  4. git reset HEAD test.tsx
  5. git commit -m "" 快速提交代码,多次add 一次commit
  6. git rm <file> 从版本库删除某文件
  7. 丢弃工作区的修改
  8. git checkout --<file>
  9. git checkout --readme.txt
  10. git checkout . 丢弃所有本地修改
  11. 如果已经add,可以用git reset HEAD <file> 先撤销add,再丢弃更改
  12. 如果你已经commit了,可以用 git reset --hard HEAD^ 进行回退上一个版本<慎重操作>。
  13. 尽量使用: git reset --soft HEAD^ 或者 git reset --mixed HEAD^。
  14. 如果你已经推送远程分支了,也就凉凉了......
  1. git status 仓库状态
  2. git diff <file>
  3. git diff readme.txt 可以看到当前文件的改动
  4. git diff 列出所有文件的改动
  5. 注意git diff会比较仓库中的文件和不在仓库中的同一文件的差异,也就是git add的文件A以及git add后改动的文件A
  6. 如果没有改动的话,git diff 甚至智能地不自动匹配文件
  7. git log 查看提交历史
  8. $ 从最近到最远 可以加 --pretty=oneline git 显示得更清楚些
  9. $ git log --graph --pretty=oneline --abbrev-commit 用--graph查看分支合并图
  10. $ 版本回退
  11. $ git reset --hard HEAD^, HEAD代表当前版本,HEAD^代表上个版本,Head^^代表上上版本,HEAD-100代表往上100个版本
  12. $ 不过过去了回不来怎么办, 只要命令行窗口没关闭,就可以找到你要回去的commit id,然后再用如 git reset --hard 3628164 回到该版本.
  13. $ 如果第二天后悔了怎么办?用 git reflog 查看所有命令,再找到相应的commit id即可

分支管理

  1. git branch 查看分支
  2. git branch <branch name>
  3. git branch dev 创建分支
  4. git branch -d dev 删除分支
  5. git push origin : <branch name> 删除远程分支
  6. git branch -D <branch name>强行删除分支
  7. git branch -D feature-vulcan 没有进行合并的分支用 -d参数会销毁失败
  8. 如果实在要丢弃一个没有合并过的分支,用-D进行强行销毁
  9. 修改本地分支名称 git branch -m <old_branch_name><new_branch_name>
  10. git branch -m feature-a feature-b
  11. git checkout <branch name> 切换分支
  12. git checkout -b issue-101 创建分支并切换
  13. git merge <branch name> 合并分支(branch name)到当前所在分支
  14. git merge --no-ff -m <message><branch name>
  15. $ 禁用fast forward
  16. $ git merge --no-ff -m "merge with no-ff" dev
  17. $ --no-ff表示禁用fast forward,在ff模式下删除分支后会丢掉分支信息,所以用--no-ff
  18. $ git就会在merge的时候生成一个新的commit,因为要有一个新的commit所以要加上-m参数
  19. 使用no-ff后,会多生成一个commit 记录,并强制保留dev分支的开发记录

git stash的使用场景

  1. 当正在dev分支上开发某个项目,这时项目中出现一个bug,需要紧急修复,但是正在开发的内容只是完成一半,还不想提交,这时可以用git stash命令将修改的内容保存至堆栈区,然后顺利切换到hotfix分支进行bug修复,修复完成后,再次切回到dev分支,从堆栈中恢复刚刚保存的内容。
  2. 由于疏忽,本应该在dev分支开发的内容,却在master上进行了开发,需要重新切回到dev分支上进行开发,可以用git stash将内容保存至堆栈中,切回到dev分支后,再次恢复内容即可。
  3. 总的来说,git stash命令的作用就是将目前还不想提交的但是已经修改的内容进行保存至堆栈中,后续可以在某个分支上恢复出堆栈中的内容。这也就是说,stash中的内容不仅仅可以恢复到原先开发的分支,也可以恢复到其他任意指定的分支上。git stash作用的范围包括工作区和暂存区中的内容,也就是说没有提交的内容都会保存至堆栈中。
    1. git stash save "这里是注释内容" 储藏工作现场,可以把当前的工作现场储藏起来,等以后恢复现场后继续工作
    2. git stash list 列出储藏的工作现场
    3. git stash show 显示做了哪些改动,默认show第一个存储,如果要显示其他存贮,后面加stash@{$num},比如第二个 git stash show stash@{1}
    4. git stash show -p 显示第一个存储的改动,如果想显示其他存存储,命令:git stash show stash@{$num} -p ,比如第二个:git stash show stash@{1} -p
    5. git stash apply 恢复现场,但stash内容不删除
    6. git stash drop 删除现场
    7. git stash pop 恢复现场的同时删除现场
    8. git stash apply <stash id>多个现场时指定恢复某一现场(先用git stash list查看)
    9. git rebase <branch name> 整合分支 变基 高危操作请清楚了解原理和后果后再操作

    git rebase

远程仓库

  1. ssh-keygen -t rsa -C "youremail@email"
  2. 创建ssh-key,将公钥添加到github等网站上
  3. git remote add origin <remote git repo>将本地仓库和远程仓库相关联,在本地仓库执行
  4. git remote add origin git@github.com:rdmclin2/learngit.git,远程库的名字叫origin
  5. 可以添加多个远程仓库如git remote add rdmclin2 git@... origin rdmclin2都是我们为远程仓库取的别名。
  6. git remote set-url origin <remote git repo>
  7. 修改origin 的地址,如:git remote set-url origin git@gitlab.artemisprojects.org:menchenglin/fcws.git
  8. git push origin <branch name>
  9. 将本地内容推送到远程
  10. git push origin master,如果是第一次推送的话:git push -u origin master,
  11. 也就是第一次加上-u参数,可以吧本地分支和远程分支关联起来,以后就不要添加-u参数了
  12. git clone <remote git repo>
  13. 从远程仓库克隆
  14. 如: git clone git@github.com:michaelliao/gitskills.git,非常常用的操作
  15. clone时可以指定深度,git clone git://xx00 --depth 1
  16. git remote
  17. 常看远程库信息,加上-v参数可以显示更加详细的信息
  18. git pull
  19. 抓取远程分支最新提交并合并分支
  20. git tag v0.9 6224937,可以先用git log --pretty=oneline --abbrev-commit 查看历史提交
  21. git fetch
  22. 抓取远程分支最新提交(与pull的区别是fetch不直接合并)
  23. git branch ---set-upstream <local branch> <remote branch>
  24. 指定本地分支和远程分支的链接
  25. git branch --set-upstream dev origin/dev 指定本地div分支与远程origin/dev分支的链接
  26. git tab <name>
  27. 打标签 git tag v1.0
  28. git tag
  29. 查看所有标签,按字母排序
  30. gitshow <tagname>
  31. 查看标签信息
  32. git tag <name> <commit id>
  33. 给某次提交打上标签
  34. git tag v0.9 6224937,可以先用git log --pretty=oneline --abbrev-commit 查看历史提交
  35. git tag -a <tagname> -m <message> <commit id>
  36. 创建带有说明的标签
  37. git tag -a v0.1 -m "version 0.1 released" 3628164 , -a 指定标签名, -m 指定说明文字
  38. git tag -s <tagname> -m <message> <commit id>
  39. 采用PGP签名一个标签
  40. git tag -s v0.2 -m "signed version 0.2 released " fec145a , -s 用私钥签名一个标签
  41. 看这里http://www.ruanyifeng.com/blog/2013/07/gpg.html 了解如何安装gnupg
  42. git tag -d <tagname>
  43. 删除标签 git tag -d v0.1
  44. git push origin <tagname>
  45. 推送标签到远程
  46. git push origin v1.0
  47. git push origin --tags
  48. 一次性推送全部尚未推送到远程的本地标签
  49. git push origin :refs/tags/<tagname>
  50. 如: git push origin :refs/tags/v0.9

现有工程中删除 .DS_Store

$ find . -name .DS_Store - print0 | xargs -0 git rm -f —ignore-unmatch
向顶层的.gitignore文件中增加 .DS_Store然后
$ git add .gitignore
$ git commit -m ‘.DS_Store banished’

下载github上单个文件夹

将 /tree/master换成/trunk/, 然后用svn checkout,例如:
svn checkout https://github.com/Mooophy/Cpp-Primer/trunk/ch03
gists介绍:
https://www.zhihu.com/question/21343711
http://www.worldhello.net/gotgithub/06-side-projects/gist.html