一键排版 HTML 代码行数 代码紧凑
已保存!
退出 生成文件
abcd
red
#FFEBEE#FFCDD2#EF9A9A#E57373#EF5350#F44336#E53935#D32F2F#C62828#B71C1C#FF8A80#FF5252#FF1744#D50000
---
title: git常用命令
author: wuzhiyong
top: false
cover: false
toc: true
mathjax: false
date: 2022-03-24 17:17:54
img:
coverImg:
password:
summary:
tags:
categories: [git]
---

### config
|命令|说明|
|---|---|
|`git init`|初始化
|`git config -l`|查看当前config配置
|`git config --global user.name "username"`|设置用户名
|`git config --global user.email "email@gmail.com"`|设置邮箱

### 远程仓库
|命令|说明|
|---|---|
|`git clone [url]`|检出仓库
|`git remote -v`|查看远程仓库
|`git remote add [name] [url]`|添加远程仓库
|`git remote rm [name]`|删除远程仓库
|`git remote set-url origin [newUrl]`|修改远程仓库
|`git push -u -f origin`|仓库迁移
|`git push -u -f origin --all`|把所有分支迁移过去
|`git push -u -f origin --tags`|把所有tag迁移过去
|`git fetch`|下载远程仓库最新的commit到本地
|`git fetch --all`|下载远程仓库最新的commit到本地
|`git fetch origin --prune`|更新远程分支,`--prune`同`-p`
|`git remote update origin --prune`|更新远程分支

### 分支
|命令|说明|
|---|---|
|`git branch`|查看本地分支
|`git branch -r`|查看远程分支
|`git ls-remote --heads origin`|查看远程分支
|`git branch -a`|查看所有分支
|`git branch [name]`|创建本地分支,创建后不会自动切换
|`git checkout [name]`|切换分支
|`git checkout -b [name]`|创建分支并切换
|`git checkout [name] -f`|`--force`或者`-f`,强制切换分支,未提交的会被丢弃
|`git branch -d [name]`|删除分支,如果分支没有合并是不能被删除的
|`git branch -D [name]`|删除分支,没有合并也能被强制删除
|`git push origin [name]`|本地分支push到远程,远程没有该分支则自动创建
|`git push origin [local]:[name]`|本地分支push到远程
|`git push origin --delete [name]`|删除远程分支,`-d`也行
|`git push origin :heads/[name]`|删除远程分支
|`git push origin :[name]`|删除远程分支

### 合并
|命令|说明|
|---|---|
|`git merge [name]`|将名称为[name]的分支与当前分支合并
|`git merge --no-ff [name]`|将名称为[name]的分支与当前分支合并,并保存之前的分支历史
|`git merge --abort`|合并产生冲突后,抛弃合并过程并且尝试重建合并前的状态
|`git rebase [name]`|将`name`分支合并到当前分支
|`git rebase [name1] [name2]`|将`name1`分支合并到`name2`分支,等同于先`git checkout name2`在执行`git rebase name1`
|`git rebase [start] [end] --onto [name]`|从开始到结束复制到name分支,注意:`前开后闭`

### tag
|命令|说明|
|---|---|
|`git tag`|查看本地tag
|`git tag [name]`|创建轻量tag
|`git tag -a [name] -m [message]`|创建附注tag,不带-m会提示你输入message
|`git tag [name] [commitId]`|对历史commit创建tag
|`git tag -l "[tag规则]"`|按规则查询tag,注意规则在双引号内,如`git tag -l "v2.*"`
|`git push origin [name]`|推送tag到服务器
|`git push origin --tags`|推送所有tag到服务器
|`git tag -d [name]`|删除tag
|`git push origin :refs/tags/[name]`|删除远程tag
|`git show [name]`|查询tag具体信息
|`git pull --tags`|拉取远程仓库的标签
|`git push --tags`|推送标签到远程仓库
|`git ls-remote --tags origin`|查看远程仓库tag
|`git checkout [tag]`|切换到tag的位置,默认不会创建新的分支
|`git checkout -b [name] [tag]`|创建新的分支并切换到tag的位置,`[name]`非必须

> 如果创建的不是轻量tag,推送到远程后用`git ls-remote --tags origin`命令查看会产生一个后缀为`^{}`的同名tag.

### switch
|命令|说明|
|---|---|
|`git switch [name]`|切换分支,如果没有则报错,如果本地没有远程有则拉取
|`git switch -`|切换到上一个分支
|`git switch -c [name]`|创建并切换分支,如果有则报错
|`git switch -c [name] [commit]`|以一个提交来创建分支
|`git switch --detach [commit]`|切换到一个提交,不创建分支
|`git switch --orphan [name]`|创建一个没有任何提交记录的分支,内容为空
|`git switch -c [name] [tagName]`|以一个tag创建分支

### 提交
|命令|说明|
|---|---|
|`git status`|查看当前分支状态
|`git status -sb`|简洁输出当前分支状态,`short branch`
|`git show --stat`|查看当前状态
|`git commit [filename] -m [message]`|提交一个文件
|`git commit -am [message]`|提交所有文件
|`git add [filename]`|新增文件
|`git add .`|新增所有文件
|`git rm [filename]`|删除文件


### 暂存区
|命令|说明|
|---|---|
|`git stash`|存到暂存区,如果有修改没有提交无法切换分支,可以先暂存
|`git stash list`|查看暂存区
|`git stash pop`|从暂存区取出,暂存区删除
|`git stash apply`|从暂存区取出,暂存区不删除
|`git stash clear`|删除所有缓存


### 回退
|命令|说明|
|---|---|
|`git diff`|查看尚未暂存的更新
|`git clean [-n]`|显示当前目录下没有被add的文件
|`git clean [-f]`|删除当前目录下没有被add的文件
|`git reset --hard [commitid]`|回退到上一个commit,所有提交都被删除
|`git reset --hard origin/master`|强制更新本地内容,一般搭配`git fetch`命令一起使用
|`git reset --soft [commitid]`|回退到上一个commit,所有提交都保留
|`git reset --mixed [commitid]`|回退到上一个commit,所有提交都保留

> `git reset --soft`和`--mixed`区别在于如果当前commit和上一个commit之间有新增的文件,`--soft`回退之后该文件处于已add的状态,`--mixed`回退之后该文件处于未add的状态,需要在执行`git add`.


### 日志
|命令|说明|
|---|---|
|`git reflog`|查看所有分支所有日志,log的其它参数同样使用reflog
|`git log`|查看当前分支所有日志
|`git log --pretty=oneline`|单行模式查看当前分支所有日志
|`git log -n 5`|查看前5条日志
|`git log --stat -n 5`|查看前5条日志,并简要显示增改行数
|`git log --since=2.days`|查看最近2天的日志
|`git log --grep=test`|查看关键字包含为`test`的日志
|`git log --author=Wuzhiyong`|查看指定作者的日志
|`git log --committer=Wuzhiyong`|查看指定作者的日志
|`git show [commitid]`|查看某次commit的修改
|`git log --graph --oneline --decorate --simplify-by-decoration --all`|查看分支图
|`git show-ref`|查看本地refs,添加`--tags`查看本地tag,`--heads`查看本地分支

### 问题
- 配置公钥
```bash
# 生成公钥,过程中按3次回车
ssh-keygen -t ed25519 -C "xxxxx@xxxxx.com"
# 进入gitee添加公钥
# 测试公钥是否能用
ssh -T git@gitee.com
# 返回以下内容证明配置正确
Hi XXX! You've successfully authenticated, but Gitee.com does not provide shell access.
```
> 如果配置正确还是让输入用户密码,首先`git remote -v`检查远程地址是`https`还是`ssh`.使用`git remote set-url origin git@gitee.com:happywzy/xxxx.git`修改.

- rebase操作
```bash
# 目标希望将fd75768和e87d4921两个连续的提交rebase到master分支
# 因为是前开后闭,这里start通过^向前指定了一个区间
# 也可以start设置为fd75768前一个commitid
$ git rebase fd75768^ e87d4921 --onto master
fatal: It seems that there is already a rebase-merge directory, and
I wonder if you are in the middle of another rebase. If that is the
case, please try
git rebase (--continue | --abort | --skip)
If that is not the case, please
rm -fr ".git/rebase-merge"
and run me again. I am stopping in case you still have something
valuable there.
# 上面提示已经存在一个rebase-merge目录,先删除了
$ rm -fr ".git/rebase-merge"
# 再次执行
$ git rebase fd75768^ e87d4921 --onto master
Successfully rebased and updated detached HEAD.
# 切换到master分支,提示刚刚复制了两个提交,即HEAD后面还有两个提交
$ git checkout master
Warning: you are leaving 2 commits behind, not connected to
any of your branches:
b9bb17a step 5
f2d9256 step 4
If you want to keep them by creating a new branch, this may be a good time
to do so with:
git branch <new-branch-name> b9bb17a
Switched to branch 'master'
# 现在切回master看不到复制过来的提交
# 通过下面的命令可以将HEAD重置到最新提交,即可看到rebase过来的2个提交
$ git reset --hard b9bb17a
```