Git 的详细使用方法

本篇文章主要为大家详解Git的使用方法,这些命令都是官方给出的git操作,但是在实际工作当中,许多公司会重新包装某些操作,以达到更加安全的方式使用git,因此在实际工作中,还需要详细查看公司的git文档,避免错误操作导致不可逆后果!


可使用 git 的网页教程

也可查看官方使用文档

如果觉得看得不方便?点击链接访问我的个人文档,让你更加直观了解 git!


git 使用秘籍:早建分支!多用分支!

git commit — 创建新的提交记录

git commit

git commit -amend — 将暂存区里面的所有文件作为最近一次提交的修改

git branch — 创建分支

  1. 创建名为 newImage 的分支

git branch newImage

tip: 但是此时使用 git commit 可能不会在新的分支上提交记录,原因是我们提交的记录还是在原来的分支上,需要使用 git checkout newImage 切换分支

  1. 切换到名为 newImage 的分支

git checkout newImage

tip:在 Git 2.23 版本中,引入了一个名为 git switch 的新命令,最终会取代 git checkout,因为 checkout 作为单个命令有点超载(它承载了很多独立的功能)。 由于现在很多人还无法使用 switch,本次课程仍然使用 checkout 而不是 switch, 但是如果你想尝试一下新命令,我们的应用也是支持的!

  1. 创建一个新的分支同时切换到新创建的分支

git checkout -b newImage

  1. 创建一个新的分支同事指向某个节点

git checkout -b newImage C2

git merge / git rebase — 合并分支

  • git merge

  1. 把 bugFix 合并到 main 里

git merge bugFix

  1. 再把 main 分支合并到 bugFix

git checkout bugFix; git merge main

  • git rebase

Rebase 实际上就是取出一系列的提交记录,“复制”它们,然后在另外一个地方逐个的放下去。

Rebase 的优势就是可以创造更线性的提交历史。如果只允许使用 Rebase 的话,代码库的提交历史将会变得异常清晰。

  1. 把 bugFix 分支里的工作直接移到 main 分支上。移动以后会使得两个分支的功能看起来像是按顺序开发,但实际上它们是并行开发的。

git rebase main

tip:提交记录 原先的 bugFix 依然存在,而 bugFix' 是我们 Rebase 到 main 分支上的 bugFix 的副本。

  1. 再将 main rebase 到 bugFix 上

git rebase bugFix

tip:由于 bugFig 继承自 main ,所以 Git 只是简单的把 main 分支的引用向前移动了一下而已。

  1. 其实还有更加简便的方法可以将 bugFix 分支移动到 main 下,并且分支指向 bugFix

git rebase main bugFix

tip:如果 main 和 bugFix 不在同一个分支,使用该命令后,会将 bugFix 有而 main 中没有的提交也一起合并到 main 下;假设 bugFix 和 main 在同一分支下,且 bugFix 在 main 之前,使用该命令后,会将 bugFix 移动到 main 位置,且分支被 bugFix 所指。

  • rebase -i

rebase -i 指的是交互式的 rebase,其中 -i 参数是 -interactive 的缩写。在命令后增加了这个选项, Git 会打开一个 UI 界面并列出将要被复制到目标分支的备选提交记录,它还会显示每个提交记录的哈希值和提交说明,提交说明有助于理解这个提交进行了哪些更改。在实际使用时,所谓的 UI 窗口一般会在文本编辑器 —— 如 Vim —— 中打开一个文件。

Tip:当 rebase UI界面打开时, 能做3件事:

  • 调整提交记录的顺序(通过鼠标拖放来完成)

  • 删除不想要的提交(通过切换 pick 的状态来完成,关闭就意味着不想要这个提交记录)

  • 合并提交(略,待补充)

git rebase -i HEAD~4

HEAD — 当前检索符号

HEAD 是一个对当前检出记录的符号引用 —— 也就是指向你正在其基础上进行工作的提交记录

你可以通俗的理解为使用 git checkout c1 , 那么 HEAD 则指向 c1

如果想看 HEAD 指向,可以通过 cat .git/HEAD查看,如果 HEAD 指向的是一个引用,还可以用 git symbolic-ref HEAD查看它的指向。

git log — 查看提交记录的哈希值

git log

tip:由于 Git 的哈希值有 40 位,例如 fed2da64c0efc5293610bdd892f82a58e8cbc5d8 ,因此为了简化操作,只需要输入 fed2 即可对哈希进行处理。

^ / ~ / -f — 对节点的操作

由于通过哈希值来指定提交记录并不方便,因此, git 还引用了如下两个方法,方便我们对提交记录进行处理。使用 ^ 向上移动 1 个提交记录;使用 ~<num> 向上移动多个提交记录,如 ~3(不跟数字时与 ^相同,向上移动一次)

  • ^

  1. 切换到 main 的父节点

git checkout main^

tip:可以将 HEAD作为相对引用的参照,例如使用 git checkout C3; git checkout HEAD^,此外,如果不加数字修改符直接检出 main^,会回到第一个父提交记录。

  1. 切换到 main 的另外一个父节点

git checkout main^2

  • ~

  1. 后退当前四步

git checkout HEAD~4

Tip:~ 和 ^ 支持链式操作,例如 — git checkout HEAD~^2~2

  1. 创建一个 bugWork 节点,使其指向 main 的上一级的第二分支的上一级

git branch bugWork main~^2~

  • -f

  1. 将 main 分支强制指向 HEAD 的第 3 级父节点提交

git branch -f main HEAD~3

tip:-f 容许我们将分支强制移动到那个位置。

  1. 将 three 分支强制指向 C2 节点

git branch -f three C2

git reset / git revert — 撤销变更

和提交一样,撤销变更由底层部分(暂存区的独立文件或者片段)和上层部分(变更到底是通过哪种方式被撤销的)组成。

  • git reset

Git 把 main 分支移回到 main 的上一层

git reset HEAD~1

Tip:在reset后, C2所做的变更还在,但是处于未加入暂存区状态。

  • git revert

虽然在本地分支中使用 git reset 很方便,但是这种“改写历史”的方法对大家一起使用的远程分支是无效的。为了撤销更改并分享给别人,我们需要使用 git revert

git revent HEAD

Tip:在我们要撤销的提交记录后面其实也并没有删除该分支,反而增添了一个新的分支。这是因为新提交记录 C2' 引入了更改 —— 这些更改刚好是用来撤销 C2 这个提交的。也就是说 C2' 的状态与 C1 是相同的。revert 之后就可以把你的更改推送到远程仓库与其他人分享。

git cherry-pick — 将提交复制到当前位置

将 C2 和 C4 复制到当前 HEAD 下

git cherry-pick C2 C4

git tag — 永久地将某个特定的提交命名为里程碑

tag并不会随着新的提交而移动,也不能切换到某个标签上面进行修改提交,它就像是提交树上的一个锚点,标识了某个特定的位置。

git tag v1 C1

git describe — 查看离最近一次 tag 的距离

git describe 的语法是:

git describe <ref>

<ref> 可以是任何能被 Git 识别成提交记录的引用,如果没有指定的话,Git 会以你目前所检出的位置(HEAD)。

输出的结果:

<tag>_<numCommits>_g<hash>

tag 表示的是离 ref 最近的标签, numCommits 是表示这个 ref 与 tag 相差有多少个提交记录, hash 表示的是给定的 ref 所表示的提交记录哈希值的前几位。当 ref 提交记录上有某个标签时,则只输出标签名称

查看 main 的 git describe

git describe main

输出结果:v1_2_gC2

查看 side 的 git describe

git describe side

输出结果:v2_1_gC4

git clone — 在本地创建一个远程仓库的拷贝

git clone

Tip:在本地仓库多了一个名为 o/main 的分支,o 代表远程仓库的名称(开发中默认为 origin 而不是 o),这种类型的分支就叫做远程分支。远程分支反映了远程仓库(上次和它通信时)的状态,有助于理解本地的工作与公共工作的差别。远程分支有一个特别的属性,在检出时自动进入分离 HEAD 状态。Git 这么做是出于不能直接在这些分支上进行操作的原因。

再次使用 git checkout o/main; git commit

Tip:Git 变成了分离 HEAD 状态,当添加新的提交时 o/main也不会更新。这是因为 o/main只有在远程仓库中相应的分支更新了以后才会更新。

git fetch — 从远程仓库获取(下载)数据

git fetch

Tip:git fetch 完成了仅有的但是很重要的两步,一是从远程仓库下载本地仓库中缺失的提交记录,二是更新远程分支指针,git fetch通常通过互联网(使用 http://或 git://协议) 与远程仓库通信。

  1. git 中常用到抓取后合并的动作

git fetch; git merge o/main

先用fetch下载了 C3, o/main 指向了 C3 然后通过 git merge o/main合并了这一提交记录。现在 main分支包含了远程仓库中的更新。

  1. fetch 的高级操作

  • git fetch <remote> <place>

git fetch origin foo

含义:Git 会到远程仓库的 foo分支上,然后获取所有本地不存在的提交,放到本地的 o/foo上

Tip:使用 fetch 并不会更新本地 foo,原因是考虑到本地的 foo 有可能未修改完,git 不会帮我们篡改本地 foo,而是简单的下载远程 o/foo

  • git fetch <remote> <source>:<destination>

git fetch origin foo~1:bar

将 foo 的上一级分支更新到本地,并且与本地 bar 绑定

Tip:由于已经指定了目标分支,所以 foo 和 o/foo 都没有被更新

当本地分支不存在,则先在本地创建本地新的分支,然后再进行绑定,如下

git fetch origin foo~1:bar

当 <source> 为空时会创建本地分支,如下

git fetch origin :bar

git pull — 抓取并合并到本地分支

由于先抓取更新再合并到本地分支这个流程很常用,因此 Git 提供了一个专门的命令来完成这两个操作。以下用作对比

git pull

可以看出, git pull 就是 git fetchgit merge 的缩写

  1. git pull 的高级用法

git pull origin main 等同于 git fetch origin main; git merge o/main

通过指定 main更新了 o/main。然后将 o/mainmerge 到的检出位置。

git pull origin main:foo 等同于 git fetch origin main:foo; git merge foo

先在本地创建了一个叫 foo的分支,从远程仓库中的 main 分支中下载提交记录,并合并到 foo,然后再 merge 到当前检出的分支 bar上。

git push — 上传且合并远程仓库记录

Tip: git push 不带任何参数时的行为与 Git 的一个名为 push.default 的配置有关。它的默认值取决于正使用的 Git 的版本,目前使用的是 upstream。 在项目进行推送之前,必须要检查该配置。

  1. 正常情况下合并

git push

远程仓库接收了 C2,远程仓库中的 main 分支也被更新到指向 C2,远程分支 (o/main) 也同样被更新。所有分支同步。

  1. 历史偏离时提交合并

所谓历史偏离即在你 push 前,你的同事已经 push 过,那么此时你的代码被 Git 判定为在旧版项目上进行修改的无效代码。

  • rebase

git fetch; git rebase o/main; git push

先是使用 git fetch 更新了 C2 ,再使用 git rebase o/main 创建 C3'main 指向了 C3',再次用 git push 更新了远程分支,并且更新了本地 o/main

  • merge

git fetch; git merge o/main; git push

先是使用 git fetch 更新了 C2 ,再使用 git merge o/main 创建 C4main 指向了 C4,再次用 git push 更新了远程分支 C3 C4,并且更新了本地 o/main 也指向了 C4

  • git pull

git pull --rebase; git push

git pull --rebase 就是 git fetchgit rebase 的缩写

git pull; git push

git pull; git push 就是 git fetchgit merge 的缩写

  1. push 的高级操作

  • git push <remote> <place>

git checkout C0; git push origin main

含义:切到本地仓库中的“main”分支,获取所有的提交,再到远程仓库“origin”中找到“main”分支,将远程仓库中没有的提交记录都添加上去

Tip:在这里使用 git checkout C0 将 HEAD 指向另外的节点的目的是清楚的告诉我们git push origin main 与当前指针无关。

  • git push <remote> <source>:<destination>

git push origin foo^:main

将 foo^ 与远程的 main 绑定,当提交 foo^ 时,会更新到远程仓库的 main 中

当远程分支不存在的时候,会在远程仓库创建新的分支,并且更新本地分支,如下

git push origin main:newBranch

当 <source> 为空时会删除远程仓库的分支,如下

gti push origin :foo

pull request — 远程服务器拒绝(remote rejected)

在一个大的合作团队中工作, 很可能是main被锁定了, 需要一些 pull request 流程来合并修改。如果直接提交(commit)到本地main, 然后试图推送(push)修改, 将会收到这样类似的信息

! [远程服务器拒绝] main -> main (TF402455: 不允许推送(push)这个分支; 你必须使用pull request来更新这个分支.)

正确的做法应该是新建一个分支, 推送(push)这个分支并申请pull request,但是忘记并直接提交给了main是无法推送更新的

远程跟踪分支

通过之前的观察,很容易让人以为 maino/main 是有关联的,实则不然。在进行 pull 操作时, 提交记录会被先下载到 o/main 上,之后再合并到本地的 main 分支。在进行 push 操作时, 工作从 main 推到远程仓库中的 main 分支(同时会更新远程分支 o/main) 。因此,main 的地位可以被随时替代,已达到使用新的分支来跟踪远程分支的目的。

  • checkout -b

  1. 可以创建一个新的分支跟踪远程分支

git checkout -b foo o/main; git pull

Tip:使用远程分支来更新 foo 分支,以便于更好的跟踪远程分支。如下,执行 git checkout -b foo o/main 后会新建一个 foo 分支跟踪 o/main,当输入 git pull 时,会更新本地 o/main,然后分支 foo 跟随 o/main 进行移动,以达到更新 foo 分支的目的。

  1. 创建新分支绑定 o/main,通过 push 更新 o/main

git checkout -b foo o/main; git commit; git push

  • branch -u

可以创建一个新的分支跟踪远程分支

git branch -u o/main foo; git commit; git push

Tip:如果当前就在 foo 分支上, 还可以省略 foo:git branch -u o/main

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值