一份工作4年前端的Git备忘指南

简介: 一份工作4年前端的Git备忘指南

image.png


刚毕业的时候用过极短时间的SVN,后面就一直在用Git来做代码的版本控制了,前前后后差不多4年的时间,期间做了一些在使用Git过程中的记录和心得,在这里分享给大家,大家或许可以从中吸收到一些有用的东西。

无论是github,还是gitlab,还是其他的代码托管平台,代码管理都是用git去做的,git可以说是一名程序员的必备技能,对于工作和面试都是非常有帮助的。

  • Git常用命令
  • 优雅使用Git的一些实践
  • oh-my-zsh 常用命令


Git常用命令


  • git克隆远程分支仓库:
    git clone -b 分支名称 远程地址
    git克隆远程仓库项目时如果不指定分支,只会克隆默认分支的内容。
  • 查看git用户名和密码
    git config user.name
    git config user.email
  • 分支相关
    git branch(查看当前分支)
    git branch -a(查看所有分支)
    git checkout 分支名(切换到对应分支) 会自动将代码更新为分支代码
    git branch 分支名(创建一个分支)
    git branch -d 分支名(删除一个分支)
    git branch -D 分支名(强制删除一个未合并的分支)
    git checkout -b 分支名 [基于的分支名或commit值](切换分支并直接切换过去)
  • 查看git历史
    history
  • 按照关键词搜索git历史
    history | grep push
  • 查看commit历史
    git log
    git log --summary
  • 设置git账号
    git config --global user.name "Frankkai"
    git config --global user.email "gaokai20100801@gmail.com"
    git config user.name "Frankkai"
    git config user.email "gaokai20100801@gmail.com"
  • 查看git账号
    git config --global --list
    git config --local --list
  • 仅仅查看某一项的配置
    git config --local user.name
  • 回滚本次修改
    git reset HEAD static/lib/js/constantsUrl.js
    git checkout -- static/lib/js/constantsUrl.js
  • 查看本次修改的代码
    git diff
    git diff HEAD
    git diff --staged
  • 提交后发现丢了几个文件没有提交
    发现丢了修改记录,重新添加
    git add "*.html"
    重新提交,最终只有一个提交
    git commit --amend
  • 缓存某种后缀的文件
    git add "*.js"
  • 清除缓存区中的文件
    git reset octofamily/octodog.txt
  • 彻底删除某种后缀的文件
    git rm "*.txt"
  • 合并分支到master
    git merge 分支名
  • add .之前取消提交某些文件
    git checkout -- <filename>
  • 藏代码到脏目录(适用于其他成员修改了相同分支代码,但又不想提交)
    git stash
  • 释放脏目录代码
    git stash pop
  • 释放指定脏目录代码
    git stash pop stash@{0}
  • 删除远程分支(此分支必须是非默认分支)
    git push origin --delete branchname
  • 已经commit,强制回退到旧版本
    git log//找到commit hash值
    git reset --hard hash值
  • 查看stash目录
    git stash list
  • 删除某一个stash
    git stash drop stash@{0}
  • 设置远程仓库地址
    git remote set-url origin git@foo.bar.com:baz/helloworld.git
  • 本地创建了新分支,但是orgin没有,push代码前
    git push --set-upstream origin preproduction
  • 指定tag到远程
    git push origin <tag_name>
  • 将全部tag打到远程
    git push --tags
  • 查看当前tags
    git tag --list
  • 仅仅删除index不删除working tree上的.idea文件
    git rm --cached -r .idea // --cached仅仅删除index,-r(recursive)递归删除.idea目录下的所有文件
  • git主动track文件,控制文件,做好提交准备
    git add <file(s)>/.
  • git unstage文件,释放文件,选择性控制
    git reset HEAD <file(s)>/.
  • 暂存区文件如何覆盖工作目录文件
    git reset HEAD <file(s)>/. && git checkout -- <file(s)>/.
  • 提交已经被git管理的,modified为红色的所有文件
    git add -u
  • 重置工作区和暂存区的所有文件为原始状态
    git reset --hard
  • 比较当前分支与某次提交的区别
    git diff HEAD [commit hash fragment]
  • 删除一个分支
    git branch -D [branch name]
  • 同步到remote后,合并多个commit 为1个


git rebase -i HEAD~2/hash
pick && squash
:wq!


  • 查看项目的origin代表的地址
    git remote -v
  • pick中途误退出
    git rebase --abort
  • 未同步到remote,重新提交
    reset soft
  • gitflow release 发布新版本
git flow release start v0.5.0
npm version minor
git flow release finish -n
git push
git checkout master
git push
  • gitflow hotfix 修复一个master上的bug


git flow hotfix start foo
npm version patch // 注意:一定要在修复bug代码之前新增版本号
git add .
git commit -m "version change message"
git flow hotfix finish -n
git push
git checkout master
git push
  • 对比2个分支的日志
git log develop..master


  • 合并master代码到feature
git checkout feature
git merge master
git merge master feature


  • git rebase冲突时怎么办
resolve conficts
git add .
git rebase --continue
  • squash多个commits成一个怎么敲?
  • 假设merge feature到master。
git checkout master
git merge --squash feature
git commit -m "这是一次squash commit"
git push


  • 查看当前分支的父分支
git reflog show <childBranch>
32c3956 (HEAD -> currentBranch, origin/fatherBranch, fatherBranch, list) childBranch@{0}: branch: Created from fatherBranch

childBranch 是你新建的分支。
fatherBranch 是它的父分支,也就是来源分支。


  • 撤销远程分支错误提交
...reset
git push --force


  • 其实使用本地分支的提交替代远程分支。


  • 误删除领先远程的本地分支如何恢复?
git reflog // 找出最新的commit sha1值,HEAD@{1}比HEAD@{2}新
git branch branchName <sha1>


通过git reflog找到一个commit,然后再cherry-pick也可以。


  • 删除由npm version patch/minor/major误添加的tag


git tag | grep v1.1.38
git tag -d v1.1.38
git push origin :refs/tags/v1.1.38
  • git fetch与git pull的区别
git fetch 更新origin/*下的所有分支,在发布git flow feature前很有用,用于更新remote分支。
git pull 主要用来更新多人合作的当前分支,多用于更新local分支。


git fetch --prune


--pruneBefore fetching, remove any remote-tracking references that no longer exist on the remote.
  • 及时查看本地所有分支的状态
git remote show origin
  • 假如远程已不存在这个分支,git fetch --prune也更新不到状态,该怎么办?
git push origin --delete feature/fix-chat-unread-msg-async
  • 删除单个脱离的远程分支
git remote prune <name>


  • 取消一次合并(merge)
    git merge --abort
  • 回退一次commit
    git revert Head/[commit hash]


优雅使用Git的一些实践


  • windows下gitbash支持中文输入:
    1)鼠标左键点击左上角git的logo
    2)找到options并且切换到text目录,将Character set设置为UTF-8
  • 生成ssh-key
    ssh-keygen -t rsa -C "gaokai20100801@qq.com"
  • windows查看ssh-key
    /c/Users/frank/.ssh/id_rsa.pub
  • mac/linux查看ssh-key
    cd ~/.ssh
    ls
    cat id_rsa.pub
  • git flow
    https://danielkummer.github.i...
  • 误删除stash,该怎么办?


git fsck --unreachable |
grep commit | cut -d\  -f3 |
xargs git log --merges --no-walk --grep=WIP

找到对应的commit hash值

git stash apply 1f55da93d26cd51f15f9e93351dae6b75e25e36f
  • .idea修改总是会提醒,.gitignore不生效

  .idea/

git rm -r --cached .idea


  • Git中的origin是什么?
    origin是一个变量,代表着一个git仓库地址。可以使用git remote -v查看origin代表的地址。
  • Git的system,global和local参数分别代表什么?
--system可以输出很多git的系统设置,其中最有用的是alias,例如git s代表了git status,系统所有登录用户有用。
--global输出了git的全局设置,主要包括全局的user.name和user.email,优先级低于单个仓库中设置的user.name和user.email,当前用户所有仓库有用。
--local输出了git的项目设置,主要包括remote.origin.url以及gitflow的很多配置,只对某个仓库有用。


  • Git工作区和暂存区的区别?
     add           commit
工作目录---->暂存区---->版本历史



  • 暂存区:git已经获得了对文件的管理权限,暂存区文件有状态:new file,deleted,modified等等。

版本历史:git log查看每一次commit记录。

意外收获:


若是想非常细粒度的控制commit记录,可以使用git add 指定文件,分开多次commit,每一次commit提交一个细粒度功能的变更文件集合,多次走文件目录 暂存区 版本历史这个流程。


  • Git如何重命名文件?
git mv README.md readme.md
  • Git的working tree和index是什么意思?
    index指的是git索引,可以理解成git有文件的一个复制,仅删除index则仅删除存在于git中的文件。
    working tree则是指操作系统的工作树,也就是操作系统的磁盘上存储的文件。
    举两个常用的例子:
  • 仅删除git index中的文件,.idea等IDE隐藏的工作树文件是不能删除的:--cached
    git rm --cached -r .idea // **--cached仅仅删除index**,-r(recursive)递归删除.idea目录下的所有文件
  1. 删除index和working tree上的文件,恩断义绝
    git rm 删除index上和working tree上的文件,

仅仅删除working tree不删除index的情况,不存在。

  • nothing to commit 和 working tree clean?
    暂存区没有可以提交到版本历史的内容。
    工作区也是干净的。
  • 如何一目了然地区分出工作区和暂存区?
  • Your branch is ahead of 'origin/master' by 1 commit 版本历史
  • Changes to be committed 暂存区
  • Untracked files 工作区


// 版本历史
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
// 暂存区
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
      renamed:    readme.md -> README.md
      new file:   helloman
// 工作区
Untracked files:
(use "git add <file>..." to include in what will be committed)
      hi
  • 如何更加优雅地查看日志?
    git log --oneline简洁的commit记录
    git log -n2 --oneline最近的2次简洁的commit记录
    git log --all所有分支的历史版本信息
    git log --graph图形化查看版本演进历史
    git log --oneline --all -n4 --graph组合查看日志
  • 如何快速定位到git的命令文档?
    git help --web log 浏览器查看git log的用法
  • git自带的图形化界面怎么看?
    gitk 无需安装第三方插件,在纯命令行下,无第三方软件情况下可用。
  • git 里的作者和提交人不一样吗?
    作者是代码的生成者,是为了版权保护。
  • 神秘的.git目录
    HEAD工作分支refs/heads/foo
    configrepo的配置信息
    refs heads,分支;tags,标签或者里程碑
    refs/heads/master存放了什么,最新的一个commit
    refs/tags/js01存放了什么,最新的一个tag,包含一个object
    objects文件夹,2个字符的和松散的pack文件夹,存放的是tree,tree下有blob文件
    可以直接通过vim修改HEAD,config等信息,和命令的作用是相同的。
  • 如何判断git文件的类型?
    git cat-file -t/-p [hash fragment] // -t 类型,-p 内容
    只要任何文件的文件内容相同,在git眼里,它就是唯一的一个blob。


commit  
tree // 位于objects目录下
blob // 位于objects目录的二级目录下,具体的文件


  • tree, commit, blob的区别?
    commit:一个commit肯定会对应一棵树,包含了根tree,author,committer,parent等等一个commit对象的信息。


tree:取出一个commit,存放了一个快照,这个快照,对应了当前项目的所有的文件夹及其文件的快照,是特定时间的整个仓库的一个状态;树里可以有blob,也可以有树,因为树是文件夹;根树是最大的树。


blob: 与文件名是否相同无关,只要内容相同,就是唯一的blob。


  • 一个commit包含了哪些?


git cat-file -p [commit hash fragment]

包含tree,parent,author和commiter。

tree f06f7f36af17cb9098031c66d22a7910c0fa1bac
parent 92a55c8a5b1d38d224232ad84b9b728ae77189cb
parent eda632a1f2a3ea049c5f5268f6b2f064b71898ce
author FrankKai <gaokai20100801@gmail.com> 1548139120 +0800
committer FrankKai <gaokai20100801@gmail.com> 1548139120 +0800
Merge branch 'feature/chatBreakChange' into prerelease
# Conflicts:
#       src/api/chat.js


  • 一个tree包含了哪些?
git cat-file -p [tree hash fragment]


  • 包含tree,blob。
  • blob 015aaf344153ed7822069b2a98898b7d7a215b0d .babelrc
  • blob 9d08a1a828a3bd2d60de3952744df29f9add27fa .editorconfig
  • blob 080140b833db5b758b1eb869a269f4bbb068a19e .eslintignore
  • blob 8f777c376c0314e480f9bbba273d4902810bcb11 .eslintrc.js
  • blob 895e844218637929546ed2295ae90f991ceb5d38 .gitignore
  • blob db7b635d23657349dbe4c33cc353ef4efd8ca960 .npmrc
  • blob 797e871f4b8c0a3071e8b6ab2cc40b804cd2971c .postcssrc.js
  • blob d3983c1d6a5525aae58b823448723434ca83ceed .prettierrc
  • blob 93cc7473ab066204f3329221111a945e2dc83576 BUS.md
  • blob defc3d9914d1af08e6670b96995261bfe1fb61a6 CHANGELOG.md
  • blob bfd46fd4008cbe7103181fc5cd64392a74426e96 MQTT.md
  • blob abdb55935d833dd4f4b79475aa7d63ffcb0cc9cd README.md
  • tree f1f80f844bb80389826198a15ec0f224a53525f8 build
  • blob 2aefa3130f4ff753b5c3e538db53b9b186f12540 index.html
  • blob 967b8f243420a9a8a07b8f429f0a7ba874a834ad package-lock.json
  • blob 35d9fa46f569395b25a87daef4820de42d071831 package.json
  • tree f6bdc675a8f9af805867b5a19c263e5bbfe4c26c src
  • tree 09e231414b91779326447a0c8d5b3421aa2308c2 static
  • tree ad94369cfdd2038a552e44fc0abbd1738113b5e6 test
  • blob 0b96f21c27a3759cecde02fba1e050d86a8e9a54 yarn.lock
  • 一个blob包含了哪些?


git cat-file -p [tree hash fragment]


  • 就是一个具体的文件。
  • detached HEAD是什么?
    分离头指针。
    git checkout [commit hash fragment],切换到分离头指针状态,不与任何branch或tag关联,git会认为这是不重要的,当成垃圾清理掉。

缺点:切换分支后,需要用git branch [branch name] [commit hash fragment]新建一个分支,否则会丢失原消息。

优点:可以基于某一次commit切出分支,然后新建一个commit,快速会退到想要的版本。


  • HEAD可以指向什么?
    它位于.git/HEAD。

可以指向分支或者commit,但其实分支归根结底还是指向了commit。

git log 查看HEAD指针指向的分支名:(HEAD->foo, bar, master)

可以快速diff,git diff HEAD [commit hash fragment]。

父亲的父亲diff:git diff HEAD HEAD~2,git diff HEAD HEAD^^。

  • 如何修改最新一次commit的message?
    git commit --amend
    注意:不能在团队的集成分支上,做这样的变更,仅适用于本地。
  • 如何修改老旧commit的message?


git rebase -i [父 commit hash fragment]
reward
添加修改后的commit message


  • 注意:不能在团队的集成分支上,做这样的变更,仅适用于本地。
  • git stash pop stash@{n}还能做什么操作?
    当前分支的本地代码未提交的情况下,pull了领先的远程分支代码,此时远程代码会覆盖本地代码。


git比较聪明,它不会完全将本地的代码扔掉,即使没有人为的生成一次commit记录,也会自动为我们在stash下生成一次记录,以免造成重大的代码丢失。


  • gitflow模式下,如何规范版本发布?
版本号升级 gitflow对应
bug -> patch hotfix
feature->minor release
系统重构->major release

但是在scrum的情况下,迭代非常快速,若所有feature都升级minor,会导致minor数字很大,该怎么处理这种情况?


只升级minor时,在commit提交信息中,添加以下信息:


类型 提交信息
bug patch [bug patch]
feature patch [feature patch
  • 创建一个新的项目并上传到git


git init
git ac
git remote add origin remote repository URL


  • git参数--decorate是什么?
  • 有short,full,auto,no几种值,--decorate=short
  • 打印出commit的ref name。
  • short时,ref name 前缀refs/head,refs/tags/和refs/remotes不会打印
  • full时,完整前缀会被打印
  • auto时,如果输出是一个终端,会按照short的方式打印;非终端会显示全部
  • no时,会隐藏HEAD和tag等等refs信息
  • 默认值是short



  • 清空所有本地git 缓存
git rm -r --cache .
  • error Command "husky-run" not found
    rm -rf .git/hooks/
  • 一次完整的rebase流程
  • git checkout feature
  • git rebase master
  • resolve conflicts
  • git add .
  • git rebase --continue
  • git revert和git reset的区别
    git revert 生成一个新的commit的方式回滚到上一个或者指定commit版本的代码,原理是Head继续前进。有存在被回滚掉的commit分支代码合并过来时,代码正常被合并

git reset 删除某个commit之后的代码,原理是Head向后退。有存在被回滚掉的commit分支代码合并过来时,被reset掉的代码仍然会合并上来

oh-my-zsh 常用命令

缩写全写对照表

缩写 全写
gst git status
gaa git add .
gcmsg "" git commit -m ""
gp git push
glog git log --oneline --decorate --graph
gl git pull
gf git fetch
gfa git fetch --all --prune



使用小技巧

  • 如何修改默认指令的参数,比如,glog的decorate默认是short,我想指定glog的decorate为no,要怎么做?
    glog --decorate=no
努力成为优秀前端工程师!


相关文章
|
7月前
|
存储 前端开发 开发工具
前端开发中的Git版本控制:构建可靠的协作和代码管理
前端开发中的Git版本控制:构建可靠的协作和代码管理
86 0
|
JSON 前端开发 JavaScript
前端AJAX入门到实战,学习前端框架前必会的(ajax+node.js+webpack+git)(一)
前端AJAX入门到实战,学习前端框架前必会的(ajax+node.js+webpack+git)(一)
596 0
|
29天前
|
前端开发 持续交付 开发工具
理解前端开发中的 Git - Rebase
Git Rebase 是前端开发中常用的一种版本控制操作,用于将一个分支的更改整合到另一个分支。与合并(Merge)不同,Rebase 可以使提交历史更加线性整洁,有助于保持代码库的清晰和可维护性。通过 Rebase,开发者可以将特性分支的改动应用到主分支上,同时保留或重写提交记录。
|
2月前
|
前端开发 开发工具 git
如何清理 docker 磁盘空间+修改 Gitea 服务器的 Webhook 设置+前端一些好学好用的代码规范-git hook+husky + commitlint
如何清理 docker 磁盘空间+修改 Gitea 服务器的 Webhook 设置+前端一些好学好用的代码规范-git hook+husky + commitlint
38 5
|
2月前
|
前端开发 开发工具 git
搭建Registry&Harbor私有仓库、Dockerfile(八)+前端一些好学好用的代码规范-git hook+husky + commitlint
搭建Registry&Harbor私有仓库、Dockerfile(八)+前端一些好学好用的代码规范-git hook+husky + commitlint
22 0
|
4月前
|
JavaScript IDE 前端开发
前端开发工具配置 nodejs & git & IDE
前端开发工具配置 nodejs & git & IDE
|
4月前
|
存储 前端开发 开发工具
前端常用的git操作
【8月更文挑战第24天】前端常用的git操作
31 1
|
5月前
|
前端开发 JavaScript 开发工具
前端优化之路:git commit 校验拦截
前面在git分支规范那篇文章里,介绍了commit提交规范,但是想要做到高效落地执行,就需要做些别的功课。
|
6月前
|
前端开发 持续交付 开发工具
详细介绍Git的基本原理、在前端开发中的应用以及如何使用Git来优化团队协作
【6月更文挑战第14天】Git是前端开发中的必备工具,它通过分布式版本控制管理代码历史,支持分支、合并和冲突解决,促进团队协作。在前端开发中,Git用于代码追踪、版本控制、代码审查和持续集成部署,优化团队协作。制定分支策略、编写清晰提交信息、定期合并清理分支以及使用Git钩子和自动化工具能进一步提升效率。理解并善用Git,能有效提升前端项目的质量和开发效率。
85 3
|
7月前
|
前端开发 持续交付 开发工具
【专栏:工具与技巧篇】版本控制与Git在前端开发中的应用
【4月更文挑战第30天】Git是前端开发中的必备工具,它通过分布式版本控制管理代码历史,支持分支、合并、回滚等操作,促进团队协作和冲突解决。在前端项目中,Git用于代码追踪、代码审查、持续集成与部署,提升效率和质量。优化协作包括制定分支策略、编写清晰提交信息、定期合并清理分支及使用Git钩子和自动化工具。掌握Git能有效提升开发效率和代码质量。
108 2
下一篇
DataWorks