git 常见问题记录

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对应多个远程仓库常用操作

  1. 查看远程仓库信息
git remote -v
  1. 添加、删除或修改远程仓库
  2. pull和push的时候区分操作

15.git switch 和 git restore 对原有git checkout进行职责分离

  1. git switch <branchName> 切换分支
  2. git switch -c <branchName> 创建并切换分支,与旧命令 git checkout -b <branchName> 效果相同
  3. git restore <filePath> 撤销,与旧命名 git checkout <filePath> 效果相同

16. 忘记代码在哪个分支的操作流程

  1. 查看历史版本操作记录,找到提交记录,找到commitId

    git reflog 
    

    git log是显示当前的HEAD和它的祖先的,递归是沿着当前指针的父亲,父亲的父亲,…,这样的原则。
    git reflog根本不遍历HEAD的祖先。它是HEAD所指向的一个顺序的提交列表:它的undo历史。reflog并不是repo(仓库)的一部分,它单独存储,而且不包含在pushes,fetches或者clones里面,它纯属是本地的。
    reflog可以很好地帮助你恢复你误操作的数据,例如你错误地reset了一个旧的提交,或者rebase,…,这个时候你可以使用reflog去查看在误操作之前的信息,并且使用git reset --hard 去恢复之前的状态。

    1. git reflog [show] [log-options] [<ref>]
    2. git reflog expire [--expire=<time>] [--expire-unreachable=<time>] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all | <refs>…]
    3. git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] ref@{specifier}…
    4. git reflog exists <ref>
    git log 和 git reflog 日志范围
  2. 查询commitId所属分支

    git branch --contains <commitId>
    
  3. 可选操作,commit记录无法找到所属分支,可以创建一个临时分支

    git btranch <localBranchName> <commitId>  // 创建新分支
    git checkout <commitId> -b <localBranchName> // 创建新分支并切换到新分支
    

原理篇

1.git中说的快照是什么?

git的commit就等同于保存了一次快照。

git的快照如何进行?

git会读取当前工作空间的所有数据,进行数据预存,再重新调整。它会和上一次的快照版本的内容进行比较,对于没有改变的文件数据,git会把当前预存中冗余文件的数据去除掉,改为保留指向上一个版本中该文件数据的指针,对于有差异的文件数据就会保留下来,最终再把数据完整保存下来,这才算是执行了一次快照。

2. .git目录下的文件有哪些,有什么作用?

image-20210818100812664.png

综述:

  1. objects文件夹

git仓库初始化后,会生.git文件夹作为git数据库。add操作后会在objects目录下生成对象,此时生成文件对象类型为blob,内容是我们编写的代码;

commit操作后会继续生成新的对象,此时生成文件的对象类型为tree,内容为之前add的文件的sha1哈希码,换言之就是我们的代码文件目录;

同时commit操作会生成文件类型为commit类型的对象,里面记录了提交信息,如下图所示。

image-20210818103406355.png
  1. refs文件夹

我们一个项目一般有多个分支,那么我们的分支信息在哪里保存呢,答案是在refs文件夹下,以及HEAD等文件。

在Git仓库里面,HEAD、分支、普通的Tag可以简单的理解成是一个指针,指向对应commit的SHA1值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容