Git 常用命令复习
最近打算对帝傲狮进行重构,觉得应该是时候启用版本控制工具来管理代码了。想当初为了学习这个,我还专门看了几天的《Git版本控制管理》,可是长期在公司使用clearcase,现在我连它长什么样都记不起来了-_–# 。悔恨当初做的笔记太渣,现在重新把书啃一遍那基本上又不太现实。好在这两年网上积累了好多有关的优秀资源,以下便是我这两天通过学习&使用这些网络资源而整理的git 常用命令的使用说明
git clone
- clone 操作将会复制一个已经存在的git仓库
- clone 操作会自动的创建一个名叫
origin
的远程连接指向原始的仓库 - This makes collaborating with Git fundamentally different than with SVN
git config
git config user.name
设置用户名git config user.email
设置电子邮箱- 默认情况下是对当前仓库进行设置,加上
--global
标签之后,则为全局设置
git add
- 直到运行
git commit
之前,git add
并没有直接影响仓库 git add <file>
stage 单个文件的改变git add <directory>
stage 整个目录的改变git add -p
交互式的add
git commit
- 将处于stage 状态的该表保存到仓库
git commit -a
会将工作区的所有改变保存到仓库- 除非你真的准备好了,否则git 不会强迫你与中心仓库记性交互
- 就像stage 空间是工作目录与代码仓库之间的缓存一样,本地仓库是开发者的代码贡献与中心仓库之间的缓存
-
git commit --amend
修改之前的commit。这将导致当前的stage区间与前一个commit的状态融合。 - 和
git reset
一样,git commit --amend
不应该发生在发布后的<commit>
上。 -
--no-edit
可以使git commit --amend
使用上一次commit的注释
git status
用来显示工作区的状态
git log
- 该命令被用来显示commit 历史
git log
将使用默认格式显示,通常会输出多于一屏的内容。使用空格翻页,使用q
退出。git log -n <limit>
限制输出的条数git log -oneline
高度抽象概括提交情况git log --stat
同时呈现相关文件、相关行的信息git log --author=<pattern>
搜索指定作者的commit。pattern可以是包含正则表达式的字符串git log <since>..<until>
搜索两者之间的commit。since、until既可以是commitID,也可以是branchName或者是其他的referencegit log <file>
查看指定文件的提交情况git log --graph --decorate --oneline
—graph 顾名思义,用来图形化提交状态;——decorate用来显示分支或者便签的名称;
git checkout
- 该命令有三种功能:检出file,检出commit,检出branch
git checkout <existing-branch>
更新本地仓库与<exsiting-branch>
匹配,之后的操作都将记录到该分支上。检出分支后,不必担心之前的最新代码会遭到污染,任何改变如果没有commit
,只存在于stage状态git checkout <commit>
检出commit。会使得工作目录的所有代码变成该commit的状态(<commit>
可以为commit hash或者是tag)。检出一个旧的commit,并不会造成代码丢失,开发状态将会变为detached HEAD
。值得注意的是,开发应当发生在真正的分支上,否则代码融合的时候会遇到不小的麻烦。git checkout <commit> <file>
检出文件。和之前的检出不同,这种检出会影响到当前工程,使得该文件的状态变为Change to be committed,若希望还原回主线状态,应使用git checkout HEAD <file>
git checkout -b <new-branch>
创建分支,并切换到该分支去git checkout -b <new-branch> <exsiting-branch>
与上条一样,不过创建的分支是基于<existing-branch>,而不是当前分支
git revert
- 作为undo 操作存在
- 并没有删除任何commit 结点,而是将之前的结点append 到HEAD
- 比reset 更安全
git reset
- 是一个可能影响仓库安全的命令
- 和
git checkout
一样,根据目的不同,有多种用法 git reset <file>
清除该文件的stage状态,保留工作区间的文件状态git reset
将stage恢复到最近一次提交,保留工作区间的文件状态git reset --hard
将stage和工作区间的文件都恢复到最近一次提交git reset <commit>
将stage恢复到的状态,保留工作区间的状态,以便re-commit的时候有一个更干净的stage git reset --hard <commit>
将stage和工作区间的文件恢复到状态 - 需要注意的是:如果
之后的仓库被发布过,那么你不应该使用 git reset --hard <commit>
,因为有可能其他开发者对这个<commit>
及之后的代码有依赖
git clean
- 该命令通常和
git reset --hard
一起使用 - 主要目的是用来删除工作区间里没有被追踪的文件
git clean -n
并不会真正执行清除,而是告诉你将会清除哪里文件git clean -f
将会清理当前文件夹下的未被跟踪的文件,但并不会清理文件夹以及.gitignore
中提及的文件git clean -df
清理当前文件夹下的未被跟踪的文件和目录git clean -xf
清理当前文件夹下的未被跟踪的文件以及那些git 通常忽略的文件
git branch
- 每一个branch都可以看做是独立的开发流水线,是上述所有操作组合形成的抽象引用
git branch
支持创建,罗列,删除以及重命名操作,通常需要配合git checkout
进行分支切换,配合git merge
进行代码融合- 分支不仅可以使开发任务并行,还可以保证主线代码永远处于可用状态
git branch
罗列当前仓库中所有的分支,带上-r
可以罗列远程分支git branch <branch-name>
创建分支,但并没有切换过去git branch -d <branch-name>
如果代码已经merge回主线,则安全的删除该分支,否则给予警告,且不执行删除操作git branch -D <branch-name>
强行删除分支git branch -m <branch-name>
修改当前分支的名字
git merge
- 通常来说merge 有两种算法来执行:
fast-foward merge
以及3-way merge
- 当前分支与目标分支之间是linear path,则执行
fast-forwad merge
,如图1所示,git 只需要将当前分支的HEAD移过来即可(不走回头路) - 如果当前分支与目标分支之间有分叉,如图2所示,则执行
3-way merge
。 - git 使用
edit/stage/commit
的工作流程来解决merge 冲突:使用edit来解决冲突,使用add 来闭合修改,使用commit 来完成merge
git rebase
git rebase <base>
将当前分支rebase为<base>
,其中<base>
可以为commit、tag或者是分支名称- 使用rebase主要目的是保持项目仓库的linear状态,以便分支融合的时候可以使用
fast-forward merge
- 和
git reset
一样,不要对以发布的仓库部分执行rebase git rebase -i
以交互的形式进行rebase
git remote
- 该命令可以让你创建、查看、删除与其他仓库的连接,这些连接更像是一个个书签
git remote
呈现你的所有连接git remote -v
和上一条命令一样,但是要多显示URLgit remote add <name> <url>
创建一个连接,在此之后,可以直接使用<name>
来访问这个连接了git remote rm <name>
删除这个连接git remote rename <old-name> <new-name>
修改连接名称
git fetch
git fetch <remote>
将该连接的所有分支全部导入本地git fetch <remote> <branch>
仅导入该连接的特定分支- 我们可以checkout 远程分支,但此刻会处于一个HEAD detached状态;可以想象这些远程分支为只读的,我们能做的是review他们的代码以及merge到我们的本地分支上来
git pull
git pull <remote>
将该连接的当前分支导入本地,并进行融合操作git pull --rebase <remote>
和上述操作效果一样,但使用rebase而不是融合git pull
与SVN的update
类似,作用都是保持本地代码最新--rebase
可以避免不要的merge操作- 使用
git config --global branch.autosetuprebase always
将pull的默认动作设置为rebase
git push
git push <remote> <branch>
将推送到远程仓库去。如果本地仓库和远程仓库之间的代码不能执行 fast-forward merge
,则git 会拒绝该次推送git push <remote> --force
和上一条效果一样,只不过会强制执行git push <remote> --tags
将本地标签全部推送到远程仓库去
参考资料
附图
- 图1 a fast-forward merge
- 图2 a 3-way merge