Git常见问题
模板
1.远程仓库新建分支,本地没有怎么处理?
问题描述:远程仓库新建分支,本地没有
标签:[可选]
解决办法:git remote update origin --prune
解决办法描述:刷新
常用名词
branchName:分支名
localBranchName:本地分支名
remoteBranchName: 远程分支名
commitId:提交记录ID
1.远程仓库新建分支,本地没有怎么处理?
描述:远程仓库新建分支,本地没有
标签:
解决办法:git remote update origin --prune
解决办法描述:更新本地缓存的远程分支列表
更近一步:
2.远程仓库删除的分支,本地缓存的remote信息仍然存在,怎么处理?
问题描述:-
标签:
解决办法:git remote prune
解决办法描述:移除本地缓存
3.git push的几种常见写法
-
git push origin localBranchName : remoteBranchName
origin 是远程主机的别称,主机别称是可以设置的
localBranchName是本地分支名
remoteBranchName是远程分支名
-
git push origin localBranchName(省略远程分支名)
将本地分支推送到与之关联的远程分支上(通常同名),若远程分支不存在则新建
-
git push origin : remoteBranchName(省略本地分支名)
将本地不存在的分支推动到远程分支上,等同于删除远程分支(git push origin --delete master)
-
git push origin(省略本地分支名、远程分支名)
将当前分支,推送到与之存在追踪关系的远程分支
-
git push(省略远程主机、本地分支名、远程分支名)
如果当前分支只有一个远程分支,则远程主机名也可省略
-
其他用法
-
git push -u orgin localBranchName
为本地分支制定默认的远程主机,这样git push若没添加其他参数时会推送到默认主机上的存在追踪关系的分支
git push --all origin
git push --force origin
git push origin --tags
-
-
关于 refs/for和refs/heads
refs/for推送后需要经过code review才能merge,而refs/heads不需要
4.git checkout的骚功能
-
git checkout -b local_branchName
从当前分支检出新分支,并切换过去
local_branchName 新的本地分支名
-
git checkout -b local_branchName remote_name/remote_branch_name
从指定的远程分支检出新分支,并切换过去
local_branchName 本地分支名
remote_name 远程地址别称
remote_branch_name 远程分支名
5.git merge和代码冲突
参考https://blog.csdn.net/qq_27905183/article/details/78575247
git merge branchName 合并分支【branchName】到当前分支
git pull 拉取并合并当前分支对应的远程分支
-
自动合并,不会产生冲突
1.修改不同的文件
2.修改同一文件不同的地方
3.同时更改文件名和文件内容(慎用)
-
合并产生冲突,手动解决
- git status 提示共同修改的文件
- git ls-files -s 输出文件冲突状态,第二列的值,0表示没有冲突,1表示两个用户之前共同版本对应的内容,2表示当前用户对应的文件,3表示合并后的文件对应的远程版本
- git show :n:filename 其中n是上面提到的数字,filename是文件名,该命令用于展示对应版本的内容
- 手动解决冲突,然后手动add、commit、push就可以了。这里注意对应的冲突文件内容已经改变,冲突区域会同时存在当前版本和远程版本的内容,一般用<<<<<< >>>>>>>>>>>包裹
- 除了以上命令方式解决,还可以选择git内置图形化界面,一般会显示3个区域
树冲突
6.git 对比两个分支的异同
参考 https://www.cnblogs.com/mkl34367803/p/9196563.html
7.Git使用git stash相关命令
冲突错误日志:commit your changes or stash them before you can merge
原因:出现这个问题的原因是其他人修改了xxx.file并提交到版本库中去了,而你本地也修改了xxx.file,这时候你进行git pull操作就好出现冲突了,解决方法,在上面的提示中也说的很明确了。
解决办法:
直接commit本地修改
-
使用git stash相关命令
git stash git pull git stash pop
-
通过git stash将工作区恢复到上次提交的内容,同时备份本地所做的修改,之后就可以正常git pull了,git pull完成后,执行git stash pop将之前本地做的修改应用到当前工作区。
git stash: 备份当前的工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时,将当前的工作区内容保存到Git栈中。
git stash save <message>
git stash pop: 从Git栈中读取最近一次保存的内容,恢复工作区的相关内容。由于可能存在多个Stash的内容,所以用栈来管理,pop会从最近的一个stash中读取内容并恢复。
git stash list: 显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。
git stash clear: 清空Git栈。此时使用gitg等图形化工具会发现,原来stash的哪些节点都消失了。
-
-
补充
- git stash pop [--index] [stash_id] 弹出最新进度到工作区,可指定index或stash_id
- git stash apply [--index] [stash_id] 除了不删除恢复的进度之外和git stash pop命令一样
- git stash drop[stash_id] 删除一个存储进度,如果不指定stash_id,则默认删除最新的存储进度
- git clear 删除所有存储的进度
8.Git删除分支
-
git删除本地分支
git branch -d <local branchName>
未合并的分支不会删除,会警报
-
删除远程分支
git push origin --delete < remote branchName>
-
删除本地分支,强制
git branch -D <local branchName>
-
批量删除本地分支
-
删除当前分支外的所有分支
git branch | xargs git branch -d
-
删除包含指定字符的分支
git branch | grep 'dev*' | xargs git branch -d
-
9.Git游离态(detached HEAD)
HEAD没有指向任何分支,严谨的说是HEAD指向了一个没有分支名字的修订版本,此时称为处于游离态,commit操作不会提交到任何分支上去。
此时需要进行下列操作完成代码提交与合并
创建临时新分支
git branch <tempBranch> <commitId>
切换到工作分支
git checkout <work branchName>
合并临时分支到工作分支:
git merge <temp branchName>
删除临时分支
git branch -d <temp branchName>
10.Git分之重命名
先将本地分支重命名
git branch -m oldBranch newBranch
删除远程分支(远端无此分支则跳过该步骤)
git push --delete origin oldBranch
将重命名后的分支推到远端
git push origin newBranch
把修改后的本地分支与远程分支关联
git branch --set-upstream-to origin/newBranch
11.Git撤销提交
本地撤销上一次提交(未push过的提交),代码仍在,可继续提交
git reset --soft HEAD^
- 可选参数说明
- --soft:不删除工作空间改动代码,撤销commit,不撤销git add .
- --mixed:不删除工作空间改动代码,撤销commit,并且撤销git add .
- --hard:删除工作空间改动代码,撤销commit,撤销git add .
- 关于 HEAD^
-
HEAD^
指上一个版本,可以使用HEAD^^
或直接指定commit_id
,或使用HEAD~3
意思是指定倒数第三个版本
-
12.Git commit注释修改
git commit --amend
- 会弹出vim编辑器,修改后保存即可
git commit rebase
git commit reset
13.Git 修改远程仓库地址
获取远程仓库地址
git remote get-url <name>
- name:一般是origin
- 可选项
- --push:
- --all:
修改远程仓库地址
git remote set-url <name>
14.Git对应多个远程仓库常用操作
- 查看远程仓库信息
git remote -v
- 添加、删除或修改远程仓库
- pull和push的时候区分操作
15.git switch 和 git restore 对原有git checkout进行职责分离
- git switch <branchName> 切换分支
- git switch -c <branchName> 创建并切换分支,与旧命令 git checkout -b <branchName> 效果相同
- git restore <filePath> 撤销,与旧命名 git checkout <filePath> 效果相同
16. 忘记代码在哪个分支的操作流程
-
查看历史版本操作记录,找到提交记录,找到commitId
git reflog
git log是显示当前的HEAD和它的祖先的,递归是沿着当前指针的父亲,父亲的父亲,…,这样的原则。
git reflog根本不遍历HEAD的祖先。它是HEAD所指向的一个顺序的提交列表:它的undo历史。reflog并不是repo(仓库)的一部分,它单独存储,而且不包含在pushes,fetches或者clones里面,它纯属是本地的。
reflog可以很好地帮助你恢复你误操作的数据,例如你错误地reset了一个旧的提交,或者rebase,…,这个时候你可以使用reflog去查看在误操作之前的信息,并且使用git reset --hard 去恢复之前的状态。- git reflog [show] [log-options] [<ref>]
- git reflog expire [--expire=<time>] [--expire-unreachable=<time>] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all | <refs>…]
- git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] ref@{specifier}…
- git reflog exists <ref>
git log 和 git reflog 日志范围 -
查询commitId所属分支
git branch --contains <commitId>
-
可选操作,commit记录无法找到所属分支,可以创建一个临时分支
git btranch <localBranchName> <commitId> // 创建新分支 git checkout <commitId> -b <localBranchName> // 创建新分支并切换到新分支
原理篇
1.git中说的快照是什么?
git的commit就等同于保存了一次快照。
git的快照如何进行?
git会读取当前工作空间的所有数据,进行数据预存,再重新调整。它会和上一次的快照版本的内容进行比较,对于没有改变的文件数据,git会把当前预存中冗余文件的数据去除掉,改为保留指向上一个版本中该文件数据的指针,对于有差异的文件数据就会保留下来,最终再把数据完整保存下来,这才算是执行了一次快照。
2. .git目录下的文件有哪些,有什么作用?
综述:
- objects文件夹
git仓库初始化后,会生.git
文件夹作为git数据库。add操作后会在objects目录下生成对象,此时生成文件对象类型为blob
,内容是我们编写的代码;
commit操作后会继续生成新的对象,此时生成文件的对象类型为tree
,内容为之前add的文件的sha1哈希码,换言之就是我们的代码文件目录;
同时commit操作会生成文件类型为commit
类型的对象,里面记录了提交信息,如下图所示。
- refs文件夹
我们一个项目一般有多个分支,那么我们的分支信息在哪里保存呢,答案是在refs文件夹下,以及HEAD等文件。
在Git仓库里面,HEAD、分支、普通的Tag可以简单的理解成是一个指针,指向对应commit的SHA1值。