Git,当下主流的版本控制工具,功能强大,说主流也无可厚非。但是大部分开发者依旧过度依赖于IDE或现有工具的界面化git操作,日子一久,难免生疏,遂整理了这篇平常实战中宝典。
概念
- 工作区(disk working )
即当前的工作目录 - 暂存区(staging area)
即通过git add命令改动的文件就存入了暂存区 - 本地仓库(local repo)
即通过git commit命令改动的文件就存入了本地仓库 - 远程仓库(remote repo)
即通过git push命令改动的文件推送到了远程仓库
基本操作
1. git clone
从远程git repo创建一个本地拷贝,本地repo以url最后一个斜线后的名称命名
- 指定名称
git clone <url> <newname>
- 指定分支
git clone -b <branch-name> --single-branch <url>
2. git add
将本地工作区的改动添加到暂存区
- 添加指定文件
git add <file-name>
- 添加当前目录下所有文件
git add .
3. git commit
将暂存区的内容改动提交到本地仓库
git commit -m "commit-message"
- 修改上一个commit描述内容
git commit --amend
- 修改作者名称
git commit --amend --author='Author Name <email@address.com>'
4. git push
将当前分支merge到远程关联的分支
- 若分支已经存在则更新,不存在则添加
git push -u <alias> <branch-name>
- 已关联远程分支
1. git branch -vv 查看关联远程分支名称
2. git push 直接push到远程对应的分支
5. git fetch
拉取远程仓库的内容更新和分支更新
- 获取指定repo更新
git fetch <alias>
- 获取所有repo更新
git fetch --all
6. git merge
把一个分支合并到当前分支
1. git checkout <branch-name> 检出目标分支
2. git merge <alias>/<branch-name> merge到目标分支
- 若产生冲突
1. git mergetool 手动解决冲突
2. git diff 对比
3. git add 将改动添加到暂存区
7. git pull
从远程仓库拉取内容并merge到当前分支,pull = fetch + merge,首先执行git fetch,然后执行git merge,把原来分支HEAD merge到当前分支,然后产生一个新的commit
- 改变pull的merge操作,实用rebase方式
git pull --rebase
8. git rebase
将本地的所有提交临时保存为补丁(patch),放在”.git/rebase”目录中,然后将当前分支更新到最新的分支尖端,最后把保存的补丁应用到分支上。
$ git checkout <target-branch>
$ git rebase <origin-branch> 将target-branch更新为最新的origin-branch,再把保存的patch应用到target-branch
在rebase的过程中,也许会出现冲突(conflict)。处理完冲突后,我们通过以下命令来进行rebase操作:
$ git add . 更新内容索引(index),将改动添加到暂存区
$ git rebase --continue 继续应用(apply)余下的补丁
$ git rebase --abort 任何时候,可以用--abort参数来终止rebase的行动,并且分支会回到rebase开始前的状态
9. git remote
remote主要用于管理项目关联的远程仓库,通过别名来标识远程主机
- 展示所有远程仓库
git remote
- 展示每一个别名对应的实际仓库地址
git remote -v
- 添加一个新的remote repo
git remote add <alias> <url>
- 删除一个存在的仓库
git remote rm <alias> 删除一个存在的remote alias.(如果添加的时候提示已经存在,则可以使用该命令先删除alias再添加)
- 更新远程仓库的主机地址
git remote set-url <alias> <url> 更新url. 可以加上—push和fetch参数,为同一个别名set不同的存取地址.
10. git branch
用来列出分支,创建分支和删除分支
- 列出本地所有分支
git branch
- 列出本地和远程分支
git branch -a
- 列出远程分支
git branch -r
- 列出本地所有分支最近一个提交
git branch -v
- 展示所有的分支关联的远程仓库
git branch -vv
- 创建分支
git branch <branch-name> 基于上一次提交创建的分支
- 删除分支
git branch -d <branch-name>
- 删除远程分支
推送代码到远程的关联分支
git push <远程主机名> <本地分支名>:<远程分支名>
如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支
git push <alias> :<remote-branch-name>
等同于
git push <alias> --delete <remote-branch-name>
11. git checkout
- 创建一个本地分支track远程的分支
git checkout -b <branch-name> <alias>/<branch-name>
- 切换到一个已存在分支
git checkout <branch-name>
- 快速切换分支
git checkout -
- 放弃工作区指定文件的修改
git checkout -- <file-name> 删除该文件中所有没有暂存和提交的改动,这个操作是不可逆的,-- 可以不加
- 放弃工作区所有的改动
git checkout .
- 把A分支的某一个commit,放到B分支上
1. git checkout <b-branch-name>
2. git cherry-pick <commit SHA>
- 新建并切换到新分支上,同时这个分支没有任何commit
git checkout --orphan <branch-name>
- 从stash中拿出某个文件的修改
git checkout <stash@{n}> -- <file-path>
12. git tag
建立书签
- 展示当前分支的最近的tag
git describe --tags --abbrev=0
- 在最近一个commit(通常release版本)上建立书签
git tag -a <version-number> 需要输入tag信息
- 在指定历史commit SHA上建立书签
git tag -a <version-number> <commit SHA>
或
git tag -a <version-number> -m "发布(描述)" <commit SHA>
- 将指定tag 同步到远程仓库
git push <alias> <local-version-number>
- 将所有tag 同步到指定远程仓库
git push <alias> --tags
- 删除本地标签
git tag -d <tag-name>
13. git stash
将当前工作区、暂存区的改动压入栈(不包括为track的文件),保留为上一次commit后的clean状态
- 存储当前的修改,但不用提交commit
git stash
- 保存当前状态,包括untracked的文件
git stash -u
- 展示压入栈内的改动
git stash list
- 取出stash栈顶的项目应用于当前工作目录
git stash apply
- 取出stash栈内指定项目应用于当前工作目录
git stash apply stash@{3}
- 回到最后一个stash的状态,并删除这个stash
git stash pop
- 清空stash栈中的所有项目
git stash clear
14. git clean
移除工作目录中未track的文件
- 移除所有untracked文件
git clean -f
- 强制删除untracked的文件
git clean <file-name> -f
- 强制移除untracked的目录
git clean <directory-name> -df -d参数表示同时移除目录,-f表示强制执行。在git的配置文件中, clean.requireForce=true,如果不加-f,clean将会拒绝执行.
15. git rm
移除文件
- 移除工作区的文件,同时也从暂存区移除
git rm <file-name>
- 仅移除暂存区文件,工作区保留
git rm --cached 功能上等同于git reset HEAD,清除了缓存区,但不动工作目录树
例如:移除被git track的文件
git rm --cached app.iml
git commit -m 'remove file that in gitignore but already tracked by git'
16. git reset
撤销改动和提交
- 把暂存区的指定file放到工作区中
git reset <file-name>
- 撤销所有暂存区的改动,恢复回工作目录
git reset HEAD 通常应用于误add进暂存区的文件
- 撤销指定的暂存区的改动
git reset HEAD <filename>
- 还原工作区、暂存区的所有改动到提交历史尖端
git reset HEAD --hard
- 还原到指定的commit SHA
git reset --hard <commit SHA> reset命令会抹去某个commit id之后的所有commit
总结:
git reset --mixed id 是将git的HEAD变了(也就是提交记录变了),但文件并没有改变,(也就是working tree并没有改变). 取消了commit和add的内容.
git reset --soft id 实际上,是git reset –mixed id 后,又做了一次git add.即取消了commit的内容.
git reset --hard id 是将git的HEAD变了,文件也变了.例如:git reset --hard de7fc4f
按改动范围排序如下:
soft (commit) < mixed (commit + add) < hard (commit + add + local working)
不带soft和hard参数的git reset,实际上带的是默认参数mixed.
17. git revert
撤销提交
- 撤销最近的一个提交
git revert HEAD revert会创建一个反向的新提交,可以通过参数-n来告诉Git先不要提交
18. git diff
比较文件的改动
- 对比工作区和暂存区域快照之间的差异
git diff
- 对比暂存区和上次提交时快照之间的差异
git diff --cached
- 对比工作区和上次提交时快照之间的差异
git diff HEAD
- 对比两个分支的差异
git diff <branchA> <branchB>
- 对比两个分支分离后的改动
git diff <branchA>…<branchB>
- 对比本地仓库中任意两个commit之间的文件变动
git diff <commit SHA><commit SHA>
19. git log
展示分支的提交历史
- 图形化地表示出分支合并历史
git log --oneline --graph
- 显示特定分支的log
git log <branch-name>
- 查看在分支1,却不在分支2中的提交
git log --oneline <branch1> ^<branch2>
- 展示commit关联的分支、tag信息
git log --oneline --decorate
- 展示指定作者的提交历史
git log --author=<author name>
- 展所有作者的提交历史描述
git shortlog
- 限制输出数量
git log -n n替换为需要输出的数量
- 根据commit信息过滤log
git log --grep=<keywords>
- 查看每次commit的diff
git log -p 每一个提交都是一个快照(snapshot),Git会把每次提交的diff计算出来,作为一个patch
或
git log --stat 展示每个改动的介绍,--stat比-p的输出更简单一些
或
git show <commit SHA>
20. git status
查询repo的状态
- 简略展示暂存区和工作区的状态
git status -s
高级使用
1. 回到远程仓库的状态
抛弃本地仓库的所有版本(commit)【以及工作区中的内容】,回到远程仓库的状态
1. git fetch --all
2. git reset --hard <alias>/<branch-name>
2. 重设第一个commit
也就是把所有的改动都重新放回工作区【即不被git管理】,并清空所有的commit,这样就可以重新提交第一个commit了
git update-ref -d HEAD
3. 修改上一个commit的描述
1. git commit --amend
2. vim编辑描述
4. 查看某段代码的作者
git blame <file-name>
5. 显示本地执行过git命令
git reflog 类似shell的history命令
6. 提交时修改作者名
git commit --amend --author='Author Name <email@address.com>'
7. 给git命令起别名
git config --global alias.<handle> <command>
比如:git status 改成 git st,这样可以简化命令
git config --global alias.st status
8. 展示文件
git ls-files -t 展示所有tracked的文件
git ls-files --others 展示所有untracked的文件
git ls-files --others -i --exclude-standard 展示所有忽略的文件
9. 重命名分支
git branch -m <new-branch-name>
10. 执行rebase之前自动stash
git rebase --autostash
11. 从远程仓库根据ID,拉下某一状态,到本地分支
git fetch <alias> pull/<commit id>/head:<branch-name>
12. 清除gitignore文件中记录的文件
git clean -X -f
13. 展示忽略的文件
git status --ignored
14. 展示任意分支某一文件的内容
git show <branch-name>:<file-name>
15. 强制推送
git push -f <remote-name><branch-name>