MikhayEeer's note station
Share some notes during my study and work.
UCAS在读研究生
技术栈:
C/C++/Python/Golang/Linux/Git
对新技术和新事物充满研究激情,欢迎一起交流探讨!
博客有任何问题或建议,欢迎联系我!
by mikhayeeer
@[TOC]
最初是由linux开发者linus用两周时间用c语言编写而成。github就是使用git系统对网站进行管理,github只支持git分布式系统,故名为github。
svn和cvs也是版本控制系统,是集中式的,集中式的在每次写代码时都需要从服务器上拉取一份,如果服务器丢失,那么所有的都丢失,本机客户端仅仅保存当前版本信息。所有的回滚操作都需要服务器支持。 而git是分布式的,每个电脑都是服务器,可以自由在本地回滚。
私以为最高频的应该就是远程仓库和本地仓库的拉取与推送了
git add .
git commit -m "This is description"
git push origin master
git pull origin master
git status
git log
git 官网: https://git-scm.com
git help
Linux安装
sudo apt install git
windows Git - Downloading Package (git-scm.com)
查看git信息
git -V
git version
配置config,设置自己的用户名和邮箱,这些是每次提交的时候都会用到的信息
git config --global user.name "User Name"
git config --global user.email "UserEmail@Example.com"
# --global表示配置全局,整个git环境
# 查询git config的信息
git config --list
git config -l #两种都行
# 按 q 退出查看
取消配置
git config --global --unset user.name
配置git使用的代理(根据个人需求设置)
git config --global http.proxy "http://127.0.0.1:7890"
git config --global https.proxy "http://127.0.0.1:7890"
在git的过程中,主要分为两个大区
工作区和版本库,版本库又分为暂存区和分支
.git,该目录不属于工作区,是git的版本库,是git管理的所有内容;Git
|————————WorkSpace:工作区
|————————Index/Stage:暂存区/缓存区
|————————Repository:本地仓库/仓库区
|————————Remote:远程仓库
Index:缓存区,存在于.git中
一个仓库对应一个目录,该目录中的所有文件被git管理
git init
# 需要在空目录
执行git init操作的目录即为工作区,在操作之后,该目录下会有.git目录,是版本库
.git是git的配置文件目录,是隐藏文件夹,普通的ls命令无法查看
ls
# 用-lha参数来查看隐藏的目录
ls -lha
插播一句废话:
-lha是命令ls的三个可选参数,分别代表显示详细信息、以便于人类可读的方式显示大小、显示所有文件(包括隐藏)
#查看仓库状态
git status
# 能看到是否有改动,untracked未跟踪代表未提交
#暂存文件,将工作区文件存入暂存区/缓存区
git add .
git add --all # 添加所有,基本同git add . , 但是会记录删除操作
git add filname.txt # 添加某文件
#提交文件,将暂存区文件存入分支,形成一个版本
git commit -m "提交的描述信息"
# 删除文件
git rm filename
push和pull操作会放到下文远程仓库中
# 查看历史提交日志
git log
# log的日志格式
# commit <hash id> (HEAD -> master)
# Author : 提交者(user.name)
# Date : 提交时间
# myBase add new file "readme.md"
git log filename
# 查看某一文件的回滚版本
# 查看提交历史: 包括回滚操作
git reflog
git log --pretty=oneline #单行显示
git log --help
#会打开本地的log命令选项文档
#合并merge
git log --merge #仅展示合并的commit
git log --no-merge #不展示合并的commit
前面提到的仓库是本地仓库,当多人进行协同开发工作的时候,每个人都在自己的本地仓库维护版本,但是工作需要多人之间共享代码、合并代码,就需要用到远程仓库
程序员在本地仓库进行add操作将工作区文件存入暂存区,通过commit操作将暂存区文件存入分支,形成一个版本。
然后通过clone,push,pull操作与远程仓库进行交互
# 当前仓库名
git remote
#本地关联远程仓库
git remote add origin https://gitee.com/Username/case.git
#查看远程仓库地址
git remote -v
git remote show origin
# 使用prune参数刷新本地分支仓库
git remote prune origin
git remote rename <old name> <new name>
git remote remove <remote_name>
git push origin master
git clone https://gitee.com/username/case.git
git clone https://gitee.com/username/case.git .
# 有 . 在末尾,及克隆到当前目录,最好保证是一个空目录
git pull origin master
# 单一分支的时候可以省略后面的参数
git push
git pull
|命令|描述|
|–|–|
|git remote add <标识> 远程仓库地址|本地仓库关联远程仓库|
|git push <标识> master|将本地仓库上传到远程仓库的master分支|
|git pull <标识> master|从远程仓库master分支拉取到本地仓库|
|git clone 地址|将远程仓库复制到本地,并形成本地仓库|
git fetch
# 拉取远程全部分支,包括这些分支的仓库版本和日志记录
在进行PR操作前,需要与远程仓库的最新进展进行同步,就可以使用fetch。
该操作比较适用于本地仓库有多个远程仓库,通过remote查看。
例如fork一个主要仓库,在自己的仓库修改后,想要提交一个PR合入到主要仓库。
git remote add upstream <仓库地址>
git fetch upstream # 拉取upstream仓库的更新
git pull upstream master
git push origin feature
想要直接与Github仓库进行交互使用,可以通过SSH对github仓库进行访问和写入数据。 SSH连接需要使用密钥进行身份验证,也就需要在本地电脑上生成SSH密钥并把公钥添加到github账户中。 详细操作可以直接参考github的文档
ssh-keygen -t ed25519 -C "your_email@example.com"
测试与github的连接
ssh -T git@github.com
github相关内容不是本篇博客重点,点到为止。更多问题可以直接搜索关键字github ssh
分支,是一个个版本存储的最终位置; 一个分支相当于一条时间线,每一次commit都会形成一个版本,一个个版本依次存储在分支的一个个提交点上,分支上有个指针默认指向最新的提交点。
#查看分支
git branch
#查看所有分支
git branch -a # 包括远程
# 创建分支
git branch dev #创建名为dev的分支,只会创建,不会切换
git checkout -b dev #创建dev分支
git checkout -b previous upstream/previous
# 基于远程仓库upstream/previous创建previous分支
#切换分支
git checkout dev
#删除本地分支
git branch -D <branch_name>
#删除远程分支
git push origin --delete <remote_branch_name>
gitk –all
### 5.2.1 分支的细节原理
### 5.2.2 分支切换时,保存当前工作
如果修改了文件,是不可能直接切换到其他分支,是git为了防止丢失当前工作区的内容
使用命令`git stash`保存状态
```shell
# 保存当前工作状态
git stash
# 查看存储的工作状态
git stash list
# 在其他分支完成工作后,切换为刚刚的分支,可以恢复状态
git stash pop # 将list也删除了
git stash apply # 不删除list,默认恢复第一个
git stash apply list_name # 恢复指定的list
git stash drop list_name
git stash clear
# 查看新保存的stash和当前目录的差异
git stash show
该命令是解决git不提交代码不能切换分支的问题,有时候并不一定需要把代码push到远程
# 分支合并
git merge branchB
# 当前的分支是A,上面的命令是在A分支下合并分支B
# 强制合并分支
git merge branchB --allow-unrelated-histories
合并原理:
可能会造成冲突
当两个分支对同一个文件进行了修改,会出现冲突,冲突后,git会将冲突的内容都展示在文件中,用<<<< ==== >>>>来进行隔开
将A分支的某一修改,合并到当前的B分支
git checkout branch_A
git log
#查看需要合并的分支A的具体commit
git checkout branch_B
#切换到合并的分支
git cherry-pick <commit_hash_id>
# 合并具体的commit
git checkout main
# 模拟合并
git merge --no-commit dev
# 取消合并
git merge --abort
# 解决冲突,继续合并
git add .
git commit -m "merge"
vscode中进行冲突的管理 vscode在发现合并带来的冲突时候,会把更改分为两类,一种是合并更改,一种是暂存更改,暂存更改的意思是来自于合并的分支,但是没有造成冲突,而合并更改中,就是合并的分支和当前的分支产生了冲突,需要人为去管理
起因,错误删除了远程原仓库中的文件,并在本地修改后提交到了自己的仓库,随后发起了pull request,需要恢复这个删除的文件。 可以直接复制原本的内容,然后创建新的文件,但是也可以利用其他方法
git fetch # 拉取所有远程仓库为最新
git fetch upstream
git pull upstream main # 但是被删除的commit还是存在,不会直接恢复
git checkout <branch-name> -- <file-name>
git checkout upstream/main -- "Reports/season 3/successfulbarrier/[WeeklyReport]2024.07.15~2024.07.28.md"
git add .
git commit -m "Restore deleted files from remote repository"
git log
git reset –hard
git reset –soft
git reset –mixed
* 利用`HEAD`来回滚仓库版本
```bash
# HEAD 指向当前仓库,是头指针
git reset --hard HEAD^
# ^代表上一次提交的版本
git reset --hard HEAD~3
# ~3以当前版本为基数,回滚几次; ~1表示回滚1次,同^; 这个表示回滚3次
git reset
## 6.2 Github使用
[[Github]](这个博客还在写,准备写一些开发中常用到的功能)
### 常见问题
遇到拒绝访问
可能是token过期了,需要重新生成一个token,并且记得给token权限
默认的github端口是22,更换端口为443
```json
Host github.com
HostName ssh.github.com
Port 443
git submodule add address
git submodule init
git submodule update
适用于git 2.23之后版本,新增switch和restore
git switch dev
git switch -b dev # 合并
git switch -c dev # 创建
git restore filename # 撤销提交修改,会从缓存区删除
以linux下为例 ```shell sudo apt install git
git adduser git
su git
ssh-keygen -t rsa -C “email@example.com”
cd ~ cd .ssh
touch authorized_keys
## 6.6 忽略 .gitignore
忽略一些文件或者文件夹
在仓库中右键git bash here
```shell
touch .gitignore
编辑文件.gitignore
dir/ // 忽略dir文件夹
dir/*.txt //忽略dir目录下所有.txt文件
//并不会忽略 dir/dir2/a.txt这类文件
*.py //忽略所有.py文件
*.gz //忽略所有.gz结尾文件
!hhh.gz // hhh.gz文件除外
abc //忽略abc文件
/todo //忽略根目录的todo文件
**/__pycache__/
再次git status就发现忽略的文件,没了
git status --ignored
.gitignore对已经追踪的文件是无效的,所以需要线清除一下相关缓存状态
.gitignore 文件只是 ignore 没有被 staged(cached) 文件,对于已经被 staged 的文件,加入 ignore 文件时一定要先从 staged 移除。
git rm --cached <file>
git rm --cached .obsidian/workspace.json
git rm -r --cached .obsidian # 忽略文件夹
# 使用-r参数递归忽略整个文件夹
git add .
git commit -m "ignore workspace.json"
在.git/hooks/下添加文件pre-commit或者pre-commit.sh 如果是linux还需要赋予该文件执行权限。
然后在文件中写下脚本,用来判断一些文件的存储规则:
#!/bin/bash
CURRENT_DIR=$(pwd)
HOOK_DIR=$(dirname "$0")
cd "$HOOK_DIR/../../.." || exit 1
FILES_TO_COMMIT=$(git diff --cached --name-only --diff-filter=ACM)
INVALID_FILES=""
for FILE in $FILES_TO_COMMIT; do
if [[ "$FILE" =~ \.(png|jpg|jpeg|gif)$ ]]; then
if [[ ! "$FILE" =~ ^z_LinkSource(/|$) ]]; then
INVALID_FILES="$INVALID_FILES $FILE"
fi
fi
done
if [ -n "$INVALID_FILES" ]; then
echo "ERROR:Image files must be stored in the z_LinkSource/ directory or its subdirectories.\n The following files need to be moved to the correct directory before committing:"
echo "$INVALID_FILES"
exit 1
fi
echo "Pre-commit Checking Passed!"
exit 0