Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于Git那些事儿 #39

Open
FrankKai opened this issue Apr 22, 2018 · 3 comments
Open

关于Git那些事儿 #39

FrankKai opened this issue Apr 22, 2018 · 3 comments
Labels

Comments

@FrankKai
Copy link
Owner

FrankKai commented Apr 22, 2018

内容包括:

  • Git常用命令
    • git克隆远程分支仓库
    • 查看git用户名和密码
    • 分支相关
    • 查看git历史
    • 按照关键词搜索git历史
    • 查看commit历史
    • 设置git账号
    • 查看git账号
    • 仅仅查看某一项的配置
    • 回滚本次修改
    • 查看本次修改的代码
    • 提交后发现丢了几个文件没有提交,发现丢了修改记录,重新添加后最终只有一个提交
    • 缓存某种后缀的文件
    • 清除缓存区中的文件
    • 彻底删除某种后缀的文件
    • 合并分支到master
    • add .之前取消提交某些文件
    • 藏代码到脏目录(适用于其他成员修改了相同分支代码,但又不想提交)
    • 释放脏目录代码
    • 删除远程分支(此分支必须是非默认分支)
    • 已经commit,强制回退到旧版本
    • 查看stash目录
    • 删除某一个stash
    • 设置远程仓库地址
    • 本地创建了新分支,但是orgin没有,push代码前
    • 指定tag到远程
    • 将全部tag打到远程
    • 查看当前tags
    • 仅仅删除index不删除working tree上的.idea文件
    • git主动track文件,控制文件,做好提交准备
    • git unstage文件,释放文件,选择性控制
    • 暂存区文件如何覆盖工作目录文件
    • 提交已经被git管理的,modified为红色的所有文件
    • 重置工作区和暂存区的所有文件为原始状态
    • 比较当前分支与某次提交的区别
    • 删除一个分支
    • 同步到remote后,合并多个commit 为1个
    • 查看项目的origin代表的地址
    • pick中途误退出
    • 未同步到remote,重新提交
    • gitflow release 发布新版本
    • gitflow hotfix 修复一个master上的bug
    • 对比2个分支的日志
    • 合并master代码到feature
    • git rebase冲突时怎么办
    • squash多个commits成一个怎么敲?
    • 查看当前分支的父分支
    • 撤销远程分支错误提交
    • 误删除领先远程的本地分支如何恢复?
    • 删除由npm version patch/minor/major误添加的tag
    • git fetch与git pull的区别
    • 远程分支删除,本地git fetch不能更新到最新分支
    • 及时查看本地所有分支的状态
    • 假如远程已不存在这个分支,git fetch --prune也更新不到状态,该怎么办?
    • 删除单个脱离的远程分支
    • 取消一次合并(merge)
  • 优雅使用Git的一些实践
    • windows下gitbash支持中文输入
    • 生成ssh-key
    • windows查看ssh-key
    • mac/linux查看ssh-key
    • git flow
    • 误删除stash,该怎么办?
    • .idea修改总是会提醒,.gitignore不生效
    • Git中的origin是什么?
    • Git为什么越来越受欢迎?
    • Git的system,global和local参数分别代表什么?
    • Git工作区和暂存区的区别?
    • Git如何重命名文件?
    • Git的working tree和index是什么意思?
    • nothing to commit 和 working tree clean?
    • 如何一目了然地区分出工作区和暂存区?
    • 如何更加优雅地查看日志?
    • 如何快速定位到git的命令文档?
    • git自带的图形化界面怎么看?
    • git 里的作者和提交人不一样吗?
    • 神秘的.git目录
    • 如何判断git文件的类型?
    • tree, commit, blob的区别?
    • 一个commit包含了哪些?
    • 一个tree包含了哪些?
    • 一个blob包含了哪些?
    • detached HEAD是什么?
    • HEAD可以指向什么?
    • 如何修改最新一次commit的message?
    • 如何修改老旧commit的message?
    • git stash pop stash@{n}还能做什么操作?
    • gitflow模式下,如何规范版本发布?
    • 创建一个新的项目并上传到git
    • git参数--decorate是什么?
    • error Command "husky-run" not found.
  • oh-my-zsh 常用命令
    • 缩写全写对照表
    • 使用小技巧
@FrankKai FrankKai changed the title Git常用命令总结 如何更优雅的使用Git? Apr 22, 2018
@FrankKai
Copy link
Owner Author

FrankKai commented Apr 22, 2018

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 "[email protected]"
    git config user.name "Frankkai"
    git config user.email "[email protected]"

  • 查看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 [email protected]: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分支。

https://www.git-tower.com/learn/git/faq/difference-between-git-fetch-git-pull

  • 远程分支删除,本地git fetch不能更新到最新分支
git fetch --prune

--prune
Before 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>
git rebase -i [hash]
第1个pick保留,其余pick改为s
:wq

@FrankKai
Copy link
Owner Author

FrankKai commented Apr 22, 2018

优雅使用Git的一些实践

  • windows下gitbash支持中文输入:
    1)鼠标左键点击左上角git的logo
    2)找到options并且切换到text目录,将Character set设置为UTF-8

  • 生成ssh-key
    ssh-keygen -t rsa -C "[email protected]"

  • 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.io/git-flow-cheatsheet/index.html

  • 误删除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为什么越来越受欢迎?
    SVN集中式VCS需要客户端与服务端时刻相连,并且没有完整的版本库。
    Git分布式VCS两端都有完整的版本库,脱离服务端后客户端自己可以做版本控制,交付和集成的效率得到很大的提升。
    Git是由linux内核核心开发者linus开发出来的,原因是不满集中式VCS的性能以及bitkeeper商业化,Git在存储,性能,备份,离线,工作流方面都很优秀。
    Git促进了DevOps的发展,开源社区Github提供代码存储和第三方CI/CD,Gitlab社区版本自带了CI机制,因此国内阿里云,点评,去哪儿,携程均是基于Gitlab做二次开发。

  • 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则是指操作系统的工作树,也就是操作系统的磁盘上存储的文件。
    举两个常用的例子:
  1. 仅删除git index中的文件,.idea等IDE隐藏的工作树文件是不能删除的:--cached
    git rm --cached -r .idea // **--cached仅仅删除index**,-r(recursive)递归删除.idea目录下的所有文件
  2. 删除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 <[email protected]> 1548139120 +0800
committer FrankKai <[email protected]> 1548139120 +0800

Merge branch 'feature/chatBreakChange' into prerelease

# Conflicts:
#       src/api/chat.js
  • 一个tree包含了哪些?
git cat-file -p [tree hash fragment]

包含tree,blob。

100644 blob 015aaf344153ed7822069b2a98898b7d7a215b0d    .babelrc
100644 blob 9d08a1a828a3bd2d60de3952744df29f9add27fa    .editorconfig
100644 blob 080140b833db5b758b1eb869a269f4bbb068a19e    .eslintignore
100644 blob 8f777c376c0314e480f9bbba273d4902810bcb11    .eslintrc.js
100644 blob 895e844218637929546ed2295ae90f991ceb5d38    .gitignore
100644 blob db7b635d23657349dbe4c33cc353ef4efd8ca960    .npmrc
100644 blob 797e871f4b8c0a3071e8b6ab2cc40b804cd2971c    .postcssrc.js
100644 blob d3983c1d6a5525aae58b823448723434ca83ceed    .prettierrc
100644 blob 93cc7473ab066204f3329221111a945e2dc83576    BUS.md
100644 blob defc3d9914d1af08e6670b96995261bfe1fb61a6    CHANGELOG.md
100644 blob bfd46fd4008cbe7103181fc5cd64392a74426e96    MQTT.md
100644 blob abdb55935d833dd4f4b79475aa7d63ffcb0cc9cd    README.md
040000 tree f1f80f844bb80389826198a15ec0f224a53525f8    build
100644 blob 2aefa3130f4ff753b5c3e538db53b9b186f12540    index.html
100644 blob 967b8f243420a9a8a07b8f429f0a7ba874a834ad    package-lock.json
100644 blob 35d9fa46f569395b25a87daef4820de42d071831    package.json
040000 tree f6bdc675a8f9af805867b5a19c263e5bbfe4c26c    src
040000 tree 09e231414b91779326447a0c8d5b3421aa2308c2    static
040000 tree ad94369cfdd2038a552e44fc0abbd1738113b5e6    test
100644 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~2git 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
  • cherry pick是什么?
    如何理解git cherry pick?

  • 清空所有本地git 缓存

git rm -r --cache .
  • error Command "husky-run" not found
    rm -rf .git/hooks/

  • 一次完整的rebase流程

1. git checkout feature
2. git rebase master
3. resolve conflicts
4. git add .
5. git rebase --continue
  • git revert和git reset的区别
    git revert 生成一个新的commit的方式回滚到上一个或者指定commit版本的代码,原理是Head继续前进。有存在被回滚掉的commit分支代码合并过来时,代码正常被合并
    git reset 删除某个commit之后的代码,原理是Head向后退。有存在被回滚掉的commit分支代码合并过来时,被reset掉的代码仍然会合并上来

  • fatal: 拒绝合并无关的历史
    git pull origin master --allow-unrelated-histories

@FrankKai FrankKai changed the title 如何更优雅的使用Git? 关于Git那些事儿 Apr 22, 2018
@FrankKai
Copy link
Owner Author

FrankKai commented Nov 1, 2019

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

@FrankKai FrankKai added the Git label Mar 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant