git基本使用方法整理

目录

常用指令

新电脑关联远程仓库

本地创建仓库

基于远程仓库开发

创建本地仓库

拉取一个远程的新分支

本地分支上开发

本地分支提交至远程dev分支

本地分支推送到远程,远程还未建立需要推送的分支

commit注释规范

修改.gitignore文件后如何生效

git submodules包管理器

保持代码独立

Git Submodule到底是什么

添加一个Submodule

克隆一个含有submodule的项目

使用特定版本

更新Git Submodule

删除Submodule

在工作中使用Git Submodule

使用Git的全部功能

参考文献


常用指令

git clone https://github.com/xx.git 从远程库中克隆

git checkout –b dev 创建并切换到dev分支

git branch –d dev 删除dev分支

git checkout -b 本地分支名 origin/远程分支名  创建一个本地分支,并于远程分支关联

git checkout dev 切换到dev分支上

git add xx/.把xx或所有文件添加到暂存区

git commit –m “XX” 提交文件 –m 后面的是注释

git status 查看仓库状态

git log 查看历史记录

git reset –soft HEAD^ 或者 git reset –soft HEAD~1 回退到上一个版本(仅仅是撤回commit操作,代码仍然保留)

git reset –hard HEAD^ 或者 git reset –hard HEAD~1 回退到上一个版本HEAD~2回退到上上个版本

git remote 查看远程库的信息

git remote –v 查看远程库的详细信息

git branch 查看当前所有的分支

git merge dev 在当前的分支上合并dev分支

git pull 从远程分支拉取最新代码

git push 上传本地分支代码至对应远程分支

git remote show origin 查看远程分支状态

git remote prune origin 删除本地已经不存在的远程分支

新电脑关联远程仓库

生成新 SSH 密钥并添加到 ssh-agent - GitHub Docs

新增 SSH 密钥到 GitHub 帐户 - GitHub Docs

本地创建仓库

git init 把当前的目录变成可以管理的git仓库,生成隐藏.git文件。

基于远程仓库开发

创建本地仓库

  1. git clone https://github.com/zongyunqingfeng/testgit 从远程库中克隆
  2. git checkout –b dev创建并切换到dev分支,作为本地的开发主分支

拉取一个远程的新分支

  1. git pull
  2. git checkout -b feat_new origin/feat_new

        第二步如果报错,则是没有做第一步

        fatal: 'origin/feat_new ' is not a commit and a branch 'feat_new ' cannot be created from it

本地分支上开发

  1. git checkout dev 切换到本地dev分支
  2. git pull 拉取远程最新代码
  3. git checkout -b feat 创建本地feat分支用于开发功能模块

本地分支提交至远程dev分支

  1. git add .把所有文件添加到暂存区
  2. git commit –m “XX” 提交文件 –m 后面的是注释
  3. git pull origin dev 拉取远程dev分支最新代码
  4. 处理冲突并测试:可以使用vscode实现,对于二进制文件可以直接覆盖(要先备份feat分支下的文件,然后直接覆盖掉pull了dev后的文件)
  5. 如果有冲突处理,则需要再一次add和commit
  6. git checkout dev 切换到本地dev分支
  7. git merge --no-ff feat 将本地feat分支代码合并至本地dev分支,如果跳出一个写注释的窗口,可以直接按Q退出
  8. git push 将本地dev分支上传至远程dev分支

本地分支推送到远程,远程还未建立需要推送的分支

        git push origin dev:dev 将本地dev(冒号前的)分支,推送到远程dev(冒号后的)分支,远程如果没有该分支,则会新建一个

commit注释规范

  • feat: 添加新特性
  • fix: 修复bug
  • docs: 仅仅修改了文档
  • style: 仅仅修改了空格、格式缩进、逗号等等,不改变代码逻辑
  • refactor: 代码重构,没有加新功能或者修复bug
  • perf: 优化相关,比如提升性能、体验
  • test: 增加测试用例
  • chore: 改变构建流程、或者增加依赖库、工具等
  • revert: 回滚到上一个版本

修改.gitignore文件后如何生效

#add .gitignore
#查看状态,是否忽略了指定的文件? 
$ git status --ignored #查看状态,包括忽略的文件
 
#让其对已经跟踪的文件也起作用
$ git rm -r --cached .  #清除缓存 -r 表示递归删除(如果有文件夹的话) . 表示所有文件
 
#查看一下具体效果
$ git status --ignored
$ git add .           #重新trace file
$ git commit -m "update .gitignore"     #提交和注释

git submodules包管理器

        大部分现代软件项目都需要依赖于他人的工作,当别人已经实现了一个很好的解决方案,就不需要再浪费时间再去实现一遍。因此很多项目都会以库或模块的形式使用第三方代码。

        Git是世界上最流行的版本控制系统,它提供了一种优雅、健壮的方式管理这些依赖关系。Git的“submodule”概念允许我们引用和管理第三方库,同时保持与我们自己的代码清晰的隔离。

        在本文中,您将了解到为什么Git中的submodule能起作用、它的底层逻辑是什么以及它是如何工作的。

保持代码独立

        为了弄清楚为什么Git的submodule很有价值,让我们先看一个没有submodule的例子。当我们需要引用第三方代码(比如开源库)的时候,最简单的办法是从GitHub下载代码,然后将其保存到自己的项目中。虽然这么做可以很快解决问题,但这么做非常丑陋,原因如下:

  • 通过强制将第三方代码复制到项目中,我们可以有效的将多个项目混合到一个项目中,而我们自己的项目和别人的项目(库)之间的界限开始变得模糊。
  • 每当我们需要更新库代码时(也许是因为它的维护者提供了一个很棒的新特性或修复了一个讨厌的bug),我们都必须再次下载、复制和粘贴,这很快就变成了一个乏味的过程。

        软件开发中“将不同的东西分开”的一般规则是有原因的。当然,在自己的项目中管理第三方代码也需要这样,而Git submodule的概念正是针对这些情况而设计的。

        当然,submodule并不是解决这类问题的唯一方法,我们还可以使用许多现代语言和框架提供的各种“包管理器”系统,选择哪种依赖管理方法并没有绝对的对错之分。

        不过,Git的submodule体系架构有以下几个优点:

  • Submodule提供一致、可靠的接口,和语言或框架无关。当我们使用多种技术时,每种技术可能都有自己的包管理器和自己的一组规则和命令,而Submodule总是可以以相同的方式工作。
  • 不是每段代码都可以通过包管理器复用,有时候我们只想在两个项目之间共享自己的代码,在这种情况下,submodule可以提供最简单的工作流。

Git Submodule到底是什么

        Git中的submodule实际上只是标准的Git repository。并没有什么花哨的创新,就只是我们现在都很熟悉的Git repository而已。这也是submodule的一项优势:它们十分健壮、方便直接,因为从技术角度来说,没有任何新东西在里面,并且经过了大量现场测试的考验。

        使Git repository成为submodule的唯一原因是它被放在了另一个父Git repository中。

        除此之外,Git submodule仍然是一个功能完整的repository:我们可以执行所有常规的Git操作——从修改文件,一直到commit、pull和push,在submodule中都可以实现。

添加一个Submodule

        让我们举一个典型的例子,假设我们想要向项目中添加一个第三方库,在我们获取任何代码之前,需要先创建一个单独的文件夹,作为第三方库存储的路径:

$ mkdir lib
$ cd lib

        现在,我们准备将一些第三方代码以submodule的方式注入到项目中,下面假设我们需要一个小小的“时区转换器”JavaScript库:

$ git submodule add https://github.com/spencermountain/spacetime.git

        当我们运行这个命令时,Git开始将repository作为submodule克隆到我们的项目中:

Cloning into 'carparts-website/lib/spacetime'...
remote: Enumerating objects: 7768, done.
remote: Counting objects: 100% (1066/1066), done.
remote: Compressing objects: 100% (445/445), done.
remote: Total 7768 (delta 615), reused 975 (delta 588), pack-reused 6702
Receiving objects: 100% (7768/7768), 4.02 MiB | 7.78 MiB/s, done.
Resolving deltas: 100% (5159/5159), done.

        看一下工作区文件夹,我们可以看到库文件实际上已经加到项目里了。

        你可能会问:“那有什么区别呢?”。毕竟,第三方库的文件都在这里,就像我们复制粘贴它们一样。关键的区别在于它们包含在自己的Git repository中!如果我们只是下载一些文件,将它们扔到我们的项目中,然后提交它们——就像我们项目中的其他文件一样——它们将成为同一个Git repository的一部分。然而,submodule可以确保库文件不会“泄漏”到主项目的repository中。

        让我们看看还发生了什么:在主项目的根文件夹中创建了一个新的.gitmodules文件,下面是这个文件的内容:

[submodule "lib/spacetime"]
  path = lib/spacetime
  url = https://github.com/spencermountain/spacetime.git

        这个.gitmodules文件是Git用来跟踪项目中的submodule的几个配置之一,另一个是.git/config,它的结尾被添加了下面的配置:

[submodule "lib/spacetime"]
  url = https://github.com/spencermountain/spacetime.git
  active = true

        最后,Git还在内部的.git/modules文件夹中保存了每个子模块的.git仓库的副本。

        你不需要记住所有这些技术细节。可以看到,Git submodule的内部维护是相当复杂的,因此请记住:千万不要手工修改Git子模块的配置!如果你想移动、删除或以其他方式操作子模块,请不要手动尝试。要么使用适当的Git命令,要么使用像“Tower”[2]这样的Git桌面GUI,它们会处理这些细节。

        现在我们已经添加了子模块,让我们看看主项目的状态:

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
  new file:   .gitmodules
  new file:   lib/spacetime

        如您所见,Git将添加submodule视为与其他任何更改一样的更改。因此,我们必须像其他任何更改一样提交此次更改:

$ git commit -m "Add timezone converter library as a submodule"

克隆一个含有submodule的项目

        在上面的示例中,我们向现有的Git repository添加了一个新的submodule。但是,反过来,当我们需要克隆一个已经包含submodule的仓库时,又会怎么样呢?

        如果我们执行普通的git clone <remote-URL>,将会下载主项目,但任何submodule文件夹都是空的!这再次生动的证明了submodle文件是独立的,不包含在它们的父仓库中。

        在这种情况下,要在克隆了父仓库之后填充submodule,可以简单地执行git submodule update --init --recursive。不过更好的方法是在调用git clone时直接添加--recurse-submodules选项。

使用特定版本

        在普通的Git仓库中,我们通过使用git checkout <branchname>或者在Git 2.23引入的git switch <branchname>,告诉git当前活动的分支是什么。当在这个分支上进行新的提交时,HEAD指针会自动移动到最近的提交。理解这一点很重要——因为Git submodule的工作方式不太一样!

        在submodule中,我们总是签出一个特定的版本——而不是一个分支!即使在submodule中执行git checkout main这样的命令,在后台,也只会把该分支上当前最新的提交记录下来,而不会改变分支本身的内容。

        这并不是系统错误,而是有意设计的。考虑一下:当我们引用第三方库时,希望完全控制在主项目中使用的确切代码。当库的维护者发布一个新版本(这当然很好),我们不一定希望这个新版本立马被应用到项目中,因为我们还不知道这些新的更改是否会破坏我们的项目!

        如果想知道项目中的子模块使用的是什么版本,可以在主项目中查看以下信息:

$ git submodule status
   ea703a7d557efd90ccae894db96368d750be93b6 lib/spacetime (6.16.3)

        上面显示了lib/spacetime子模块当前签出的版本,它还告诉我们这个版本是基于一个名为“6.16.3”的tag。在Git中处理submodule时,经常会使用tag。

        要是我们希望submodule使用tag为“6.14.0”的旧版本。首先,我们必须更改目录,以便在子模块的上下文中执行Git命令。然后,我们可以基于tag执行git checkout:

$ cd lib/spacetime/
$ git checkout 6.14.0
Previous HEAD position was ea703a7 Merge pull request #301 from spencermountain/dev
HEAD is now at 7f78d50 Merge pull request #268 from spencermountain/dev

        如果我们回到主项目,再次执行git submodule status,我们会看到:

$ cd ../..
$ git submodule status
+7f78d50156ae1205aa50675ddede81a61a45fade lib/spacetime (6.14.0)

        仔细看一下输出:SHA-1哈希值前面的小+符号告诉我们,submodule的版本与当前存储在父仓库中的版本不同。由于我们刚刚更改了已签出的版本,因此这是正常的。

        在主项目中调用git status也会告诉我们这个事实:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
  modified:   lib/spacetime (new commits)

        可以看到,Git认为移动submodule的指针和其他变化一样:如果我们保存这个改动,就必须提交到仓库里:

$ git commit -m "Changed checked out revision in submodule"
$ git push

更新Git Submodule

        在上面的步骤中,是我们移动了submodule指针:我们选择签出一个不同的修订,提交它,并将它推送到团队的远程仓库中。但如果我们的一个同事更改了submodule的修订——可能是因为子模块发布了一个有趣的新版本,而我们决定在项目中使用它(当然是在彻底测试之后……)。

        我们在主项目中做一个简单的git pull——我们可能会经常这么做——从共享远程仓库中获得新的更改:

$ git pull
From https://github.com/gntr/git-crash-course
   d86f6e0..055333e  main       -> origin/main
Updating d86f6e0..055333e
Fast-forward
   lib/spacetime | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

        倒数第二行表示子模块中的某些内容已被更改,让我们仔细看看:

$ git submodule status
+7f78d50156ae1205aa50675ddede81a61a45fade lib/spacetime (6.14.0)

        我相信你还记得那个小+号:它表示submodule指针被移动了!要将本地签出的版本更新为我们的团队成员选择的“官方”版本,可以运行update命令:

$ git submodule update lib/spacetime 
Submodule path 'lib/spacetime': checked out '5e3d70a88180879ae0222b6929551c41c3e5309e'

        好了!我们签出了主项目仓库中记录的submodule版本!

删除Submodule

         这边记录一个亲测可行的方案,还有很多其他方案可以看下面这篇文章

git rm -r the_submodule
rm -rf .git/modules/the_submodule

如何删除子模块?_git 删除子模块_HuntsBot的博客-CSDN博客

在工作中使用Git Submodule

        我们已经介绍了使用Git submodule的基本概念,其他工作流程是相当标准的。

        例如,检查子模块中新的更改的工作方式与其他任何Git repository类似:在submodule repository中运行git fetch命令,如果你确实想要使用这些更新,可能会接着执行类似git pull origin main的命令。

        如果是自己管理的内部代码库,那也可能需要在子模块中进行更改。可以像处理任何其他Git仓库一样处理submodule:可以进行更改、提交更改、推送更改等等。

使用Git的全部功能

        在表面简单的命令下面,Git提供了很强大的功能。但是它的许多高级工具——比如Git submodule——并不为人所知。这么多开发人员错过了很多强大的东西,这真是太遗憾了!

        如果你想深入了解其他一些先进的Git技术,强烈推荐一个免费短视频合集:“Advanced Git Kit”[3],你可以学到Reflog、Interactive Rebase、Cherry-Picking,甚至分支策略等主题。

        祝你成为一个更好的开发者!

总结

参考文献

Git 修改.gitignore如何生效?_荷塘月色-CSDN博客_gitignore生效深入理解Git submodules - 简书 (jianshu.com)

如何删除子模块?_git 删除子模块_HuntsBot的博客-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值