前言
之前有写过一篇 Git 命令总结,但没有一个比较好的教程来实践这些命令,此篇文章总结是建立在 [Pro Git第二版] 基础之上,结合开发过程中实际的使用情况,挑选了一些非常实用的命令,如果你正在看 Pro Git 此书,希望看完以后通过这篇文章进行知识回顾。
起步
设置用户信息:
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
查看所有配置信息:
通过查看所有配置信息,可以单独设置或查看某一项配置
$ git config --list
$ git config -l
单独检查 Git 的某一项配置:
$ git config user.name // 查看 user.name
$ git config color.status // 查看 color.status
$ git config user.name "Riny Ren" // 设置 user.name
获取 git 帮助的三种方式:
$ git help config // 获得 config 命令的手册
$ git config --help // 获得 config 命令的手册
$ man git-config // 获得 config 命令的手册
基础
初始化项目:一种是本地创建 init ,另一种是 clone 。
$ git init
$ git clone https://github.com/angular/angular
查看文件状态:
$ git status
$ git status -s // 简洁格式
$ git status -short // 简洁格式
添加文件到暂存区:
$ git add router.js // 添加当前路径下的 router.js 的文件
$ git add *.js // 添加当前路径下的 .js 后缀的文件
$ git . // 添加当前目录下所有文件
$ git * // 添加当前目录下所有文件
查看内容改动:
$ git diff // 工作区与暂存区对比
$ git diff --staged // 暂存区与本地仓库对比
$ git diff --cached // 暂存区与本地仓库对比,与上面命令等价
$ git diff HEAD // 工作区与与本地仓库对比
暂存区提交到本地仓库:
$ git commit // 不输入 commit 信息会启动 vim 编辑器
$ git commit -m '第一次提交' // 带 message 参数输入信息,不需要启动编辑器
$ git commit -a -m '第一次提交' // -a 参数,会先执行 git add 命令,简化流程
// 指定暂存区文件到本地仓库
$ git commit [file1] [file2] ... -m [message]
移动文件:(有重命名功能)
$ git mv a.txt b.txt // 把文件名 a 改为文件名 b [重命名]
$ git mv a.txt public/a.txt // 把文件名 a 移动到当前目录下的 public 文件中
移除 Git 已关联(追踪)的文件:
$ git rm router.js // 移除当前路径下的 router.js 的文件
$ git rm *.js // 移除当前路径下的 .js 后缀的文件
$ git rm --cached router.js // 停止 git 文件追踪,不删除文件
查看提交历史:(可以通过 SourceTree 查看提交历史)
$ git log
$ git log -2 // 查看最近2条历史 (常用)
$ git log --stat // 显示额外的提交总结信息(常用)
$ git log --oneline // 单行显示,不推荐使用--pretty=oneline(常用)
$ git log --oneline --graph // 路线图显示
$ git reflog // 可查看已被撤销的 commit 历史,非常实用
追加遗漏掉的 commit :
在实际使用中非常常用,当你 commit 的时候发现有文件遗漏掉,需要追加时,加上--amend
参数不会生成额外的 commit 信息。
$ git commit --amend
撤消对文件的修改:
撤销对工作区的修改,也就是未添加到缓存区的文件,注意有2个中划线。
$ git checkout -- config.js
撤销暂存的文件:
$ git reset HEAD config.js // 软撤销,会将之前的修改保存在工作区
$ git reset HEAD --hard config.js // 硬撤销 会放弃之前的修改
查看远程服务器以及仓库地址:
$ git remote -v
从远程仓库抓取:
$ git fetch // 不输入默认为 origin
$ git fetch origin2 // 可以指定远程仓库的名称
从远程仓库拉取:
$ git pull // 不输入默认为 origin
$ git pull origin2 // 可以指定远程仓库的名称
推送到远程仓库:
$ git push // 不输入默认为 origin
$ git push origin2 // 可以指定远程仓库的名称
设置命令别名:
设置命令别名可以简化命令书写。
// 设置成功后 git co a.txt 等价于 git checkout a.txt
$ git config --global alias.co checkout
// 设置成功后 git unstage a.txt 等价于 git reset HEAD -- a.txt
$ git config --global alias.unstage 'reset HEAD --'
分支
分支创建:
基于当前的 branch 创建新分支。
$ git branch dev
分支切换:
分支切换时,要保证工作区和暂存区是干净的。
$ git checkout master
分支的创建+切换:
$ git checkout -b dev // 创建并切换分支
$ git checkout -b dev origin/dev // 从远端 dev 分支创建新的分支
$ git checkout -b fixbug dev // 从本地本地 dev 分支创建新的分支
合并分支:
$ git merge dev // 把 dev 分支合并到当前分支
删除分支:
$ git branch -d fixbug // 软删除,分支未 marge 会删除失败
$ git branch -D fixbug // 强制删除,分支未 marge 会丢失分支的数据
可以通过查看分支情况看确定 branch 是否已经合并。
查看分支 merge 情况:
$ git branch --merged // 列出已 merge 的分支
$ git branch --no-merged // 列出未 merge 的分支
查看本地的分支:
$ git branch
查看远端的分支:
$ git ls-remote
查看所有的分支:(包含本地和远端)
$ git branch -a
删除远程分支:
git push origin --delete fixbug // 删除远端分支 fixbug
生成远程分支:
在创建本地分支时,如果没有从远端分支创建(也叫检出)本地分支,那么本地分支是没有和远端分支相关联的;如果本地需要关联(追踪)远端分支,前提是远端分支需要存在,所以第一次创建的分支,在 push
之前需要生成远端分支。如果不加 --set-upstream
参数,在命令行会提醒你带上此参数来创建上游分支。
git checkout -b fixbug develop // 从develop 分支下创建 fixbug
// 此时没有跟踪关系,因为 develop 和当前分支都属于本地分支
git push --set-upstream origin fixbug
// 设置上游分支(其实就是创建远端分支并追踪推送)
技巧
以上是根据 Pro Git 教程挑选出来的非常有用的命令,主要的命令讲解在此书中讲的非常清楚,所以不再赘述。接下来会介绍一些在实际应用中非常有用的操作。
查看某个 commit 的变化:
// 通过 git log 查看 commit 变化
$ git log
$ git show [commit id]
通过可视化工具查看 commit 历史更加方便,推荐使用 sourceTree,在关联好本地仓库后,找到历史菜单,可以看到 git log 以图形化的方式显示所有的 commit 的信息。
合并分支:
分支是 Git 的核心,在大型项目中,每天远端会出现上百个分支也不足为奇,在合并分支时只需要清楚,当前所在分支是目标分支,另外一个分支就是被合并分支。
$ git branch // 查看当前所在分支
$ git merge [branch name] // 合并 [branch name] 到当前分支
在 SourceTree 中合并分支更加简单,只需要切换到目标分支后,右击其他分支,选择合并。
解决冲突:
在合并分支中经常产生冲突,所以学会解决冲突是一项非常重要的技能,如果在 merge branch 时发生冲突,Git 会在被冲突的文件加上一串标识符,<<<<<<<
,=======
,>>>>>>>
标记出不同分支的内容。
// RAEDME.md
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
可以看到冲突被标记了出来,上面的更改来自 HEAD,也就是当前分支的修改,下面的更改来自分支 feature1 ,手动解决其实非常简单,用文本编辑器打开直接删除不想要的,保留想要的。
step1:先删除不需要保留的代码片段。
<<<<<<< HEAD
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
step2:再删除 Git 标记即可。
Creating a new branch is quick AND simple.
或者两次更改都保留,删除 Git 标记。
Creating a new branch is quick & simple.
Creating a new branch is quick AND simple.
紧接着 git commit -a
即可,在发生冲突时,Git 会自动为我们加上 message 信息,所以不需要 -m 参数去增加信息,执行命令后会进入到 vim 编辑器中,在编辑器中输入 :wq
即可保存退出 vim 编辑器。
如果在解决冲突时,发现发现自己操作失误,想放弃本次 merge,可以使用下面命令放弃本次merge:
git merge --abort
撤销最近 commit 的修改:
使用 reset 来撤回刚刚本地 commit 的修改:
$ git reset HEAD^ // HEAD 是刚刚最后一次的commit,需要用HEAD^
不带参数撤回后,之前 commit 的修改会放在工作区,一般 --hard
和 --soft
比较常用。
$ git reset HEAD^ --soft // commit 的修改会存放在暂存区
$ git reset HEAD^ --hard // commit 的修改会直接放弃,一般不推荐使用
使用 Git 临时存储区:
在实际开发中会不断的切换分支,当你的代码写到一半需要切换到另外一个分支的时候,你又不想 commit --amend
来追加 commit ,类似于食之无味,弃之可惜,可以使用 stash
命令缓存起来,下次再来思考这个问题。
$ git stash // 把当前工作区[未添加到暂存区]的文件存储起来 [存储]
$ git stash list // 查看所有存储的栈,最新入栈的编号为{0} [查找]
$ git stash apply stash@{0} // 取出存储区栈编号为{0}的文件修改 [取出]
$ git stash clear // 清除所有的存储栈 [清除]
撤销 reset 重置:
当你 reset 时发现弄错了,想回到最新版本的 commit ,可是在 git log
里没有找到你的 commit id
,这时可以通过 git reflog
查看之前的操作记录,拿到 HEAD_ID,然后 reset
回去。
git reflog 会记录你的 reset
, commit
, checkout
, clone
等关键操作。
$ git reflog
6504c5a HEAD@{0}: reset: moving to HEAD^
e63a0bf HEAD@{1}: reset: moving to e63a0bf
6504c5a HEAD@{2}: reset: moving to HEAD^
e63a0bf HEAD@{3}: commit: 5月11日 10点04分 新增一行
然后执行reset:
$ git reset --hard e63a0bf
这里需要加上 hard 参数,放弃当前 commit 基于目标 commit 的修改,也就是直接使用目标 commit 的内容。这里有点绕,需要自己试验一下,如果没 reset 成功,不需要慌张,使用 git status 查看状态,看是否修改的已在缓存区。
后记
熟练使用 Git 需要记忆大量的命令,一旦熟悉这些基础命令,对于图形化工具的原理会更加清楚,对使用图形化工具非常也帮助,如果有一些场景没有涉及到请留言,我会更新补充。