获得版本库
git init
git clone
查看信息
git help
git log
git status
git diff
版本管理
git add
git commit
git rm
远程协作
git push
git pull
分支操作
git branch
查看分支git branch <分支名称>
创建分支git branch -a
查看远程所有分支git branch -d <分支名称>
删除本地分支(如果分支尚未被合并到话,git会阻止当前删除操作)git branch -D <分支名称>
删除本地分支(分支即使尚未合并,也会被删除)git checkout -b <分支名称>
创建并切换到新分支,相当于是git branch <分支>
和git checkout <分支>
两个指令git merge <分支>
将衍生出去的分支合并回当前分支git branch -v
显示当前分支所处的最新一条记录
删除远程分支
# 第一种: 可以简单理解为,将一个分支推送到远程要删除的分支上
git push origin :<remoteBranch>
# 第二种:
git push origin --delete <remoteBranch>
日常开发常见分支
develop
频繁变化的分支,开发人员直接提交的分支test
测试和产品使用的分支,变化不是太频繁master
生产发布分支,版本最稳定
分支本质
分支本质上是一条commit
提交链,也可以说是一条工作记录线,每个提交节点包含了当前节点ID
、上个节点ID
以及提交信息和操作等。
HEAD
指向等当前分支
fast-forward
- 如果可能,合并分支时git会默认使用
fast-forward
模式 - 在
fast-forward
模式下,删除分支会丢掉分支信息 - 合并时加上
--no-ff
参数(git merge --no-ff)会禁用fast-forward
,这样会多出一个commit id
版本回退
回退到上一个版本
git reset --hard HEAD^
git reset --hard HEAD~1
git reset --hard <commit id>
git reflog
查看历史操作,如果使用git reset --hard commit_id
回退到某个节点话,可以使用 git reflog
查看其中的操作,然后再次调用 git reset --hard commit_id
返回到指定的提交节点
checkout 和 stash(保存工作现场)
git checkout <file name>
丢弃工作区中相对于暂存区中变化的内容
git reset HEAD <file name>
将暂存区中修改的内容迁移到工作区
如果在开发途中需要修改其它分支的内容,或者某一时刻,开发工作没有完成,但是需要中断,不好的做法是先提交,但应当注意的是:提交的内容应该是正确且可运行的代码,如果没有开发完成,可以先暂时保存起来,这个时候就用到了
git stash
,表示将当前代码和状态临时保存。
git stash save '<name>'
给保存现场起个别名
git list
展示当前所有保存现场信息
git checkout -b <local branch> origin/<remote branch>
在本地新建并检出分支对应到远程分支
git checkout --track origin <remote branch>
如果本地分支和远程分支保持一致,可以这样简写
从保存现场恢复
git stash pop
从保存的现场中恢复并且删除保存信息git stash apply
从保存的现场中恢复,但是保留现场信息。如果要删除保存信息的话,需要收到调用git stash drop stash@{<编号>}
删除git stash apply stash@{<编号>}
恢复指定编号的保存的现场信息
标签Tag
标签有两种:轻量级标签(light weight)与带有附注标签(annotated)
git tag
查看所有标签git tag -l '<title>'
查找标签名称,支持通配符git tag v1.0
创建一个轻量级标签git tag -a v1.1 -m '<message>'
创建一个带有附注的标签git push origin <tag>
推送标签git push origin <tag1> <tag2> ...
同时推送多个标签git push origin --tags
将本地所有未推送的标签推送到远端分支git show <tag>
查看特定标签的详细信息git tag -d <tag name>
删除标签git push origin :refs/tags/<tag>
删除远程指定分支(将一个空的标签覆盖远程标签,和删除远程分支类似)git push origin --delete tag <tag name>
删除远程标签git push origin refs/tags/<tag>:refs/tags/<tag>
将本地标签推送到远程的完成写法
tag
并不与分支挂钩,当在a分支打上标签之后,如果切换到b分支(a、b分支已经合并),那么也是可以看到已经打上的标签的
diff
git diff
比较工作区与暂存区的差异git diff <commit id>
比较工作区与指定提交记录之间的差异git diff --cached <commit id>
比较暂存区与版本库中指定提交记录之间的差异
远程仓库操作
pull
pull
操作是将远程代码拉取到本地,然后与本地代码合并,相当于是执行了 fetch
和 merge
两个操作
push
push
推送本地代码到远程仓库
push到全写是:
git push origin <local branch>:<remote branch>
git push -u origin master
这里的
-u
作用是将本地的master
分支与远程的master
分支关联,下次再提交的时候就不需要指定远程仓库的分支了,直接执行git push
即可,如果不用-u
的话,需要执行git push origin master
git remote add origin <remote branch>
将本地仓库与远程仓库关联,这里的
origin
表示后面远程仓库地址的别名,这样以后就用origin
来表示远程地址。本地仓库可以与多个远程仓库地址关联,如果有多个远程仓库的话,就不能都是用origin
别名了,每个远程仓库对应一个别名
git remote show
展示与本地仓库关联的所有远程仓库
git remote show <remote repository>
展示指定别名的远程仓库详细信息
更改远程仓库地址
有时远程仓库地址可能发生改变,这个时候就需要修改远程地址
- 查看远程仓库地址:
git remote -v
- 修改远程仓库地址:
git remote set-url origin <new url>
git别名
因为git的一些命令很长而且不好记忆,可以自定义一些容易记忆的别名:
git config --global alias.co checkout
将git co
代替git checkout
git config --global alias.unstage 'reset HEAD'
git unstage
代替git reset HEAD
submodule
如果代码仓库A引用了另一个代码仓库B,当B仓库发生更新之后,为了可以让仓库A及时更新,这里引用了 submodule
# local path 必须是本地不存在的文件夹,不然的话会报错
git submodule add <remote repository> <local path>
当仓库B的代码发生变化之后,在仓库A之后进入引用仓库所在的目录,执行 git pull
即可拉取仓库B的更新
如果仓库A引用了多个仓库的话,上面的方式显得太繁琐,可以在仓库A的根目录下执行:
git submodule foreach git pull
如果要全新 clone
仓库A的话,git clone <remote repository> <local path>
,因为仓库A引用了仓库B,所以 clone
下来的代码中会有对仓库B的引用关系,但是并不会 clone
下来仓库B的代码,如果要下载下来仓库B的代码,需要执行以下两个命令:
git submodule init
初始化引用仓库git submodule update --recursice
递归更新引用仓库
上面的执行方式太过繁琐,可以在执行 clone
的时候一并拉取引用仓库的代码:
git clone <remote repository> <local path> --recursice
如果要删除引用的仓库,没有直接命令可以删除,需要通过以下三个组合命令删除:
- 将
submodule
从缓存区删除:git rm --cache <submodule directory>
- 将
submodule
的实体文件从工作区删除:rm -rf <submodule local path>
- 将
.gitmodules
目录删除:rm -rf .gitmodules
subtree
subtree
和 submodule
解决的问题一样,就是仓库引用问题,但是因为 submodule
存在弊端:父子仓库都可以更新子仓库中的代码,删除引用繁杂等,所以就引入了 subtree
添加 subtree
步骤:
- 添加引用仓库的远程引用
- 关联引用仓库等远程引用
# 添加远程仓库B的引用
git remote add subtree-origin <remote repository B>
# 将远程仓库B关联到subtree,存放地址是subtree,使用的是master分支,
# --squash 参数是将B仓库的提交合并,
# 如果不使用该参数的话,查看仓库A的提交记录的话,会包含仓库B的提交记录
git subtree add --prefix=subtree subtree-origin master --squash
subtree
添加关联仓库之后,多出来的文件夹中包含的就是引用仓库的代码,这个和 submodule
不一样,submodule
多出来的文件夹,点击之后是跳转到引用仓库的地址,并不包含文件
cherry-pick
如果要将某个分支的更改应用到另一个分支上(本地分支),这个时候就需要使用 cherry-pick
了
git cheery-pick <commit id>
补充信息
git blame <文件名> 查看指定文件的历史修改
git commit --amend -m '提示信息'
git rm 删除文件和使用操作系统的删除文件是有一点区别的:
# git rm 删除文件相当于是先调用操作系统的删除文件,然后操作添加到暂存区,如果要恢复到话,需要先执行 git reset HEAD <文件名> ,然后执行 git checkout <文件名>
# 操作系统的删除文件,只是删除了文件,并没有添加到暂存区,所以只需要执行 git checkout <文件名> 就可以了
评论区