git学习

git版本控制,若干个版本构成一个history,git本质是对history的snapshot的记录

简单模型:线性模型、

1
2
3
graph TD;
G1-->G2;
G2-->G3

git参照的模型:DAG(有向无环图),允许某个snapshot有多个父亲

1
2
3
4
5
graph TD;
G1-->G2;
G2-->G3;
G2-->G4;
G3-->G4;

snapshot在git中定义为:一堆文件和目录的集合

文件就是blob(一堆字符),目录就是tree(其实是一个map),目录既可以包含tree也可以包含blob。

1
2
3
4
5
6
7
8
9
10
11
// 文件
type blob = array<byte>
// 目录
type tree = map<string,tree|map>
// 提交 commit
type commit = struct{
parents:array<commit>
author:string
message:string
snapshot:tree
}

上述伪代码表示了git的模型,这三种类型在git中统称为objects

1
2
3
4
5
6
7
type object = blob | tree | commit
objects = map<string, object>
def store(object):
id = sha1(object)
objects[id] = object
def load(id):
return objects[id]

objects本质是使用了sha1的哈希,

SHA-1对人并不友好,所以定义了references(main、master等)作为指向SHA-1的指针。

1
2
3
4
5
references = map<string, string> //前者是master··· 后者是SHA1值
def update_reference(name,id):
references[name] = id
def read_reference(name):
return reference[name]

Staging Area是一个git的优化

生成新的snapshot时使用此区域,放着在commit时记录到snapshot里的东西,这一部分需要手动增加。

command

Basic

  • git hlep

  • git init: 新开始一个项目,建立仓库

  • git status:查看这个仓库的状态

  • git add \: 如果不执行,增加或更改的文件会显示为Untracked files后跟红色文件名

  • git commit: 如果不执行,新add的文件会显示Changes to be committed 后跟绿色文件名,然后git commit -m “XX”后就添加进去了 这里本质是创建了一个新的snapshot,生成新的历史

    • git commit -m “info” 将stage(暂存区)中的内容提交到本地仓库 加上提交信息,比如一些描述
    • git commit -m “info” -s 提交信息中自动附带个人签名和邮箱
    • git commit -am “info” 将正在追踪的文件(tracked file)提交到stage(暂存区),然后进行提交到本地仓库。 相当于git add . && git commit -m “info”
    • git commit —amend 修改最近一次commit的message。
  • git log

    image-20211118202838319

  • git checkout [commit_id] 回滚 id根据git log 看到

  • git diff \<文件名> 使用在add前,可以看到做了哪些修改

git提交的基本格式(以Linux为例)

第一行:git提供命令生成的邮件名

第二行:描述explain 每行有限量

第三行:个人签名 signed-off-by 真实姓名 邮箱 默认加”-s”就行。

分支

在调试bug时加上一些log之类的。

  • git checkout -b [新的分支命令]
  • git branch 查看当前所在分支
  • 合并
    • git merge \
    • git rebase branch1 branch2 将branch2的整条分支整理到branch1的末尾
    • git rebase —onto branch1 branch2 branch3 把branch2分出来的branch3挪到branch1上,相当于branch3不再和branch2有关而是和branch1相关
    • git rebase —onto branch~M branch~N branch 将branch上的N~M个commit删除掉

修改

  • git commit —amend 修改最近一次commit的message。 不改变其他属性
  • git reset HEAD \ 将误add的文件从stage中除去
  • git checkout — \ 将文件回滚到branch的初始状态。

高级主题

  • git blame : 找到bug到底是是谁写的。
  • git stash push/pop/list :将当前正在做的东西放到一个临时的地方、或者取回、或者看都有哪些再放
  • .gitignore : 将一些生成的中间文件不用放到仓库里
    • Object files
      • *.o
      • *.a
      • *.dep
    • Build & install directories
      • build/
      • installs/
    • Development friendly files
      • tags

常用主题

  • git config 高级自定义

  • git clone —depth=1 最近版本,浅克隆,不含完整的版本历史信息

  • git add -p 交互式暂存

  • git rebase -i 交互式rebase

  • git stash 临时删除对工作目录的修改

  • git bisect 二分查找历史