Git 基础学习总结

Git 基础学习总结

0 | 什么是版本控制

版本控制系统(Version Control System, VCS) 类似于代码的历史记录面板,当然功能更加丰富,它可以给多个人同时使用,添加修改,撤销修改等等…

1 | VCS 简史

1972年,贝尔实验室在开发祖宗级操作系统Unix时,最早的版本控制系统SCCS诞生了

1982年,Revison Control System 诞生了,虽然支持跨平台,但其与前者相同,只适用于文本文件

1986年集中式版本控制系统(Centralized Version Control Systems, CVCS)开始研发,其采用一个中央服务器作为仓库载体,存储代码,追踪文件修改,但还没有追踪整个文件目录

80年代后期,Perforce已经广泛应用于各大网站了(直到现在仍有一些大公司在使用,如育碧,英伟达等)

2000年,Subversion出现了,不仅支持非文本文件,还支持追踪整个文件夹内的变化

2004年,微软开发了 Team Foundation Server (TFS),功能上更加全面丰富,利于协同开发,且收到了其他企业的订单

--------------------------------------------------------------

林纳斯·托瓦兹(Linus Torvalds) 与他的团队开发Linux系统的内核时,当时他们使用的VCS是免费版的BitKeeper,然而有一天 BitKeeper 不再免费服务,林纳斯决定创造一个免费的VCS

2005年4月7号,分布式版本控制系统 Git(的第一个提交)诞生了

commit e83c5163316f89bfbde7d9ab23ca2e25604af29 
Author: Linus Torvalds < torvalds@ ppc970. osdl. org> 
Date: Thu Apr 7 15: 13: 13 2005 –0700 
Initial revision of "git", the information manager from hell

2 | 工作原理

集中式 VCS

通过同一个集中管理的中央服务器保存所有文件的修订,开发人员通过客户端连到这台服务器,更新文件或提交更新,如前文所说的 CVS、Subversion、Perforce,这种工作原理有一个致命问题:如果中央服务器(Central VCS Server)不工作了,那所有人就都不用工作了…

在这里插入图片描述

在这里插入图片描述

分布式 VCS

开发者不只提取最新版本的文件快照,并完整地镜像代码仓库到本地,如前文所述的 Git、Mercurial 以及 Bazaar、Darcs 等,即使文件无修改,也会快照文件,这种工作机制不仅避免了中央服务器带来的尴尬问题,而且能保证仓库在每个人本地有完整的备份,与前者相比,分布式 VCS 具有很大的优越性

在这里插入图片描述
在这里插入图片描述

3 | 安装

安装过程比较简单,除了在官网下载安装程序,Windows 也可通过 Chocolatey 安装

https://git-scm.com/downloads

$ choco install git

Linux 系统的安装指令

$ sudo apt-get install git

安装完成后,可直接在命令行输入 git 或者 git --version 确认是否安装成功

λ git --version
git version 2.21.0.windows.1

4 | Git 指令

输入 git help 可以获取帮助

$ git help <command>
$ git <command> --help

输入 git help --all 可显示所有子命令
在这里插入图片描述

git 子命令的选项有长短两种形式,长选项是 Linux 风格

$ git commit -m "Fixed a typo." 
$ git commit --message=" Fixed a typo."

有时需要 双破折号– 分离参数,

比如分离指令的控制部分与操作数部分, 如标识文件名或区别文件名与tag

$ git diff -w master origin -- tools/ Makefile

# Checkout the tag named "main. c" 
$ git checkout main. c 
# Checkout the file named "main. c" 
$ git checkout -- main. c

5 | 基本概念

在这里插入图片描述

版本库 Repository

一个 Git 版本库(仓库)对应一个文件夹(工作目录),仓库的重要信息存储于工作目录下的 .git 文件夹里,类似一个简单的数据库,其包含所有用于维护与管理项目的修订版本和历史的信息,主要维护两件东西:对象库、索引

对象库 Object Store

----- 对象库是版本库的核心,其包括 4 种对象,每个对象都有一个唯一的SHA1散列值,散列值由内容决定,与操作系统,路径等均无关

  • 块 Blob:Binary Large Object,大意为二进制大对象,保存一个文件的主要数据
  • 目录树 Tree:即目录信息,记录Blob,路径名以及文件元数据,如文件名
  • 提交 commit:记录着一次提交的详细信息,每个提交指向一个目录树
  • 标签 tag:分配给一个对象自定义的名称,通常是提交对象.

索引 Index

----- 一个临时的、动态的二进制文件,捕获项目在某一时刻的整体目录结构的版本,记录当前有哪些修改

6 | 特点与状态

在这里插入图片描述

重要特点

  • 直接记录快照,而非差异比较:每次提交或在 git 中保存项目状态时,git对当时的全部文件制作快照并保存该快照的索引。没有修改的文件,则不再重新存储该文件,只保留一个链接指向其之前存储的文件。 git 对待数据更像是一个快照流
  • 保证数据完整性:git 存储数据前以 SHA-1 散列计算校验和,使用前再校验,因此不可能在 Git 不知情时更改任何文件内容或目录内容
  • 一般只添加数据:很难执行不可逆操作,或者以任何方式清除数据
  • 近乎所有操作都是访问本地文件不需要网络
  • 原子操作:要么执行所有修改要么放弃所有修改

状态

仓库中的文件通常处于 3 种状态下:

  1. 已追踪 Tracked ----已在版本库中的文件,或是已暂存到索引中的文件
  2. 已忽略 Ignored ----版本库中存在但不需要追踪的文件
  3. 未追踪 Untracked ----不属于以上两者的文件

而文件的修改状态有以下 3 种:

  1. 已修改 modified ----- 在工作目录中修改文件
  2. 已暂存 staged ----- 暂存文件,将已修改的文件的快照放入暂存区域
  3. 已提交 committed ----- 找到暂存区域的文件,将快照永久性存储到 Git 仓库目录

7 | 初次运行 Git 前的配置

在这里插入图片描述
配置级别

Git 的配置级别分为 3 种:

Local 针对当前仓库的配置 project/.git/ config

global 针对当前用户的配置 ~/.gitconfig

System 针对所有用户及其仓库通用的配置 /etc/ gitconfig

如果出现相同配置项如 user.email 则优先使用 Local 的其次是 global 最后 system

查看所有配置

$ git config --list
core.symlinks=false
core.autocrlf=true
core.fscache=true
color.diff=auto
color.status=auto

常用配置项

  • 配置提交人的名字与邮箱
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
  • 配置默认编辑器
$ git config --global core.editor emacs
  • 配置提交模板
$ git config --local commit.template <template-name.txt>
  • 配置忽略文件
$ git config --global core.excludesfile .gitignore_global
  • 设置颜色输出 true/false/always
$ git config --global color.ui false
# 或者指定某指令的输出的颜色样式
$ git config --global color.diff.meta "blue black bold"

8 | 创建仓库

在这里插入图片描述

方法一:克隆

通常情况下,仓库已经建好,我们需要从 gitlab 或者 github 上将仓库下载到本地

$ git clone <url> <custom_repository_name>

默认创建的文件夹名称为仓库名,如需自定可以替换 <custom_repository_name>

⚠️ 这个目录下不能有与仓库同名的文件夹,如果有需要保证文件夹内是空的,否则报错
在这里插入图片描述

方法二:初始化+添加

如果是首次创建仓库,则需要先在 github 或 gitlab 上创建一个仓库,创捷完成后,会生成一个地址,在本地找个空目录,

$ git init
# 创建文件,或把项目需要的文件挪进来
$ ...
# 添加文件
$ git add * 
# 输入提交信息并提交
$ git commit -m "Initialize a project !!"
# 设置远端地址,让 Git 知道仓库在 github 上的地址
$ git remote add origin git@github.com:<username>/test.git
# 推送,由于是初次提交,所以需要用到 -u 参数
$ git push -u origin master

9 | 提交更新

如前文所述,git 的文件状态会在三种状态间不断转换:
在这里插入图片描述
检查当前文件状态 git status

$ git status
# 显示简洁版
$ git status -s 
$ git status --short 
M apps/api/forms.py
M apps/api/views.py
# 额外显示分支
$ git status -sb

查看未暂存的文件变更 git diff

$ git diff
# 查看合并引入的内容
$ git diff --ours
# 查看合并的结果与他们那边有什么不同
$ git diff --theirs
# 查看文件在两边是如何改动
$ git diff --base     

加入暂存区 git add

$ git add <file-1>  <file-2>   
----------------------------
-i, --interactive    交互式处理文件,避免输入文件名
-u, --update         将 modified 的文件加到暂存区
-p, --patch          加patch

提交 git commit

$ git commit -m <message>

Note: 提交信息应少于 50 个字符(25个汉字)

提交的时候,若需要忽略某些文件,如.pyc,local_settings.py等,可以设定.gitnore文件

.gitignore 语法:

  • 所有空行或者以 # 开头的行都会被 Git 忽略
  • 可以使用标准的 glob 模式匹配
  • 匹配模式可以以(/)开头防止递归
  • 匹配模式可以以(/)结尾指定目录
  • 要忽略指定模式以外的文件或目录,可以在模式前加上 !取反

删除文件 git rm

删除某个 Tracked文件 不追踪 + 删除文件

$ git rm <filename>

删除某个既是 staged 也是 modified 的文件只能 --force

$ git rm -f <filename>

不追踪 + 保留文件 Tracked —> Untracked

$ git rm --cached <filename>

重命名/移动 git mv

$ git mv old.txt  new.text

实际上,git 执行了下列三项指令

$ mv old.txt new.text
$ git rm old.txt
$ git add new.text

暂存文件 git stash

$ git stash
$ git stash save
-------------------------
--patch            加 patch
--keep-index  不 stash 已暂存的文件
--include-untracked    包含未追踪的文件

查看暂存区

$ git stash list

恢复暂存的修改

$ git stash apply  <stash@{n}>
$ git stash pop  <stash@{n}>
# --index 恢复当前的上一个

移除指定暂存

$ git stash drop  <stash@{n}>

直接将暂存移入新分支

$ git stash branch <branch-name> [<stash>]

清理文件 git clean

$ git clean
--------------------
-f       直接删除未追踪的文件
-f -d    直接删除未追踪的文件和目录
-n       列出执行git clean将会被删除的文件
-i       交互式删除

⚠️注意:clean 不会删除 .gitignore排除的文件,删除排除文件加上 -x

$ git clean -f -d -x

10 | 撤销

在这里插入图片描述
修改最近一次提交的备注

$ git commit --amend

⚠️ 如果提交已经push到仓库,修改备注之后,需要执行git push -f,普通 push 会失败
在这里插入图片描述

$ git push -f

修改多个提交的备注 可用git rebase 解决

撤销修改/回退版本

# 将某个文件回退到最新版本
$ git checkout HEAD <filename>
# 回到到指定版本
$ git checkout <commit> <filename>
# 整个仓库回退到指定 commit
$ git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]
  • -- hard 选项是“硬”回退,回退不保留当前的任何修改
  • -- soft 选项时“软”回退,回退并保留修改(即索引和工作目录的内容不变)
    在这里插入图片描述

三种选项对项目的影响,mixed会重置索引

git resetHEAD 指针指向指定的提交后,原始指针另存为 ORIG_HEAD
在这里插入图片描述

11 | 查看历史

在这里插入图片描述

通常情况下 git log 即可,当然也有一些实用的选项

$ git log -g          查看message与reflog
$ git log -p          查看各个差异
$ git log -p -2      指定显示数量
$ git log --stat     查看简略增删行统计
$ git log --graph    展示分支合并示意图与对应提交详情

显示的格式可以通过 –pretty 参数自定义

$ git log --pretty=oneline|short|full|fuller
# 或者自定义样式
$ git log --pretty=format:"%h %s"
$ git log --oneline
# 相当于git log --pretty=oneline

在这里插入图片描述
按日期或作者筛选 log

写工作日志或月总结,忘了上周自己做了哪些项目,此时用这项指令很有用

$ git log --since=2019-06-01 --until=2019-06-30 --author=<author>

快速查看昨天 develop 分支上的提交

$ git show develop@{yesterday}

列出所有提交者的提交统计

可以看到每一个提交者分别有多少次提交,以及每次提交的提交信息

$ git shortlog

在这里插入图片描述
⚡查看引用日志

其记录了最近几个月 HEAD 和分支引用所指向的历史

$ git reflog

在这里插入图片描述

12 | 远程仓库

在这里插入图片描述
查看

$ git remote

# 查看并展示地址
$ git remote -v
origin  https://github.com/Jax/A.git (fetch)
origin  https://github.com/Jax/A.git (push)

# 查看更多信息
$ git remote show <remote-name>

增删

# 增加
$ git remote add <remote-name> <url>

# 删除
$ git remote rm <remote-name>

# 删除某个本地分支对应的远端
$ git branch -r -d <remote-name>/<branch>

# 删除本地版本库中陈旧远程追踪分支
$ git remote prune

# 重命名
$ git remote rename <old_name> <new_name>

# 直接修改某个远端的地址
$ git remote set-url origin git://repos.example.com/stuff.git

推拉

# 推送代码
$ git push <remote> <local-branch>:<remote-branch>
# 抓取后自动合并远程分支到当前分支
$ git pull
# 拉取某个远端代码
$ git fetch <remote-name>

git fetch 命令会将数据拉取到你的本地仓库, 它并不会自动合并或修改你当前的工作

它与 git pull 的关系可大概理解为 git pull = git fetch + git merge

执行 git fetch之前(左侧本地/右侧远端)
在这里插入图片描述
执行 git fetch 之后:
在这里插入图片描述

13 | 分支

分支的本质是指向提交对象的可变指针, 是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件,分支还可以分为两种,长期分支如 master,功能(特性)分支如 feature, hotfix

Note: 个人建议将分支理解为指针,这样有助于理解学习git

查看

$ git branch
# --merged  查看已合并
# --no-merged 查看未合并

# 查看每一个分支的最后一次提交
$ git branch -v

HEAD 指向当前所在的本地分支,ORIG_HEAD 指向原始HEAD

切换与增删

# 创建分支,加上提交码可指定提交
$ git branch <branch-name> <commit>

# 创建并切换
$ git checkout -b <name>

# 手动切换分支
$ git checkout <branch-name>

# 删除分支
$ git branch -d <branch-name>

# 删除某个远端分支(本地还保留)
$ git push -d <branch-name>

14 | 变基

-----------直接挪动指针的神器之一

常见用途是保持你正在开发的分支相对于主分支是最新的

我从主分支 master 上新建一个功能分支 feature-upload,开发当前迭代的新功能,

某位同事修复了一个重大bug并提交到了 master 分支上,此时可用变基获取这些修改

一如既往,获取修改时可能遇到需手动处理的冲突 ~~~

# 将feature-upload分支开出来时所在的“基”挪到 master 指针所在的位置
$ git rebase master

# 也可通过第二参数指定被挪的分支
$ git rebase <to-branch> <base-branch>

# 没有特殊需要的情况下,下列指令也可以达到相同目的
$ git pull --rebase

描述变基前后对比

交互式变基

$ git rebase -i HEAD~4

用途:一次修改多个提交的message | 重新排序commits | 删除某个不要的commit

举例:领导要求从提交历史(下图)中去掉提交C2,并将C4,C5 的先后顺序对调
在这里插入图片描述

$ git rebase -i master~4
# 4 指的是包括 master 指针在内的前四个提交
# 接下来会触发 git 默认编辑器,我们将 C2 前面的关键字 pick 换为 omit

我编辑器是VIM 提交码(肯定是散列值)我替换成C2 C3 C4 C5便于解说
改好之后保存退出编辑器,Job done ~
在这里插入图片描述
提示:

  • 如果需要压缩多个提交为一个,可以在编辑器里将需要被压缩的 commit 前加上s(squash) 标记 s 的会被压入上一个提交
  • 如果是修改多个提交的 Message,只修改四个中某个提交的message,只要将你想修改的提交前面的 pick 改为 edit

两个比较实用参数:–onto | --preserve-merges

# 将分支 feature 上有但 maint 上没有的提交挪到 master 上
$ git rebase --onto master maint feature

# 保留被变基的整个分支的分支与合并结构,使用-- preserve-merges
$ git rebase --preserve-merges master dev

中断或恢复

# 直接放弃变基并恢复原始状态
$ git rebase --abort
# 直接放弃但保留HEAD指针的位置
$ git rebase --quit
# 继续变基流程
$ git rebase --continue

15 | 合并

在这里插入图片描述

当前的提交历史

往当前分支合入需要的分支

$ git merge <branch>

在这里插入图片描述
在 master 分支上合并了分支 one

用变基+合并也可以,提交历史会更加“完美”:

$ git rebase master one
$ git checkout master
$ git merge one

在这里插入图片描述
合并分支one后,指针会 fast-forward 到 one 指针所在的11931提交

  • fast-forward

合并时出现该词,说明主分支是被合并分支的直接祖先,所以指针只是向后快速移动了

合并时出现冲突,可以通过 git status 查看冲突文件并解决

继续 & 终止

$ git merge --abort
$ git merge --continue

忽略合并时由任意数量空白引起的冲突

$ git merge -Xignore-space-change <branch-name> 
但保留HEAD指针的位置
$ git rebase --quit
# 继续变基流程
$ git rebase --continue

END

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值