git总结
2021-06-11 18:10:46 0 举报
AI智能生成
为你推荐
查看更多
全手打,超详细Git总结,面试和日常使用常见问题总结。
作者其他创作
大纲/内容
git
本地
帮助文档
git branch --help
仓库管理
用户名邮箱
内容管理
工作区-暂存区 内容管理 add
git add .\t将工作空间下所有文件添加到暂存区(new,modifyed)
git add -A\t将工作空间下所有文件添加到暂存区(new,modifyed,delete)
git add -u\t将工作空间下所有文件添加到暂存区(modifyed,delete)
暂存区-本地仓库 内容管理 commit
git commit -m <commit message>\t将暂存区的文件提交到版本库
工作区-本地仓库 内容管理
git commit -am <commit message>\t跳过git add 命令,直接将工作区所有已跟踪的文件提交到版本库,未跟踪的(untracked)文件不能使用该命令
版本回退,撤销操作
暂存区恢复成本地仓库
当前文件以及暂存
之后变成了未暂存
git reset HEAD --filename\t拉取最近一次提交到版本库中的文件到暂存区,该操作不影响工作区
工作区恢复成暂存区
其中dswq是文件的名字,此时暂存区和工作区都是有文件的,所以讲暂存区的文件恢复到工作区
工作区恢复成本地仓库
注意只能是已经被跟踪的文件,没有跟踪的话直接删除就行了
HEAD^^
HEAD~2
也可以是commit号码
总结
reset来自版本库
git reset --option 版本号
--hard\t硬回滚(不可逆的),即暂存区,工作区全部用指定提交版本的目录树替换掉
--mixed\tmixed或不使用参数,覆盖暂存区,但不覆盖工作区
--soft\t软回滚,不进行暂存区和工作区的覆盖
重要
checkout来自暂存区
不再追踪
git rm --cached config/db/db.sql
修改远程push一下就好
回滚文件
git restore file
本地版本库的文件的删除
使用git删除而不是手动,省略了add工作区的也会删除
只是省略了add ,还是要我们自己commit
修改commit message
git commit --amend修改提交的commit
本地版本库的文件的重命名
使用git重命名而不是手动,省略了add
差异比较 git diff
内容解析
紧急修复
当前的test已经做了修改,但是因为没写好所以不想add commit
使用stash暂存起来,到stash栈里面
之后新建分支做修改
查看stash栈里面 的内容
取出来不删除stash内容
git stash apple --index\t恢复之前暂存的某个记录
git stash drop --index\t删除某个暂存记录
git stash drop stash@{1}
git stash apply stash@{1}
分支管理
新建分支
新建分支并且切换
切换分支
切换已经存在的分支
查询分支
v:展示sha1以及提交信息a:展示本地+远程
查看分支来自哪一个分支\tgit reflog --date=local | grep <branchname>
删除分支
删除存在的分支
-D 的时候是强制删除,即使没有保存的内容
修改分支名字
提交了错误的内容要回滚
假设最上面两次是错误的要撤销的
使用分离头指针,指向要恢复到达的分支
查看当前分支的情况
直接删除dev分支
新建dev分支
可以看到是自己恢复的分支
合并分支
merge到自己的分支
在master 合并 dev 分支
强制使用递归三路合并到当前的分支不会使用fastforward。就会多出来一个commitID
最终没有共同祖先会冲突三个点的内容得到最终结果,
分支都有同一个修改时,merge冲突
diff 类似
解决之后需要add 一下,再commit一下
squash merge优美commit log
--squash用于新分支开发一个功能后,合并的时候会将所有的修改放在暂存区,我们还要commit一下就可以了
参考链接
rebase到别人尾部变基衍合
在dev分支,变基到master尾部,之后在master直接merge dev 就是fastforward,看到变基的时候冲突了
解决之后按照提示要add 之后不是commit而是continue,可以看到上面又冲突了,所以再次处理,再次add,
再次执行continue,可以看到上面是有个分离头指针的过程,其实就是变基的时候是新建的commit,和之前的dev是没有关系的之后又会删除现在dev,将dev指向现在的分离头指针,所以就把分离头指针变得不分离了
可以看到最后dev就是指向了分离头指针的commit id
git rebase --abort看提示就知道会回到最开始没变基的时候
注意变基之后,dev分支原来的commit将会变成垃圾等待gc,二新接在尾部的commit则不会
分支提交信息修改,也可以使用变基实现:git rebase -i 父亲commit号
分支上的某一个提交转移到另一个分支cherry-pick所有的提交转移到另一个分支就是merge变基的本质和cherry-pick类似
假设当前的第一个分支应该在master上commit而不是dev上commit直接切换到master,使用cherry-pick将对应commitid拿过来
日志使用
记录的是操作日志而不是提交日志,一般会在git reset版本回退的时候使用
.gitignore
忽略文件夹
tmp/
忽略tmp目录下的所有文件
忽略一个文件
只忽略当前目录的
/test
只忽略下(下)一级目录的这个文件
tmp/*.txt
不会忽略tmp/ut/*.txt
tmp/*/*.txt
忽略所有目录下的这个文件
tmp/**/*.txt
忽略但是这个除外
!*.tmp
标签管理
新增标签
简单标签
有注释的标签
删除标签
查看标签
标签不和分支挂钩,指向了一个特定的ID
远程
总结:本地新建一个仓库,如何和远程仓库关联
直接添加remote origin
git pull origin
可以看到本地是没有分支的,只是本地会多出来origin/*会把远程所有的分支都拉回来,但是不会在本地新建,
没有-b参数,默认使用的分支名字就是远程的名字,就是refspec中的远程的名字
指定本地的分支名字,同时追踪远程的分支
git pull origin src:dest会创建一个新的分支
注意
本地init仓库最好有文件,然后创建一个分支之后,先add之后,再添加远程的已经存在的分支追加,不然各种fatal
配置remote源
基于ssh
ssh-keygen将自己的公钥放到GitHub
注意GitHub的公钥已经在我们连接的时候写yes的时候放到了本地
基于http
git remote add origin https://****.git
git remote show
git remote show 某一个具体的远程源
删除远程源
远程分支管理
本地有Git仓库,远程新建状态(推荐)
git remote add origin git地址
git push origin dev:dev
本地有仓库远程有仓库,合并
只能使用强制合并
git branch --set-upstream-to=origin/remote_branch your_branch
拉取的时候要允许不相关的历史合并git pull origin master --allow-unrelated-histories
本地已有分支关联已经存在的远程分支
git branch -a 保证远程分支的信息在本地有了,就是使用git fetch拉取下来了
最好不要这样做,因为会导致不同根的历史,在GitHub上面是按照PR来处理的也就是每次提交的时候都会生成一个PR去处理相当于本地自己变成了第三方作者了
push
推送一个远程不存在的分支并关联
-u 表示做一个关联,以后直接使用git push 本地src:远程dest
一样的
推送已经关联的存在的分支
删除远程分支
方法一:删除远程分支:相当于是本地空的推送到远程
方法二:删除远程分支
修改远程分支的名字
删除远程分支之后修改本地分支名字之后再推送
pull
没有关联的时候这句话只会在本地新建origin/*,不会自己新建本地分支关联
新建一个本地分支追踪远程存在的分支
没有关联的时候这句话只会在本地新建origin/master,不会拉取别的远程分支而且会新建本地分支和远程关联
remotes/origin/test已经使用pull拉取下来了
git fetch\t
git fetch origin dev\t\t获取远程dev分支但不做合并
远程分支被删除,更新本地分支信息
本地远程分支origin/test删除了,但是本地test分支还在
远程标签管理
推送标签
推送两个标签
推送所有的标签
git push origin refs/tags/v7.0:refs/tags/v7.0
获取远程标签
直接pull就可以获取所有的标签
获取远程的某一个标签
删除远程标签
标签删除语法
相当于一个空的标签推动上去
多人协作
Gitflow
基于Git分支的开发模型
develop分支
test分支
master分支
merge自test分支
bugfix分支
本地会有一个叫origin/master分支,用来追踪远程分支,push的时候不仅仅是提交,还要更新这个的指向,系统自己改变,我们不能操作
多模块
submodule
首先是要将子模块加到本地的父目录child-module文件夹要求不存在外层和内层是两个独立的仓库
拉取自动add,需要我们commit
push之后,点击子模块,自动到达子仓库
拉取所有子模块的更新
移除submodule
使用git 删除子模块,帮助我们自动add
可以看到需要手动删除本地的文件,以及commit一下删除的操作
删除本地文件还需要commit一下删除动作,之后push上去就删除了
新成员拉取有子模块的项目
可以在clone的时候直接使用 --recursive
git clone 不使用--recursive,module是没有文件的,需要初始化一下git submodule init
执行一下更新 git submodule update --recursive
subtree 支持双向修改
添加在模块的地址
首次add子模块
-P 即是--prefix=后面是文件夹之后是子模块对应的源之后是拉取的分支之后是使用的模式,subtree多个提交合并在一起,一个全新的提交,防止污染主仓库的时间线然后再merge。2个log操作人都是自己
正常使用时候的pull
--prefix=subtree 可以替换为 -P subtree--squash不能省略,要使用什么就统一,这个结果就是只有父模块的提交者,子模块的提交者被覆盖了
直接在父模块修改子模块的内容
父模块commit之后git push到父亲仓库
还要将修改推送到子仓库push subtree这个文件夹远程源是subtree-origin要推送的分支的是master
为什么会出现冲突:因为此时三方合并的时候除了共同祖先的,还有自己的祖先,找到最开始的地方其实是两个开始
原理
区域划分
工作区
暂存区
版本库
文件的五种状态
未被追踪的
文件暂存状态staged
文件入库未修改
文件入库已修改
stashed状态
Git的四种对象
blob对象
binary large object经过压缩后的内容
每次 add 以后,git 就会对你修改了的文件生成一个 blob 对象,文件的不同版本也会是一个 blob 对象
tree对象
项目目录结构在 Git 中,不会保存每个文件夹(tree 对象其实类似于一个文件夹的作用,如果指向根文件,那么当前所有文件的状态就相当于都知道了。)为了记录文件之间的关系,会用 tree 对象来表示这种关系。
commit对象
对目标的 Git 对象进行sha-1哈希算法的计算,得到一个哈希值,目的是为了避免不同的文件得到相同的结果,从而在 Git 的记录中出现冲突。
Git的工作原理是创建文件快照,而不是像其他VCS那样增加差异。
parent\t指向上一个commit Object
author/commiter
commit message
tag对象
分离头指针(游离HEAD)
git checkout 4esds
git checkout master
commit 之后,切换回原来的分支之后当前的修改不会生效,所以使用实验的
想要保留下来,可以使用对应的commitid新建一个分支,就是git checkout newbranch commitid
.git
objects
Git的四种对象都在这里
接下来用 git cat-file 命令来查看这个对象的内容: -t 表示查看这个对象的类型,是一个commit类型的提交
git cat-file -p HEAD/唯一ID
git cat-file -t HEAD/唯一ID
-p 表示查看里面的内容指向一个tree对象,指向一个parent对象(也就是前一次commit),以及commit的作者和提交者
查看所指向的tree的类型就是tree。。。废话
查看tree的内容blob 对象就是我们的 ds和sd 文件
对一个 blob 对象,也可以用 git cat-file 对象加上 -p 参数来还原其中的内容
git会创建一个commit对象,并且将这个commit对象的parent指针设置为HEAD所指向的引用的Sha-1
每次提交存放的文件,二进制文件,gc之后全放到pack文件夹
refspec(refs目录)
默认,在git remote add的时候会自动生成,获取远端的refs/head下的所有引用,放到本地的refs/remote/origin目录下。
config里面配置的refspec,其实就是一个引用,说明去哪里获取数据我们最终pull push写或者不写refspec其实都用的是这个文件夹指定的,只是git把我们简化的写法格式化了
refs 文件中还有三个文件夹,分别保存了:heads存放分支的信息,remotes 的一个远程就是一个文件夹,里面存放的是远程分支在本地的映射,以及 tags 的信息
上面的分支内容就是一个sha-1值,也就是某一个commit的id,查看对应的内容就是一个commit
开发的时候,尽量每个功能都开一个分支,这样子在后续进行提交,回退,做某些修改的时候,都会很方便,不用担心影响到其它工作分支毕竟分支的代价就是40字节的指针
分支
tag
有注释的时候回生成一个tag对象,指向commitid
HEAD
这个文件保存的不是commitID(sha-1),而是指向某个提交的指针放分支的 refs/heads 文件夹当中的某个分支
ORIG_HEAD
远程分支的sha-1值
不常用的命令
git 裸库
没有工作区,一般在服务器
git init --bare
垃圾回收
git gc
将refs目录下的文件打包到packed-refs
查看当前的文件修改的作者是谁
git blame 1.txt
查看所有的人的操作
git reflog
查看当前的头指针
cat .git/HEAD
解决ssh没有颜色
回到上一次的目录
cd -
0 条评论
回复 删除
下一页