Skip to content

Git

Git 是一个开源的分布式版本控制系统,它采用了分布式版本库的方式,不必服务器端软件支持。

Linux Benedic Torvlds 为了帮助管理 Linux 内核开发而开发。

安装

edition

  • Git: standard edition of Git
  • MinGit: MinGit is Git for Windows Applications
  • porableGit: PorableGit is Git for Windows Applications

官网

https://git-scm.com/

ali镜像

https://registry.npmmirror.com/binary.html?path=git-for-windows

sh
# 生成公钥
$ ssh-keygen -t rsa

# 配置文件 ~/.gitconfig
$ git config list
$ git config --global user.name <name>
$ git config --global user.email <email>

简述

Objects

Git 的对象库,位于项目.git/objects 下,里面包含了创建各种对象及内容。

Working Directory 工作区

本机上的项目目录这里创建、编辑、删除文档。

当对工作区修改(或新增)的文件执行git add命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。

当执行git rm --cached <file>命令时,会直接从暂存区删除文件,工作区则不做出改变。

当执行git checkout .或者git checkout -- <file>命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区中的改动。

Staging Area 暂存区

本机上项目的临时存储区域,包含了即将被提交到版本库中的文件快照。

当执行提交操作git commit时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

Repository 版本库

每次提交会在版本库中创建一个新的快照,这些快照不可变,确保项目的完整历史。

当执行 git reset HEAD 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。

当执行 git checkout HEAD . 或者 git checkout HEAD <file> 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

仓库

Git 工具依赖于 sshd 服务,安装 git 以及 sshd 两款软件即可搭建成 Git 仓库。

sh
$ apt install ssh
$ systemctl status ssh
$ systemctl enable ssh
$ systemctl start ssh
$ apt install git

公钥访问

sh
$ ssh-keygen -t rsa
$ cat ~/.ssh/id_rsa.pub | ssh <user>@<ip>:.ssh "cat >> ~/.ssh/authorized_keys"
# 注意 .ssh 需要权限 700
# 注意 authorized_keys 需要权限 600

中心仓库

没有工作目录仅包含.git 内容,作为共享中心仓库使用。

特性中心仓库本地仓库
工作目录
用途共享/服务器本地开发
直接修改文件不可可以
典型位置服务器开发者本地
命名惯例以 .git 结尾任意名称
sh
$ git init --bare <repo.git>
$ ls -l
drwxr-xr-x 2 git git 4096 Jul 15 15:21 branches
-rw-r--r-- 1 git git   66 Jul 15 15:21 config
-rw-r--r-- 1 git git   73 Jul 15 15:21 description
-rw-r--r-- 1 git git   21 Jul 15 15:21 HEAD
drwxr-xr-x 2 git git 4096 Jul 15 15:21 hooks
drwxr-xr-x 2 git git 4096 Jul 15 15:21 info
drwxr-xr-x 7 git git 4096 Jul 15 15:25 objects
drwxr-xr-x 4 git git 4096 Jul 15 15:21 refs

本地仓库

sh
$ git init <repo>

手册

查询

sh
# 远端仓库信息
$ git remote -v 

# 本地分支信息
$ git branch 

# 远端分支信息
$ git branch -r

# 本地分支信息详情
$ git branch -v

# 工作区及暂存区信息
$ git status

# 本地及远端记录
$ git log

# 远端历史记录
$ git log --oneline

# 每个记录变更的文件情况
$ git log --stat

分支管理

sh
# 创建本地分支
$ git branch <new_local_branch>

# 删除本地分支
$ git branch -d <local_branch>

# 删除远程分支
$ git branch -dr <branch>

# 建立跟踪关系
$ git branch --set-upstream-to=<branch>

# 取消跟踪关系
$ git branch --unset-upstream

# 切换分支
$ git checkout <local_branch>

# 创建并切换到新分支
$ git checkout -b <new_local_branch>

# 克隆远程并创建并切换到新分支
$ git checkout -b <new_local_branch> <branch>

# Git v2.23+ 
# 切换分支
$ git switch <local_branch>
# 创建新分支并切换
$ git switch -c <new_local_branch>

添加仓库

sh
$ git remote add <remote> <url>

获取远端分支记录

sh
$ git fetch <remote> <branch>

合并到暂存区

sh
# 当前分支本地提交与远端指定分支最新提交进行合并生成新的提交记录
$ git merge <branch>

# --no-ff 强制创建合并提交记录
$ git merge --no-ff <branch>

# --squash 将多个提交合并成一个
$ git merge --squash <branch>

# 冲突处理!冲突文件会包含(文件中会有 `<<<<<<<`, `=======`, `>>>>>>>` 标记)
# 手动处理后添加到暂存区

# 撤销当前合并
$ git merge --abort

# 合并方式
# merge: 将两个分支的最新提交和它们的共同祖先进行三方合并,创建一个新的“合并提交”来记录这次合并。
# rebase: 将当前分支的提交“重放”到目标分支的最新提交之上。实际上事创建了一系列新的提交。
$ git merge <branch>
$ git rebase <branch>

创建提交

sh
# 指定文件
$ git add <file>

# 所有
$ git add .

# 询问模式
$ git add -p .

# 提交暂存区记录
$ git commit -m 'msg'

提交记录推送到远端分支

sh
$ git push -u <remote> <branch>

工作区回退

sh
$ git checkout -- <file>

# Git v2.23+ 
# 撤销工作区文件修改
$ git restore <file>
# 撤销暂存区文件
$ git restore --staged <file>
# 工作区文件回退指定版本
$ git restore --source=<commit> <file>

暂存区回退

sh
# 从暂存区、工作区中删除
$ git rm <file>

# 从暂存区中删除,保留工作区
$ git rm --ceched <file>


# 工作区文件回退指定版本
$ git checkout <commit> -- <file>

# 撤销最后一次提交,更改保留再暂存区。
$ git reset --soft HEAD~1

# 回退3个提交,丢弃所有更改。
$ git reset --hard HEAD~3

# 强制与远程分支同步
$ git reset --hard <remote> <branch>

# 将暂存区文件移除
$ git reset --mixed HEAD~1 # 等同 git reset HEAD~1
# 移除指定文件
$ git reset <file>

远端回退

sh
# 1.不影响历史记录
$ git log --oneline
# 指定回退历史 hash 
$ git revert <commit>
$ git push

# 2.影响历史记录
# 回退暂存区再强行提交覆盖
$ git log --oneline

# --soft 保留工作目录和暂存区的修改(仅撤销 commit)
# --mixed(默认) 保留工作目录修改,但撤销 commit 和暂存区
# --hard(危险!) 彻底丢弃所有更改,回退到指定 commit
$ git reset --hard <commit>
$ git push --force

ERR

fatal: unable to access 'https://xxx.git'; error setting certificate verify locations:

CAfile: xx

CApath: none

git config --system http.sslverify false

Ref

https://www.runoob.com/git/git-workspace-index-repo.html

https://gitee.com/all-about-git