Git 常用命令参考手册

一份 Git 常用命令参考手册,汇总了我在日常开发中使用频率最高的 Git 命令。
官方文档肯定比我全面,这里是结合实际业务场景输出。

一、安装

1. windows

2. Mac

TODO……(我没有苹果电脑)

二、Git 配置

只整理常用的 Git 配置操作。

# 查看全局配置列表
git config --global -l
# 查看局部配置列表
git config --local -l

# 查看已设置的全局用户名/邮箱
git config --global --get user.name
git config --global --get user.email

# 设置全局用户名/邮箱
git config --global user.name "输入你的用户名"
git config --global user.email "输入你的邮箱"

# 设置本地当前工作区仓库用户名/邮箱
git config --local user.name "输入你的用户名"
git config --local user.email "输入你的邮箱"

# 删除配置
git config --unset --global user.name
git config --unset --global user.email

# 文件权限的变动也会视为改动, 可通过以下配置忽略文件权限变动
git config core.fileMode false

# 文件大小写设为敏感, git默认是忽略大小写
git config --global core.ignorecase false

三、初始化仓库

即新建一个工程,将它关联上 GitHub 上的仓库,最后提交这个新建的工程到 GitHub 中。

1. 前置工作

在 GitHub 上手动创建一个仓库,比如名字叫 hello-world。

2. 操作步骤

依次在本地执行如下的命令:

# 如果本地已经新建好了 hello-world 目录,则跳过该命令,直接 cd 到 hello-world 目录下
mkdir hello-world

# 进入目标工程的根目录
cd hello-world

# 初始化本地仓库:会在当前目录生成 .git
git init

# 提交时转换成 unix 风格的换行符,检出时不转换(看各人习惯设置)
git config --global core.autocrlf input

# 添加要 push 到远程仓库的文件或文件夹(全部就写 git add .)
git add xxx

# 提交文件到本地库
git commit -m "first commit"

# 关联远程仓库
git remote add origin https://github.com/yourGithubID/hello-world.git

# 将本地仓库 push 到远程仓库
git push -u origin master                                  

3. 注意要点

在实践过程中,由于在 GitHub 上手动创建的仓库包括:README.md 文件,而本地仓库没有此文件,则在执行 git push -u origin master 命令前,需要先做如下两步:

第一步:可以通过如下命令进行代码合并【注:pull = fetch + merge】。

git pull --rebase origin master

执行上面代码后可以看到本地代码库中多了 README.md 文件。

第二步:此时再执行语句 git push -u origin master 即可完成代码上传到 GitHub。

四、克隆仓库

即将 GitHub 上的代码下载到本地,注意不是简单的 Download ZIP,那样下载的代码没有与远程仓库建立关联,无法做版本维护。

这里用的命令就是 clone

# https 协议
git clone https://github.com/yourGithubID/hello-world.git

# SSH 协议(一般不用)
git clone git@github.com:yourGithubID/hello-world.git

# 克隆指定分支, -b 指定分支名字,实际上是克隆所有分支并切换到 develop 分支上
git clone -b develop https://github.com/yourGithubID/hello-world.git

# --single-branch 完全只克隆指定分支
git clone -b develop --single-branch https://github.com/yourGithubID/hello-world.git

# 指定克隆后的文件夹名称
git clone https://github.com/yourGithubID/hello-world.git new-hello-world

# 克隆深度为1,只克隆指定分支,历史记录只克隆最后一条,减少克隆时间
git clone --depth=1 https://github.com/yourGithubID/hello-world.git

五、查看工作区状态

查看本地工作区的状态。

# 查看当前工作区暂存区变动,等同 git status --long
git status

# 以短格式给出输出
git status -s

# 显示已忽略的文件
git status --ignored

# 查询工作区中是否有 stash 存在(暂存的东西),有则提醒该工作区有几个 stash
git status --show-stash

六、查看日志

查看日志,经常用的命令。

# 查看完整历史提交记录
git log

# 查看前 N 次提交记录
git log -2

# 查看前 N 次提交记录,包括 diff
git log -p -2

# 查看指定作者历史记录
git log --author=<your_name>

# 查看指定文件的历史提交记录
git log <file>

# 只显示合并日志
git log --merges

# 以图形查看日志记录,--oneline 可选,表示输出概要日志
git log --graph --oneline

# 列出提交者代码贡献数量,打印作者和贡献数量
git shortlog -sn

# 以提交贡献数量排序并打印出 message
git shortlog -n

七、分支操作

1. 查看分支

# 查看所有分支
git branch -a

# 查看本地分支
git branch

# 查看远端分支
git branch -r

# 查看本地分支所关联的远程分支
git branch -vv

2. 删除分支

比较常用的是删除本地分支,重命名分支,删除远程分支。

# 删除本地分支,参数 -d 若是大写就等同多了--force,强制执行
git branch -d <branch_name>

# 移动或者重命名本地分支,参数 -m 若是大写就等同多了--force,强制执行
git branch -m <old_branch_name> <new_branch_name>

# 删除远程分支
git push origin -d <branch_name>

3. 切换分支

# 切换到某一个本地分支
git checkout <branch_name>

# 切换远端分支(通常是本地没有远端的分支记录才会使用此命令,反之不建议)
git checkout --track origin/<branch_name>

4. 合并分支

合并分支的操作一般借助可视化工具来做,纯命令的方式我不太熟练。

# 将 feature/v1.0.0 分支代码合并到 develop
git checkout develop
git merge feature/v1.0.0

# 以安静模式合并,把 develop 分支合并到当前分支并不输出任何信息
git merge develop -q

# 合并不编辑消息,跳过交互
git merge develop --no-edit

# 合并分支后不进行提交
git merge develop --no-commit

# 退出合并,恢复到合并之前的状态
git merge --abort

八、解决冲突

1. 冲突产生的原因

多人协作的开发模式,在代码合并/更新代码时经常会遇到冲突的情况,最常见的是在 push 时,Git 发现本地修改的某个文件在远端也做了修改,那么就会提示需要先进行 pull。

pull 后会有两种情况:

  • Git 自动做了合并(无需理会)
  • 提示有文件存在冲突 - CONFLICT

还有一种情况就是同一个文件,在合并分支的时候,如果同一行被多个分支或者不同人都修改了,合并的时候也会出现冲突。

2. 解决冲突的步骤

解决冲突需要自己去判断到底要保留远端代码还是本地代码或者两端都保留。

这个操作一般借助可视化工具进行比较方便,具体步骤如下:

  • 查看冲突文件内容
  • 确定冲突内容保留哪些部分,修改文件
  • 重新提交,done

3. 冲突标记介绍

Git 提示冲突后,我们切换到对应文件,可以看到冲突内容被标记出来了。

<<<<<<< HEAD:file.txt

Hello world

=======

Goodbye

>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt

可以看到Git用 <<<<<<<,=======,>>>>>>> 将代码分成了三个区域。

其中 <<<<<<< HEAD 和 ======= 之间的内容表示你本地的分支;
======= 和 >>>>>>> 之间的表示本次 pull 下来或 merge 过来的内容。

九、文件暂存

应用场景:在当前分支开发时,临时需要切换到其他分支修改 Bug,但此时又不想提交当前分支上开发到一半的代码(切换分支必须把当前工作内容提交,否则无法切换),这个时候就可以用到 git stash

强烈建议给每个 stash 添加描述信息!!!

# 暂存当前工作区内容
git stash

# 暂存时添加描述信息,推荐使用此命令
git stash push -m "更改了 xx"

# 暂存包含没有被 Git 追踪的文件
git stash -u

# 查看当前暂存列表
git stash list

# 恢复修改工作区内容, 会从 git stash list 移除掉
git stash pop # 恢复最近一次保存内容到工作区,默认会把暂存区的改动恢复到工作区
git stash pop stash@{1} # 恢复指定 id, 通过 git stash list 可查到

# 与 pop 命令一致,唯一不同的是不会从 git stash list 移除掉
git stash apply

# 清空所有保存(慎用)
git stash clear

# 清空指定 stash id, 如果 drop 后面不指定 id 则清除最近的一次
git stash drop stash@{0}
git stash drop  # 清除最近一次

# 想看 stash 做了什么改动,类似简化版的 git diff
git stash show stash@{0}

十、查看文件 diff

git diff 命令用于查看文件内容之间差异,对于这个命令,在终端比对用的不是很频繁,除了少量改动的时侯可能会用这个看看。

其他情况下我更倾向于用可视化工具来看,因为比对更加直观。

# 比较所有文件工作区与暂存区的差异
git diff

# 比较指定文件工作区与暂存区差异
git diff <file>

# 比较两次提交之间的差异
git diff <commit_id1> <commit_id2>

# 显示出所有有差异的文件的详细差异
git diff <branch1> <branch2>

# 将 diff 结果打印到文件
git diff --color master > content.txt

十一、代码回滚(reset/revert)

1. reset 方式

代码回滚中这个命令也是用的很多,而且是 –hard 用的比较多。

–hard:硬性回滚,简单粗暴,直接抛弃上次提交后的所有本次修改,回滚到之前的样子
–soft:软性回滚,可以理解为撤销指定的 commit 记录

# 回滚上一个版本
git reset --hard HEAD^

# 回滚上两个版本
git reset --hard HEAD^^

# 回滚到指定 commit_id,通过 git log 查看
git reset --hard <commit_id>

2. revert 方式(优雅)

使用 git reset 回退版本后,需要其他所有人手动用远程 master 分支覆盖本地 master 分支,显然,这不是优雅的回退方法。

git revert 撤销某次提交后,它会产生一个新的提交,虽然代码回退了,但是版本依然是向前的,所以,当你用 revert 回退之后,所有人 pull 之后,他们的代码也自动的回退了。

# 恢复某次提交的状态,恢复动作本身也创建了一次提交对象
git revert <commit_id>

# 恢复最后一次提交的状态
git revert HEAD

但是,要注意以下几点:

  • revert 是撤销一次提交,所以后面的 commit_id 是你需要回滚到的版本的上一次提交;
  • 使用 revert HEAD 是撤销最近的一次提交,如果你最近一次提交是用 revert 命令产生的,那么你再执行一次,就相当于撤销了上次的撤销操作,换句话说,你连续执行两次 revert HEAD 命令,就跟没执行是一样的;
  • 使用 revert HEAD~1 表示撤销最近 2 次提交,这个数字是从 0 开始的,如果你之前撤销过产生了 commit_id,那么也会计算在内的;
  • 如果使用 revert 撤销的不是最近一次提交,那么一定会有代码冲突,需要你合并代码,合并代码只需要把当前的代码全部去掉,保留之前版本的代码就可以了。

git revert 命令的好处就是不会丢掉别人的提交,即使你撤销后覆盖了别人的提交,他更新代码后,可以在本地用 reset 向前回滚,找到自己的代码,然后拉一下分支,再回来合并上去就可以找回被你覆盖的提交了。

3. reset 和 revert 区别

  • git revert 是用一次新的 commit 来回滚之前的 commit,git reset 是直接删除指定的 commit。
  • 在回滚这一操作上看,效果差不多。但是在日后继续 merge 以前的老版本时有区别。因为 git revert 是用一次逆向的 commit「中和」之前的提交,因此日后合并老的 branch 时,导致这部分改变不会再次出现,但是 git reset 是直接把某些 commit 在某个 branch 上删除,因而和老的 branch 再次 merge 时,这些被回滚的 commit 应该还会被引入。
  • git reset 是把 HEAD 向后移动了一下,而 git revert 是 HEAD 继续前进,只是新的 commit 的内容和要 revert 的内容正好相反,能够抵消要被 revert 的内容。

十二、合并提交记录(rebase)

有时候,在整个功能开发完毕的时侯,会有非常多的 commit,为了遵循最小化代码提交的理念,需要用 git rebase 让我们的 commit 记录很干净。

这个命令的主要作用是可以将多个 commit 记录合并为一条。

# 操作最近 4 次提交
git rebase -i HEAD~4
# 或者指定要合并到的 commit 的前一个 commit 的 id(不包含),两者之间就是合并的范围
git rebase -i <commit_id>

# 带 -i 可以进入交互模式,若是中间毫无冲突,则会一步到位,否则需要逐步调整。
git rebase --continue # 提交变更后继续下一步
git rebase --skip # 引起冲突的 commit 会被丢弃,continue 提示没有需要改动的也可以用这个跳过
git rebase --abort # 若是本次 rebase 操作进行到一半发现改坏了,可以放弃 rebase 操作,彻底回滚到之前的状态

十三、挑选指定记录合并(cherry-pick)

应用场景:我们希望将某个分支上的某次修改合并到当前分支上,那么就可以使用 cherry-pick 命令进行操作。

# 通常情况执行此命令会产生冲突,需要手动去解决
git cherry-pick <commit_id>

# 保留原有作者信息进行提交
git cherry-pick -x <commit_id>

十四、管理远程仓库

通常使用 git remote 命令来管理远程仓库。

# 查看远程仓库服务器,一般打印 origin,这是 Git 给你克隆的仓库服务器的默认名字
# 一般只会显示 origin,除非你有多个远程仓库地址
git remote

# 指定-v, 查看当前仓库地址
git remote -v

# 添加远程仓库地址 example 是自定义名字
# 添加完后可以通过 git remote 就能看到 example
git remote add example https://github.com/yourGithubID/hello-world-2.git

# 查看指定远程仓库信息
git remote show <branch_name>

# 重命名远程仓库
git remote rename <old_branch_name> <new_branch_name>

# 移除远程仓库
git remote remove <branch_name>


参考
官方文档:https://git-scm.com/book
《Git权威指南第二版》


博文对你有帮助吗?如果有的话,想不想送我一本书呢?
  目录