获得版本库
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~1git 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 checkoutgit 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 <文件名> 就可以了
评论区