Git场景

简介

  • 大神 Linus 除了 Linux 内核之外又产出了一个神作——Git分布式版本控制系统
  • 2008 年,专门提供 Git 存储的 GitHub 网站上线

基操

  • 大致流程是这样的
    1
  • 分为远程和本地的仓库
    • 本地 Repo 如上图中间存储库Repository,实际上都存在项目根目录下的.git文件夹中,内部可能有多个 branch,但至少有一个叫 master的branch
    • 完成add和commit两步操作才能将新增或修改的文件纳入本地Repo的存储库中进行版本管理。中间Index索引数据应该也是和本地 Repo一样存在项目根目录下.git目录中
    • 到这里Git与 CVS、SVN操作逻辑大致一致,只是实现了本地的版本控制。Git的特点是分布式
  • 本地 Repo 中的 branch 与一个或多个远程 Repo(上图中的Remote) 中的 branch 存在跟踪关系,这就构成了Git分布式版本控制的网状结构
    $ git --help	# Git命令用法及常用的Git命令列表
    
    • git在不同操作系统的安装就不介绍了,Mac使用brew
    • 安装VS Code时已经附带安装了Git(并没有),貌似当下这款工具比较流行,也推荐使用

本地版本库

  • Git 本地版本库的基本用法
  • 就基于vscode说明
    • VS Code的工作区概念与Git的工作区概念基本一致,打开文件夹Ctrl/⌘+O
    • 打开源代码管理Ctrl+Shift+G,可以点击初始化存储库,如果在远程有仓库,可以直接:
    git clone https://DOMAIN_NAME/YOUR_NAME/REPO_NAME.git
    # 然后再打开clone的文件,就有了.git
    
    • 不管使用何种方式初始化一个Git本地版本库,都是在项目根目录下创建.git文件夹
    • 现在安装的Git自带git bash和git cmd操作环境
  • 感觉命令行更简便,看习惯哪个吧
    2
  • 注意,如果在vscode中打开层级目录,上层初始化了git,下层clone了仓库(也初始化),进入文件夹时源代码管理不管用
    • 要保证打开的文件夹只有一份.git(直接打开当前工程)
    • ctrl+s了才会在这里出现:
      3
    • 跟踪文件(绿色U标记表示未跟踪文件),点击那个+即可,-可取消,这对应命令行的add
      # 添加到暂存区(Index)
      git add FILES # 指定文件或文件列表
      git add .     # 用“.”表示当前目录
      
      # 取消将特定文件(FILES)或者所有文件添加到暂存区
      git reset HEAD FILES # 指定文件或文件列表
      git reset HEAD
      
      # 放弃特定文件(FILES)或者所有文件的修改(检出,相当于撤回)
      git checkout -- FILES # 不要忘记“--” ,不写就把FILES当分支名了
      git checkout .	# 对应撤回那个箭头
      # 如果已经add 到 index,就不会被 checkout
      
  • 可以直接点击对号“√”(Ctrl+Enter)将暂存的文件提交到仓库中
    • 会强制让你输入comment,在Enter

      # 对应commit命令
      git commit -m "wrote a commit log infro"
      # 可以查看提交日志
      git log
      # 让HEAD回退到任意一个版本
      git reset --hard HEAD^	# HEAD的前一个版本
      git reset--hard HEAD^^	# HEAD的前两个版本
      git reset --hard HEAD~100	# HEAD的前100个版本
      git reset --hard 128个字符的commit-id	# 也可以用版本号字符串来指定任意一个版本
      git reset --hard 简写为commit-id的头几个字符
      # HEAD只是一个指向特定版本的指针
      

      4

    • 需要配置用户名和邮箱,可以在全局/局部或者项目文件中配置

      [user]
      	name = roy
      	email = szsplyr@163.com
      
    • 一旦提交到仓库,尽管也可以撤销上次提交,但是依然会在仓库里留下记录

    • git log 只能查看HEAD及其之前(时间更早)的提交记录,所以改了指向之后最新的记录查不到

      # 这其实就有个问题:可以通过git reset —hard回到过去,那怎么回到未来?
      git reflog	# 可以查看当前 HEAD 之后(时间更晚)的 提交记录
      # 从而可以通过git reset —hard回到未来
      

      5

  • 小结
    • 在本地开发,可以add暂存修改,或者checkout撤销修改
    • commit之后,可以reset,通过回退版本撤回

远程版本库

  • 如果未打开文件夹,vscode的源代码管理中会有两个选项,其中克隆存储库可以输入远程仓库地址,直接clone并初始化,并与远程仓库建立连接
  • 此时直接创建了本地版本库,操作和上面相同
  • 远程的场景:先以单人开发远程备份或者公开源代码为目的(循序渐进!)
  • git clone之后默认的分支
    • 远程为 origin/master
    • 本地为 master
      git remote	# 输出远程存储库名称
      git remote -v
      # origin  https://gitee.com/roykun/ArticleSpiders.git (fetch)
      # origin  https://gitee.com/roykun/ArticleSpiders.git (push)
      # git fetch、git push加上git clone是三个对远程存储库的基本操作
      
  • 不管是在本地仓库还是远程仓库,对代码修改之前都首先进行代码同步操作,防止产生分叉和冲突
    • vscode中这样操作,提交并拉取,同步的两大步骤!
      6
      7
    • 在这里的单人开发场景中,只会推送或只会拉取,不会同时(因为没别人)
    • 在命令行中,和远程交互,只需两句:
      git pull		# 实际上是 git fetch + git merge(合并)的组合
      # Fetch from and integrate with another repository or a local branch
      git push		# 将修改的代码推上去
      
  • 实际操作中难免会产生无法同步的情况,这时候需要在本地解决冲突
    • 一般是由于本地commit了修改,还没push,然后去pull了,本地领先于远程会冲突
    • 此时push一下就同步了(也不能叫冲突吧)
  • 单人项目工作时间线上是串行的,只要及时将本地与远程同步就不会出现分叉

多人开发

  • 实际项目往往多人团队,时间线常常是并行的,团队中的每个人都向远程版本库 push
  • 理解了 Git 背后的设计理念,才能比较准确地把握分叉合并的处理方法
    • git add 添加到暂存区里的每一个文件都会由 line diff 得到该文件的增量补丁(按行对比)
    • 所有文件的增量补丁合并起来存入仓库就是一个 commit,会生成一个SHA-1 Hash值作为 commit ID(40个十六进制数字,保证数据完整性)
    • 按时间线依次排列的一组提交记录形成一个 branch
    • 合并分支:
      8
    • 如图,项目在A版本处开始分叉,形成了两个分支,要合成新版本
      • 其实两条时间线最终版本是F和G,只需将F与A的差异部分、G和A的差异部分都放入工作区,解决冲突合并即可
  • 根据上图,为了轻松跟踪代码的成长轨迹,需要让一段连续的工作在commit日志的时间线上呈现为一段独立的分支线段,只在关键节点处进行分支合并,流程基本如下:
    • 克隆或同步最新的代码到本地存储库
    • 为自己的工作创建一个分支,该分支应该只负责单一功能模块或代码模块的版本控制
    • 在该分支上完成某单一功能模块或代码模块的开发工作
    • 最后,将该分支合并到主分支

分支

  • 创建分支,都是将当前分支分叉出一个分支,并签出(checkout)到工作区
    9
    # 命令创建分支
    git checkout -b royspace	# -b表示切换过去
    
  • 切换分支
    10
  • 合并分支
    • 假如要将 royspace 合并到master,那么首先确保当期工作区处于 master 分支,git pull一下
    • 合并royspace分支之前master分支别人更新过,合并过程会因为有冲突(都修改了同一位置)而失败
    • 这时royspace分支的代码已经合并到了当前工作区,只需在当前工作区里先解决冲突,然后提交到仓库即可(add&commit)
    • 对应命令:git merge mybranch
  • 快进式合并
    • 会合并到一条时间线中
      11
    • 但是希望royspace分支为一段独立的分支线段
      12
    • 实现很简单:git merge --no-ff mybranch,在vscode中没有对应的菜单选项,终端(ctrl+`)执行
  • 小结,遵循如下基本流程
    git clone https://DOMAIN_NAME/YOUR_NAME/REPO_NAME.git
    git pull	# 克隆或同步
    
    git checkout -b mybranch
    git branch
    
    git add FILES
    git commit -m "commit log"
    
    git checkout master
    git pull
    git merge --no-ff mybranch	# 可能需要解决冲突
    git push
    
    • 这样就会形成围绕master主线的时间线

rebase

  • 开发者的提交要尽量干净简单
    • 开发者要把自己的代码修改按照功能拆分成一个个相对独立的提交,一个提交对应一个功能点
    • 而且要在对应的 commit log message 里面描述清楚
  • 在上一个场景的基础上,增加一步Git Rebase
    • 即在 royspace 分支上完成自己的工作之后(本地),为了让 log 记录将来更容易回顾参考,用 git rebase重新整理一下提交记录
    • 不要通过rebase对任何已经提交到远程仓库中的commit进行修改
  • 命令格式
    git rebase -i  [startpoint]  [endpoint]
    # 一般只指定[startpoint], [endpoint]默认是当前分支的HEAD
    # 还是使用reset一样的参数指定 HEAD^ commit id
    
    # 重新整理HEAD之前的三个commit节点
    git rebase -i HEAD^^	# 包含当前commit
    # 此时会打开一个文件
    
    • 文件内容如下
    pick 76e9ec9 测试rebase1
    pick c93f5b8 测试rebase2
    
    # Rebase 0bb4ec6..c93f5b8 onto 0bb4ec6 (2 commands)
    #
    # Commands:
    # p, pick <commit> = use commit
    # r, reword <commit> = use commit, but edit the commit message
    # e, edit <commit> = use commit, but stop for amending
    # s, squash <commit> = use commit, but meld into previous commit
    # f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
    #                    commit's log message, unless -C is used, in which case
    #                    keep only this commit's message; -c is same as -C but
    #                    opens the editor
    # 这是个内置的小的vi编辑器
    
    • 修改commit
      • 删除某个版本
      • 修改提交日志消息
    • 退出后想撤销rebase
    git rebase --abort
    # 注释掉pick c93f5b8 测试rebase2
    
    13
    • --abort参数报错:fatal: No rebase in progress?,无法撤销删除的commit,why?
    • 同时,至少要HEAD^^,因为如果HEAD^,删除commit之后无法定位
    • 如果发生冲突,解决冲突后需要将修改后的文件存入暂存区(git add),再执行如下命令
    # 和pull远程代码产生的冲突不一样
    # 这的冲突是因为你分支的代码上存在相互依赖,rebase掉的那部分别的commit正好需要
    git rebase --continue
    
    • 一些其他场景可以使用git rebase --help查看官方文档,在本地!
  • 小结
    • rebase操作是为了让本地的log更清晰,对commit的修改操作

Fork / Pull request

  • 上面的场景是在一个企业或者团队中,有良好的信任关系和开发规范
  • 为了应对类似开源社区的鱼龙混杂的环境,需要Fork+ Pull request的协作开发工作流程
  • 当更正别人仓库里的Bug或者向别人仓库里贡献代码时
    • 先 fork(分叉) 别人的仓库,相当于拷贝一份;
    • 做一些 bug fix或其他的代码贡献;
    • 发起 Pull request 给原仓库;
    • 原仓库的所有者 review Pull request,如果没有问题的话,就会 merge Pull request 到原仓库中
  • 可以两人一组互相Fork对方的仓库,演练一下

声明

  • 内容转载自公众号,感谢作者
  • 以上场景是git基本用法,遇到特殊情况可能需要更深入了解
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
`git init` 命令用于在当前目录中初始化一个新的 Git 仓库。这个命令会创建一个名为 `.git` 的隐藏文件夹,其中包含 Git 所需要的全部文件和目录。通过 `git init` 命令,可以将一个普通的文件夹转换成一个 Git 仓库,从而使用 Git 管理文件夹中的文件。 `git init` 命令的应用场景主要有两种: 1. 新项目的开始:如果你正在开始一个全新的项目,你可以使用 `git init` 命令在本地创建一个新的 Git 仓库。在该仓库中,你可以使用 Git 来管理项目的版本控制和历史记录,包括代码的提交、分支管理、合并等等。这样可以让你更好地组织和协作开发代码,同时保留所有历史版本的备份。 2. 对已有项目的引入 Git 版本控制:如果你已经有一个项目,并且想要将它引入 Git 版本控制中,你可以使用 `git init` 命令来初始化一个新的 Git 仓库。在该仓库中,你可以使用 `git add` 命令将项目中的文件添加到暂存区中,然后使用 `git commit` 命令提交这些修改到 Git 仓库中。这样可以让你更好地管理项目的版本控制和历史记录,同时方便地与其他人协作开发。 需要注意的是,`git init` 命令只是在本地创建了一个新的 Git 仓库,如果你想要将该仓库与其他人共享或备份,你需要将它推送到远程 Git 仓库中。同时,Git 仓库中的文件和历史记录应该被定期地备份,以避免数据丢失。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Roy_Allen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值