文章目录
git学习笔记
1. commit id分析
git的提交ID(commit_id)是一个摘要值,这个摘要值实际上是个SHA1计算出来的。
SVN集中式版本控制系统,只有1份代码,因此提交ID是递增的数字来表示。而git是分布式版本控制系统,有多份代码,无法通过递增的数字来表示提交ID。
2. git基本信息:user.name与user.email
对于user.name和user.email来说,有三个地方可以设置:
- /etc/gitconfig(几乎不会使用),
git config --system
- ~/.gitconfig(很常用),
git config --global
- 针对于特定项目的,git/config文件中,
git config --local
使用方式如下:
git config --global user.name "kevin"
或者 git config --global user.email "kevin@git.com"
3. git文件之.gitignore文件
.gitignore文件有一些文件不想被git所进行版本控制,可以在根目录下手动创建一个.gitignore
文件,然后把不想被管理的文件全称(如:a.properties)写入其中,再把.gitignore
文件进行版本管理(add
,commit
)。这是git
所推荐的方式,当然也可以不新增.gitignore
文件,对于不想被管理的文件,就在每次add
的时候,不加入其,也是可以的,不过这种方式在实际开发中并不推荐。
.gitignore中使用全称是一种方式,当然也可以使用通配符等方式。
4. 标签Tag
标签有两种:轻量级标签(lightweight)与带有标注信息的标签(annotated)
创建一个轻量级标签:git tag v1.0.0
创建一个带有附注的标签:git tag -a v1.0.0 -m 'release version'
删除标签:git tag -d v1.0.0
查看标签列表:git tag
查看标签详情:git show v1.0.0
将标签推送到远端:
git push origin v1.0 v2.0
多个标签一并推送到远端git push origin --tags
本地尚未推送的标签一并推送到远端git push origin refs/tags/v6.0:refs/tags/v6.0
标签推送到远端的命令完整形态
删除远程标签:
git push origin : refs/tags/v6.0
本地推动一个空标签到远程v6.0上,相当于删除远程标签v6.0git push origin --delete tag v6.0
删除远程标签推荐的命令方式
5. 本地分支与远程分支
5.1 本地分支与远程分支关联
git push --set-upstream origin develop
将本地的develop分支推送到远程,并且在远程建立一个与本地develop关联的develop分支
git checkout -b develop origin/develop
创建并且切换到develop分支(基于本地远程分支origin/develop)
git checkout --track origin/develop
创建并且切换到develop分支(基于本地远程分支origin/develop)
说明:
git checkout --track origin/develop 是git checkout -b develop origin/develop的特殊情况,前者远程分支与本地分支名一样,后者可以不一样
git push --set-upstream origin develop 等价于git push -u origin develop
git push --set-upstream origin develop:develop2 完整写法, 分本地分支:远端分支,git push --set-upstream origin develop是本地分支与远端分支名一致的一种特殊情况
5.2 删除远程分支
git push完整写法: git push origin src:dest
git push origin :develop
本地空分支推送到远程develop上,也就把远程develop删除掉了
git push origin --delete develop
删除远程分支develop
6 git命令
常用的git命令:
git clone url 从url对应的地址克隆,使用远端的仓库名作为文件夹名
git clone url new_name 从url对应的地址克隆并且使用new_name作为克隆下来的文件夹名
git init git初始化,使用该命令后,就纳入git管理了
git add 添加,git add . 添加所有修改文件(当前目录以及其子目录),不包括.gitignore中忽略的文件
git commit 提交,-m为可选参数
git commit -am ‘message’ 等价于git add . 加上 git commit -m ‘message’,这种提交方式不适用于刚创建出来的文件,对于新建的文件还是需要使用原始的方式:git add和git commit来进行提交,当完成了初次的提交后,文件就可以使用git commit -am 'message’的方式了。
git commit --amend 对最新的提交,追加提交,不改变commit_id,-m为可选参数
git rm --cached 从缓存区中删除文件(可以将原本交给git管理的文件,摆脱git的管理)
git reset HEAD 将文件从暂存区恢复到工作区,等同于git restore --staged
git checkout – 将该文件从工作区中丢弃,即:将工作区中的修改丢弃
git restore --staged 将该文件从暂存区恢复到工作区,等同于git reset HEAD
git restore 将该文件从工作区中丢弃,即:将工作区中的修改丢弃,等同于git checkout –
git rm 删除文件,等价于 rm + git add
git mv 移动文件 等价于 mv + git add .
git log 查看日志
git log -n 查看最近的n条日志
git log --graph 以图形化的形式展示日志
git reflog 查看操作记录,log日志只能看当前点以及之前的日志,reflog可以看所有的操作记录
git reset --hard HEAD^ 回退到上一个版本,n个^就表示回退n个版本
git reset --hard HEAD~5 回退上5个版本是^的简化形式
git reset --hard commit_id 回退到当前commit_id所在的版本
git branch -av 列出所有分支信息,包括远程被追踪的分支信息,简写的SHA-1的commit_id
git branch -m master master2 对分支改名
git branch -d branch_name 根据分支名称,删除分支
git branch 查看分支列表
git stash list 查看存储(stash)的列表
git stash 不带信息的方式保存一个
git stash save ‘stash_message’ 带有信息的方式保存一个存储
git stash pop 将存储列表的第一个存储应用出来,并且删除存储列表中的第一个存储
git stash apply stash@{0} 将存储列表的第一个存储应用出来,0为index,可修改,如1表示存储列表中的第二个,该方式不会删除列表中对应的存储
git stash drop stash@{0} 删除存储列表中的第一个存储,0可修改
git blame file 查看文件修改信息
git diff:比较的是暂存区与工作区文件之间的差别
git diff HEAD(commit_id):比较的是最新的提交(特定的提交)与工作区之间的差别
git diff --cached:比较的是最新的提交与暂存区之间的差别
git push 推送,git push的完整命令:git push origin src:dest src指的是本地分支,dest指的是远端分支
git pull 拉取,同时会执行合并,git pull的完整命令:git pull origin src:dest src指的是远端分支,dest指的是本地分支
git pull = git fetch + git merge
git remote add origin url 新建一个别名,origin就代表url
git pull --rebase origin master 拉取远程origin的master到本地master,通过变基的方式合并
git push -u origin master 本地的master推送到远程origin的master上,并且将本地的master与远程的master进行关联,之后就可以使用git push进行推送了
git remote show 与本地仓库相关联的远程仓库列表,可以有多个远程仓库与之关联,等价于git remote
git remote show origin(远程仓库名) 展示远程仓库的详细信息以及本地与远程仓库的对应信息
git config --global alias.br branch 为branch起一个别名:br
7. 其他
7.1 HEAD
HEAD(.git目录下HEAD文件中可以看到所指向的当前分支)指向的是当前分支,master/dev指向的是提交。HEAD文件是一个指向当前所在分支的引用标识符,该文件内部不包含SHA-1值,而是一个指向另外一个引用的指针;当执行git commit命令时,git会创建一个commit对象,并且将这个commit对象的parent指针设置为HEAD所指向的引用的SHA-1值。对于HEAD修改的任何操作,都会被git reflog完整的记录下来,实际上,可以通过git底层命令symbolic-ref来实现对HEAD文件内容的修改。
7.2 fast-forward(快进)
如果可能,合并分支时git会使用fast-forward模式;
在这种模式下,删除分支时会丢掉分支信息;
合并分支时加上–no-ff参数会禁用fast-forward,这样会多出一个commit_id。命令为:git merge --no-ff dev
7.3 生成公钥和私钥命令
ssh-keygen
生成公钥和私钥,在使用SSH的方式时,需要用到。
7.4 查看远端分支历史记录
在缺省情况下,refspec会被git remote add命令所自动生成,git会获取远端上refs/heads下的所有引用,并将它们写到本地的refs/remote/origin目录下,所以,如果远端上有一个master分支,在本地就可以通过下面几种方式来访问它们的历史记录:
git log origin/master
git log remotes/origin/master
git log refs/remotes/origin/master
7.5 git submodule命令
git submodule add childSrc localFolder
将childSrc所对应的git仓库代码拉取到父项目的localFolder文件夹中,localFolder可以是有层次关系的文件夹,但是要求在执行该命令前,其是不存在的。
可以在localFolder中使用git pull
拉取该submodule的代码,也可以在根目录使用git submodule foreach git pull
,一次性把所有的子模块进行pull。
使用git clone
在parent所在的仓库进行克隆的时候,子模块默认是不会拉取下来的,需要在parent目录使用如下两个命令进行子模块的拉取:
git submodule init
git submodule update --recursive
上述两个命令可以在克隆的时候使用该命令代替:git clone src folder --recursive
,并且该命令也更加简洁
父项目中移除submodule项目的做法:
git rm --cached localFolder
从暂存区移除localFolderrm -rf localFolder
本地删除localFoldergit add .
git commit -m 'remove localFolder'
7.6 chery-pick命令
git cherry-pick commit_id
将该commit_id对应的修改,应用到当前分支
7.7 rebase命令
rebase变基/衍合。意即改变分支的根基。
- 从某种程度上来说,rebase与merge可以完成类似的工作,不过二者的工作方式有着显著的差异。
- merge会产生一个新的提交,其parent有两个,一个是待合并的提交点,一个是当前提交点
- merge不会修改git历史,rebase会修改git历史
rebase注意事项:
-
rebase过程中也会出现冲突
-
解决冲突后,使用git add添加,然后执git rebase --continue
-
接下来git会继续应用余下的补丁
-
任何时候都可以通过如下命令终止rebase,分支会恢复到rebase开始前的状态
git rebase --abort
-
不要对master分支执行rebase,否则会引起很多问题,一般来说,执行rebase的分支都是自己的本地分支,没有推送到远程版本库
7.8 基于git分支的开发模型
develop分支(供开发人员使用的一个分支,频繁变化的一个分支)
test分支(供测试与产品等人员使用的一个分支,变化不是特别频繁)
master分支(生产发布分支,变化非常少的一个分支)
bugfix(hotfix)分支(生产系统当中出现了紧急Bug,用于紧急修复的分支)
分支模型的流程:develop—>test—>master