git使用备忘

 

记录git常用的命令,以及使用规范。

基础

初始化

git init

git config --global user.name 'your name'
git config --global user.email 'your email'
# global表示该计算机的所有git仓库都是这个配置

git config -l
# 查看所有配置信息

修改管理

工作区$→$暂存区$→$版本库

  • 工作区的修改是针对暂存区的,如果暂存区为空,就是针对HEAD的。
  • 暂存区的修改是针对HEAD的。
# 工作区 -> 暂存区
git add -A  # 暂存所有更改,包括增加、修改、删除文件
git add <file>  # 暂存该文件的更改,包括添加、删除操作
# 暂存区 -> 版本库
git commit -m "提交信息"
git commit -amend  # 此次提交与上次提交合并,可以用于多次修改只是为了完成一件事的情况

git提交之后,对于文本文件会记录修改,而对于二进制文件则只是简单的保存整个文件,所以如果用git的话尽量只改动文本文件。

# 撤销修改
git restore <file>  # 把工作区撤销到暂存区的版本,暂存区为空就是HEAD的版本
git restore --staged <file>  # 把暂存区的版本放回到工作区

版本回退

git reset --hard 要回退的版本
  • HEAD表示当前版本
  • HEAD^表示前一个版本
  • HEAD~100表示前100个版本
git reset --hard 版本号

版本号可以利用git reflog查看

查看信息

git status

git log [--oneline] [--graph] [-p(--patch)] [-3]
# 当前版本以及以前的版本的信息
# --oneline显示简化版信息,只有一行
# -p查看每次的修改信息
# -3显示最近三次的信息

git reflog  # 查看命令历史(对版本库的操作)

分支管理

# 创建分支
git branch 分支名称

# 切换分支
git switch 分支名称

# 删除分支,注意分支删掉之后该分支的提交还是会存着的
git branch -d 分支名称  # 删除不了未合并过的分支,删除分支要在其它分支
git branch -D 分支名称  # 强行删除

# 合并分支,合并有两种模式,快速模式(fast-forward)、普通模式
git merge 分支名称  # 当前分支与指定分支合并,出现冲突需要修改文件直到不冲突
git merge --no-ff 分支名称  # 使用普通模式,合并会产生新的提交

# 切换到其它分支需要commit,如果不想commit可以暂存起来,然后切换到其它分支
git stash
git stash pop  # 回到分支后,pop出暂存的修改即可

rebase

git rebase命令有2个用途:一是把当前分支的源头改一改,也就是rebase本身的含义;二是合并几个commit,让提交历史整洁一点。

在把当前分支合并到main分支之前,由于main可能已经被更新了,为了避免冲突,需要先把main里的修改也合并到当前分支,使用:

git rebase main  # 在当前分支运行

如果有冲突,就手动改代码来解决冲突,然后把解决了冲突的文件用git add,之后git rebase —continue就可以rebase了。

有时候commit太多,可以合并提交:

git rebase 

然后会进入一个编辑页面,里面显示了一些commit,根据里面的提示决定如何处理里面的commit。

远程仓库

git remote  # 查看远程库有哪些
git remote show 远程库名字  # 查看远程仓库信息

# 关联远程仓库, 这个不需要联网, 只是进行了设置
git remote add 远程库名字 远程库链接
# 解除关联
git remote remove 远程库名字

# 推送
git push 远程库名字 本地分支:远程分支  # 第一次push要保证远程仓库是空的
git push 远程库名字 本地分支  # push到远程同名分支,没有就会创建

# 拉取并合并,等价于fetch + merge
git pull 远程库名字 远程分支:本地分支
git pull 远程库名字 远程分支  # 拉取到当前分支
git pull --rebase 远程库名字 远程分支  # 等价于fetch + rebase

# 关联远程同名分支
git branch -u 远程库名字/远程分支 分支名
# 关联后可以直接
git pull
git push

git clone  # 把仓库下载到本地并关联仓库

现在github好像不支持用密码远程连接了,需要到settings→Developer_settings→personal access tokens生成token来作为密码,生成token的时候需要勾选repo这个选项,不然没有读的权限。

标签管理

标签一般就是版本号,比如1.0,2.0这样的。

git tag 标签  # 给最新的分支打标签
git tag 标签 版本号  # 给特定版本打标签
# 添加参数-d就是删除标签

git tag  # 查看所有标签 

.gitignore文件

如果希望一些数据横跨不同分支,同步更新,可以用.gitignore文件忽略对它的管理,比如一些数据、编译产物之类的。.gitignore文件每行指定需要忽略的文件或文件夹:

file1.cpp
dir/
**/dir/  # 忽略所有名为dir的文件夹

该文件用于指出让git忽略的文件,不过这只对还未跟踪的文件有效。对于那些已经跟踪了的文件,后面又突然不想跟踪了,要让.gitignore生效,需要删除本地缓存,然后提交该文件:

git rm -r --cached .
git add -A
git commit -m 'update .gitignore'

.gitkeep文件

git会忽略掉空文件夹,如果希望git也管理这个文件夹,就需要在该文件夹内添加一些内容使之非空,一种约定俗成的做法是添加一个空的.gitkeep文件。

注意.gitkeep文件并不是git所需要的文件,不像.gitignore文件是git功能的一部分,只是一个起了个有意义的名字的普通文件,换成别的名字也完全没有问题。

Git使用规范

  • 添加功能都新开分支,最后merge进main分支。

    这也是多人协作写代码的方式,merge时应该经过团队的review。

  • 保证每个commit是可以通过编译的,没有明显的bug(正常来说可以运行)

  • 保证每个commit所做的事情足够清晰,比如调整接口就调整接口,添加功能就添加功能,不要放到一个commit里

    如果一个功能花了几天开发,每天有一次提交作为备份,可以用rebase把它们整合成1个commit。

  • 如果一个commit提交之后有一些小错误,比如注释忘了删,或者message打错了,用git commit —amend来commit到之前到commit而不是创建一个新的commit

依赖

子模块

git submodule add xxx

LFS插件

LFS(large file storage)是git的一个插件,用于管理大二进制文件。

其它

清除github上的提交历史

把一个分支和github同步的时候,github上也能看到提交历史,有时候我们不想发布这个历史,但是已经提交了,可以通过以下方式删掉:

# 切换到一个脱离主分支的另外一条全新主分支,不用太在意叫什么,因为后面还会修改分支名称
git checkout --orphan latest_branch  # --orphan是创建独立的分支,不是基于当前commit新开的分支
# 暂存所有改动过的文件,内容为当前旧分支的最新版本所有文件
git add -A
#提交更改
git commit -m "first commit"
#最后,强制更新您的存储库
git push -f origin latest_branch:main

核心就是创建独立的、没有提交历史的分支,把原来的给覆盖了。