惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Security @ Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tenable Blog
C
CERT Recently Published Vulnerability Notes
T
Threatpost
C
Cisco Blogs
Know Your Adversary
Know Your Adversary
T
Tor Project blog
博客园 - 司徒正美
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
宝玉的分享
宝玉的分享
博客园 - 三生石上(FineUI控件)
L
LangChain Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Stack Overflow Blog
Stack Overflow Blog
Microsoft Security Blog
Microsoft Security Blog
AWS News Blog
AWS News Blog
人人都是产品经理
人人都是产品经理
P
Proofpoint News Feed
酷 壳 – CoolShell
酷 壳 – CoolShell
A
Arctic Wolf
L
LINUX DO - 热门话题
C
Cyber Attacks, Cyber Crime and Cyber Security
爱范儿
爱范儿
美团技术团队
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Hugging Face - Blog
Hugging Face - Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Privacy International News Feed
PCI Perspectives
PCI Perspectives
H
Heimdal Security Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
F
Full Disclosure
SecWiki News
SecWiki News
T
The Blog of Author Tim Ferriss
Help Net Security
Help Net Security
Google DeepMind News
Google DeepMind News
P
Palo Alto Networks Blog
博客园 - 叶小钗
C
Check Point Blog
Scott Helme
Scott Helme
V
Visual Studio Blog
博客园 - 聂微东
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Google Online Security Blog
Google Online Security Blog
大猫的无限游戏
大猫的无限游戏
The Register - Security
The Register - Security

北海虽赊,扶摇可接

博客同步 - 腾讯云 - 微信 EMC 知识总结 - EMC - 硬件设计 一篇文章让你彻底掌握 Shell - Linux - 工具 《华为是怎样对待供应商的》 - 职场 - 工作 话术 - 职场 - 工作 复杂度分析 - 综合 - 数据结构和算法 - 软件 代码工程规范 - 工作效率 - 工作 个人目录管理规范 - 工作效率 - 工作 技术文档规范 - 工作效率 - 工作 嵌入式编程技巧项目启动说明书 - 工作效率 - 工作 《常用 shell 命令整理之操作文件和目录 3》 - Linux - 工具 《常用 shell 命令整理之操作文件和目录 2》 - Linux - 工具 《常用 shell 命令整理之操作文件和目录 4》 - Linux - 工具 《常用 shell 命令整理之操作文件和目录 1》 - Linux - 工具 《软件工程之美》笔记 - 笔记 - 软件 《软件工程》笔记 - 笔记 - 软件 《硬件设计经验谈》 - 硬件设计 | Metalheart = 北海虽赊,扶摇可接 = 「 勇敢者是到处有路可走的 」 《职场求生攻略》 - 职场 - 工作
《Git 知识点整理》 - Git - 工具
本文作者: Metal-Heart @北海虽赊,扶摇可接 · 2022-10-12 · via 北海虽赊,扶摇可接
  • repository
  • config
  • init
  • clone
  • fetch
  • pull
  • commit
  • push
  • branch
  • head
  • tag
  • merge
  • conflict
  • diff
  • log
  • show
  • status

# 2. Git 工作空间和文件状态

# (1). 工作空间

Git工作空间

左侧为工作区,右侧为版本库。

  • 工作区( Working Directory ) 就是在电脑里能看到的目录,比如 learngit 文件夹就是一个工作区。
  • 版本库( Repository )工作区有一个隐藏目录 .git ,是 Git 的版本库。

在版本库中标记为 index 的区域为暂存区,标记为 master 的是 Git 为我们自动创建的第一个分支,代表的是目录树。此时 HEAD 实际是指向 master 分支的一个 “游标”,所以图示的命令中出现 HEAD 的地方可以用 master 来替换。图中的 objects 标识的区域为 git 的对象库,实际位于 .git/objects 目录下。

  • 当对工作区修改(或新增)的文件执行 git add 命令时,暂存区的目录树会被更新,同时工作区修改(或新增)的文件内容会被写入到对象库中的一个新的对象中,而该对象的 id 被记录在暂存区的文件索引中。
  • 当执行提交操作 git commit 时,暂存区的目录树会写到版本库(对象库)中,master 分支会做相应的更新,即 master 最新指向的目录树就是提交时原暂存区的目录树。
  • 当执行 git reset HEAD 命令时,暂存区的目录树会被重写,会被 master 分支指向的目录树所替换,但是工作区不受影响。
  • 当执行 git rm --cached 命令时,会直接从暂存区删除文件,工作区则不做出改变。
  • 当执行 git checkout .git checkout -- 命令时,会用暂存区全部的文件或指定的文件替换工作区的文件。这个操作很危险,会清楚工作区中未添加到暂存区的改动。
  • 当执行 git checkout HEAD .git checkout HEAD 命令时,会用 HEAD 指向的 master 分支中的全部或部分文件替换暂存区和工作区中的文件。这个命令也是极度危险的。因为不但会清楚工作区中未提交的改动,也会清楚暂存区中未提交的改动。

# (1). 文件状态

Git 有三种状态,你的文件可能处于其中之一:已提交 ( committed )已修改 ( modified )已暂存 ( staged )

# 3. Git 配置系统级、全局、当前仓库用户名、邮箱的命令

系统级、全局、当前仓库选项分别是:仓库 - system、-global、-local (或默认不填)

git config --global user.name "Jerry Mouse"
git config --global user.email "jerry@yiibai.com"

列出 Git 设置

git config --list
git config -l

# 4. Git fetch 和 pull 的区别

  • git fetch :相当于是从远程获取最新版本到本地,不会自动 merge.
  • git pull :相当于是从远程获取最新版本并 merge 到本地.

# (1). git fetch 示例:

Git fetch origin master
git log -p master..origin/master
git merge origin/master

以上命令的含义:

  • 首先从远程的 originmaster 主分支下载最新的版本到 origin/master 分支上
  • 然后比较本地的 master 分支和 origin/master 分支的差别
  • 最后进行合并
  • 上述过程其实可以用以下更清晰的方式来进行:

# (1). git pull 示例:

git pull origin master

上述命令其实相当于 git fetchgit merge 。在实际使用中, git fetch 更安全一些,因为在 merge 前,我们可以查看更新情况,然后再决定是否合并。

# 5. Git reset 和 revert 的却别

  • git revert 是用一次新的 commit 来回滚之前的 commit, git reset 是直接删除指定的 commit。
  • 在回滚这一操作上看,效果差不多。但是在日后继续 merge 以前的老版本时有区别。因为 git revert 是用一次逆向的 commit “中和” 之前的提交,因此日后合并老的 branch 时,导致这部分改变不会再次出现,但是 git reset 是之间把某些 commit 在某个 branch 上删除,因而和老的 branch 再次 merge 时,这些被回滚的 commit 应该还会被引入。
  • git reset 是把 HEAD 向后移动了一下,而 git revert 是 HEAD 继续前进,只是新的 commit 的内容和要 revert 的内容正好相反,能够抵消要被 revert 的内容。
  • git revert 与 git reset 最大的不同是,git revert 仅仅是撤销某次提交。

另外,说一下 git revertgit reset –hard–soft 的区别

  • git reset –mixed id : 是将 git 的 HEAD 变了(也就是提交记录变了),但文件并没有改变,(也就是 working tree 并没有改变)。
  • git reset –soft id : 实际上,是 git reset –mixed id 后,又做了一次 git add
  • git reset –herd id : 是将 git 的 HEAD 变了,文件也变了。

# 6. Git merge 和 reabse 的相同点和不同点

merge 是合并的意思, rebase 是复位基底的意思,相同点都是用来合并分支的。

merge和rebase

不同点:

  • merge 操作会生成一个新的节点,之前的提交分开显示。而 rebase 操作不会生成新的节点,是将两个分支融合成一个线性的提交。
  • 解决冲突时。merge 操作遇到冲突的时候,当前 merge 不能继续进行下去。手动修改冲突内容后,add 修改,commit 就可以了。而 rebase 操作的话,会中断 rebase, 同时会提示去解决冲突。解决冲突后,将修改 add 后执行 git rebase –continue 继续操作,或者 git rebase –skip 忽略冲突。
  • git pullgit pull --rebase 区别: git pull 做了两个操作分别是 "获取" 和 "合并"。所以加了 rebase 就是以 rebase 的方式进行合并分支,默认为 merge。

总结:选择 merge 还是 rebase?

  • merge 是一个合并操作,会将两个分支的修改合并在一起,默认操作的情况下会提交合并中修改的内容
  • merge 的提交历史忠实地记录了实际发生过什么,关注点在真实的提交历史上面
  • rebase 并没有进行合并操作,只是提取了当前分支的修改,将其复制在了目标分支的最新提交后面
  • rebase 的提交历史反映了项目过程中发生了什么,关注点在开发过程上面
  • merge 与 rebase 都是非常强大的分支整合命令,没有优劣之分,使用哪一个应由项目和团队的开发需求决定
  • merge 和 rebase 还有很多强大的选项,可以使用 git help <command> 查看

# 7. Git stash 是什么?它的相关使用方式命令

  • git stash: 备份当前的工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时,将当前的工作区内容保存到 Git 栈中。
  • git stash pop: 从 Git 栈中读取最近一次保存的内容,恢复工作区的相关内容。由于可能存在多个 Stash 的内容,所以用栈来管理,pop 会从最近的一个 stash 中读取内容并恢复。
  • git stash pop --index stash@{0}: 恢复编号为 0 的进度的工作区和暂存区。
  • git stash apply stash@{1} 以将你指定版本号为 stash@{1} 的工作取出来
  • git stash drop [<stash>] 删除某一个进度,默认删除最新进度
  • git stash list: 显示 Git 栈内的所有备份,可以利用这个列表来决定从那个地方恢复。
  • git stash clear: 清空 Git 栈。此时使用 gitg 等图形化工具会发现,原来 stash 的哪些节点都消失了
git stash pop [--index] [<stash>]
--index 参数:不仅恢复工作区,还恢复暂存区
<stash> 指定恢复某一个具体进度。如果没有这个参数,默认恢复最新进度
git stash [save message] [-k|--no-keep-index] [--patch]
-k和--no-keep-index指定保存进度后,是否重置暂存区
--patch 会显示工作区和HEAD的差异,通过编辑差异文件,排除不需要保存的内容。和git add -p命令类似
使用save可以对进度添加备注

# 8. Git 只从暂存区删除,从工作空间删除的命令分别是什么?

git rm --cached
git rm
git commit

# 9. Git 标签的使用

git tag
git tag -a v1.01 -m "Relase version 1.01"
git show v1.4
  • -a 选项,创建一个含附注类型的标签
  • -m 选项,指定了对应的标签说明

# 9. Git 分支的使用

git branch
git branch -r
git branch [name]
git checkout [name]
git checkout -b [name]
git branch -D [name]
git merge [name]
git br -v
git br --merged
git br --no-merged

# 10. 介绍 Git 冲突处理经验,以及 merge 和 rebase 中的 ours 和 theirs 的差别。

merge 和 rebase 对于 ours 和 theirs 的定义是完全相反的。在 merge 时,ours 指代的是当前分支,theirs 代表需要被合并的分支。而在 rebase 过程中,ours 指向了修改参考分支,theirs 却是当前分支。因为 rebase 隐含了一个 git checkout upstream 的过程,将 HEAD 从 local 分支变成了 upstream 分支。git 会在 rebase 结束后撤销这个改变,但它已经不可避免地影响了冲突的状态,使 rebase 中 ours 和 theirs 的定义与 merge 截然相反。因此,在使用 ours 与 theirs 时请格外小心。

# 11. Git 远程操作相关

# (1). clone

git clone <版本库的网址>
git clone <版本库的网址> < 本地目录名 >

 git clone https://github.com/jquery/jquery.git
 
 git clone -o jQuery https://github.com/jquery/jquery.git

# (2). remote

git remote
git remote -v
 
git remote show <主机名>
 
git remote add <主机名> <网址>
git remote rm <主机名>
git remote rename <原主机名> <新主机名>

# (3). fetch

git fetch <远程主机名>
git fetch <远程主机名> <分支名>
git fetch origin master
git merge origin/master
git rebase origin/master

# (4). pull

git pull <远程主机名> < 远程分支名 >:< 本地分支名 >

git pull origin next:master
git pull origin next
git fetch origin
git merge origin/next
git pull --rebase <远程主机名> <远程分支名>:<本地分支名>

# (5). push

git push <远程主机名> < 本地分支名 >:< 远程分支名 >

注意:分支推送顺序的写法是 "<来源地>:< 目的地 >",所以 git pull 是 "< 远程分支 >:< 本地分支 >",而 git push 是 "< 本地分支 >:< 远程分支 >"。

  • 如果省略远程分支名,则表示将本地分支推送与之存在” 追踪关系” 的远程分支 (通常两者同名),如果该远程分支不存在,则会被新建。
  • 如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。
git push origin master
git push origin :master
git push origin --delete master
git push origin
git push
git push -u origin master
git push --all origin
git push --force origin
git push origin --tags

# 12. Git Flow 使用简介

就像代码需要代码规范一样,代码管理同样需要一个清晰的流程和规范。三种广泛使用的工作流程:

  • Git flow
  • Github flow
  • Gitlab flow

三种工作流程,有一个共同点:都采用 "功能驱动式开发"(Feature-driven development,简称 FDD)。它指的是,需求是开发的起点,先有需求再有功能分支(feature branch)或者补丁分支(hotfix branch)。完成开发后,该分支就合并到主分支,然后被删除。最早诞生、并得到广泛采用的一种工作流程,就是 Git flow

它最主要的特点有两个。首先,项目存在两个长期分支,分别是:主分支 master、开发分支 develop。其次,项目存在三种短期分支,分别是:功能分支(feature branch)、补丁分支(hotfix branch)、预发分支(release branch),一旦完成开发,它们就会被合并进 develop 或 master,然后被删除。

# (1). Git Flow 流程图

Git Flow流程图

# (2). Git Flow 常用的分支

  • Production 分支。也就是我们经常使用的 Master 分支,这个分支最近发布到生产环境的代码,最近发布的 Release, 这个分支只能从其他分支合并,不能在这个分支直接修改。
  • Develop 分支。这个分支是我们是我们的主开发分支,包含所有要发布到下一个 Release 的代码,这个主要合并与其他分支,比如 Feature 分支。
  • Feature 分支。这个分支主要是用来开发一个新的功能,一旦开发完成,我们合并回 Develop 分支进入下一个 Release。
  • Release 分支。当你需要一个发布一个新 Release 的时候,我们基于 Develop 分支创建一个 Release 分支,完成 Release 后,我们合并到 Master 和 Develop 分支。
  • Hotfix 分支。当我们在 Production 发现新的 Bug 时候,我们需要创建一个 Hotfix, 完成 Hotfix 后,我们合并回 Master 和 Develop 分支,所以 Hotfix 的改动会进入下一个 Release。

# (3). Git Flow 代码示例

# a. 创建 develop 分支

git branch develop
git push -u origin develop

# b. 开始新 Feature 开发

git checkout -b some-feature develop
git push -u origin some-feature
git status
git add some-file
git commit

# c. 完成 Feature

git pull origin develop
git checkout develop
git merge --no-ff some-feature
git push origin develop
git branch -d some-feature
git push origin --delete some-feature

# d. 开始 Relase

git checkout -b release-0.1.0 develop

# e. 完成 Release

git checkout master
git merge --no-ff release-0.1.0
git push
git checkout develop
git merge --no-ff release-0.1.0
git push
git branch -d release-0.1.0
git push origin --delete release-0.1.0   
git tag -a v0.1.0 master
git push --tags

# f. 开始 Hotfix

git checkout -b hotfix-0.1.1 master

# g. 完成 Hotfix

git checkout master
git merge --no-ff hotfix-0.1.1
git push
git checkout develop
git merge --no-ff hotfix-0.1.1
git push
git branch -d hotfix-0.1.1
git tag -a v0.1.1 master
git push --tags