Git

Git Questions and Answers

Git常见问题

Posted by Hao on September 29, 2021

Git常见问题

  • git error:invalid path 原因:大多是由于文件名格式不支持所至,NTFS有个路径保护机制,防止文件系统出错。If set to true, do not allow checkout of paths that would cause problems with the NTFS filesystem 解决方案: git config core.protectNTFS false

  • git merge后发现you need to resolve your current index first:
    1. 合并时遇到冲突,想取消git merge操作
      1
      
       git merge --abort
      
    2. 解决conflicts后再次执行merge操作
    3. Merge失败,冲突未解决。撤销merge申请,回退到merge之前
      1
      
      git reset --merge
      
  • git merge出现错误后,如何解决conflicts?

    1. 根据提示找到冲突的文件,解决冲突。如果文件有冲突,那么会有类似的标记
      1
      2
      3
      
      <<<<<<<到=======是在当前分支合并之前的文件内容
      =======到>>>>>>> psr/psr-02是在其它分支下修改的内容
      需要在这个两个版本中选择一个,然后把标记符号也要一起删除
      
    2. 修改完之后,执行git add <file_name>
    3. git commit进入vim界面,修改尝试合并的本次commit的log info
    4. 根据需要,选择推送到对应的远程仓库
  • git pull是更新所有分支还是只有当前分支?

    理论上等同于git fetch + git merge FETCH_HEAD,因此所有远程分支的信息会同步到本地,远程新建的branch也会同步到本地。同步只是指,本地知道远程分支当前有多少个commit领先于本地分支,以及在执行git branch -a时,能够看到当前有多少个远程分支。而当前所指分支,即FETCH_HEAD的分支会执行合并。

  • git pull后发现error: Your local changes to the following files would be overwritten by merge:
    1. 保留本地代码,并把git服务器上的代码pull到本地(将本地代码暂时封存)
      1
      2
      3
      
      git stash  //暂存代码
      git pull origin master  //获取远程仓库代码
      git stash pop  //释放本地的暂存代码
      
    2. 完全覆盖本地代码,只保留远程仓库代码
      1
      2
      
      git reset --hard
      git pull origin master
      

      或者

      1
      
      git pull origin master -f
      
  • 在两个不同的分支,且只想从指定的分支合并某个文件到另一个分支
    1. 使用git checkout完成该功能 在branch_A下运行命令git checkout branch_B message.html,之后可使用git state查询当前的提交情况。之后完成合并,使用git checkout某文件到当前分支时,会将当前分支的对应文件强行覆盖
    2. 通过merge进行合并,避免相同文件的强行覆盖 在A上创建分支A_temp,通过git merge将B分支合并到A_temp中,之后返回A分支,通过上面命令git checkout A_temp message.html文件来完成合并
  • 使用git merge mastergit rebase master进行分支合并的区别在哪里?

    git merge: 每当运行git merge时,都会创建一个额外的合并提交。git merge在不同分支下,是并线进行的

    git rebase: 它的原理是回到两个分支最近的共同祖先为起点,根据当前分支的历次提交快照,生成一系列文件补丁,然后往目标分支(基底分支)最后一次提交快照为新出发点,逐个应用提交快照,让当前分支直接继承目标分支。git rebase在不同的分支下,通过rebase之后,是单线穿行的。

  • Git mergetool的三个代码栏分别表示什么 上面三个窗口依次是“LOCAL”、“BASE”、“REMOTE”

  • 什么是upstream 当从GitHub上clone一个repo到本地时,如果没有明确声明是这个repo的contributor,此时不能向该repo执行pull请求,那么远程的repo对于本地的repo就是upstream。一个分支的upstream,其实就是与远程分支做关联,告诉git,默认此分支为推送及拉取的远程分支的信息。
    1
    2
    3
    4
    
     $ git push -u origin master (-u与--set-upstream等效)
     命令的含义是,推送master分支到远程origin仓库master分支,并且建立本地分支master的upstream为origin/master。
     $ git branch --unset-upstream
     取消当前分支的upstream
    
  • 如何解决 “Another git process seems to be running in this repository”?

    由于进程的同步互斥管理,是有资源上锁机制的,但是由于进程突然崩溃,未来得及解锁,导致其他进程访问不了。进入当前工作区目录下的隐藏文件夹.git中,可以看到有index.lock文件,只需要删除此文件,就可解决问题。

    1
    
      rm .git/index.lock
    
  • 使用git log等命令时,出现多行交互式阅读界面,如何退出?(原因需要进一步核实,存疑!)

    git打印时,使用的是vim编辑器的Ex模式,常见命令见vim编辑器,可以通过end命令阅读所有,Enter👇阅读下一行,通过:q进行退出,或使用Esc+ZZ的形式。

  • 当执行git commit后,如何修改log,以及在push之后如何修改log

    1. 只需要修改最新的一次commit注释:git commit --amend, 之后便可以利用vim来进行编辑注释。(vim可按i键进入编辑模式,esc退出编辑模式,ZZ保存并退出。更多操作可查阅vim相关资料)
    2. 修改历史提交注释(修改历史多次提交注释): 这时必须用到git rebase命令
    3. git rebase -i HEAD~X比如我想修改最近两条commit的注释,即输入git rebase -i HEAD~2
    4. 进入vim,修改需要编辑的commit,将前面的pick修改为edit
    5. 修改完成之后git log可以看到git的最后一次提交已经变成你修改为edit的那个注释了,这时再使用git commit --amend
    6. 修改完成后git rebase --continue
  • 问题背景:远程仓库有好多个分支,但是在本地使用git fetch之后,并不能获取到远程的分支信息,使用git branch -a也只能看到master分支(以及一个HEAD,指向master分支)

    问题原因:git clone –depth=1 的影响:git clone --depth=1的好处是限制 clone 的深度,不会下载 Git 协作的历史记录,这样可以大大加快克隆的速度。depth用于指定克隆深度,为1即表示只克隆最近一次commit

    git clone –depth=1后,如果我们想把其他远程分支(如test)也克隆到本地,我们需要用下面的命令:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    # 先将浅层转换为完整的存储库,消除浅层存储库所施加的所有限制。
    git pull --unshallow
    # 编辑 .git/config 文件,把 fetch 改成下面第二种形式,不要写死master。
    [remote "origin"]
          url = https://github.com/xxx/project.git
          fetch = +refs/heads/master:refs/remotes/origin/master
     
    [remote "origin"]
          url = https://github.com/xxx/project.git
          fetch = +refs/heads/*:refs/remotes/origin/*
    # 或者通过该命令修改
    git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
    
    // remote_branch_name  代表想要克隆的远程分支名字
    $ git remote set-branches origin remote_branch_name
    $ git fetch --depth 1 origin remote_branch_name
    $ git checkout remote_branch_name
      
    # 本地新建一个分支并和线上分支互通
    git checkout -b <本地分支名> <远程分支>
    // 例如
    git checkout -b test origin/test
    
  • Windows git “warning: LF will be replaced by CRLF” 解决方案: 避免git默认的自动换行转换

    1
    2
    3
    4
    
    git config --global core.autocrlf false
    true 自动完成标准化与转换
    input 只做标准化操作,不做转换操作
    false 提交与检出的代码都保持文件原有的换行符不变
    

    所以,一种规范换行符的方式是这样的:

    1
    2
    3
    4
    
    # 使用 Windows 系统的开发者设置:
    git config --global core.aurocrlf true
    # 使用 Linux/MacOS 的开发者设置:
    git config --global core.autocrlf input
    

    由于没有一个绝对有效的算法来判断一个文件是否为文本,所以Git 提供了一项禁止/警告不可逆转换的配置来防止错误的标准化与转换。它主要是影响到多种换行符混合的文件,我们可以手动将其转换为同一种换行符:

    1
    2
    3
    4
    
    git config --global core.safecrlf [true | false | warn]
    true 禁止提交混合换行符的文本文件(git add 的时候会被拦截,提示异常)
    warn 提交混合换行符的文本文件的时候发出警告,但是不会阻止 git add 操作
    false 不禁止提交混合换行符的文本文件(默认配置)
    

    附属问题:除了上面的问题,我们平常受到换行符问题的困扰更多来自协作开发工具,比如Git。有时候我们只改了源码中的一行,但提交的时候发现整个文件都被修改了。有时候拉取最新的分支,明明改动不大,但是在与本地合并的时候整个文件都是冲突。

    Linux下系统报错: $’\r’: command not found,此问题由CRLF引起

    • CRLF(carriage return line feed): “\r\n”, windows系统环境下的换行方式
    • LF(line feed): “\n”, Linux系统环境下的换行方式

Git附属内容介绍

Github Dependabot alerts 介绍

Github Dependabot 是一个github的工具,他可以帮助你检测你的repo, 并且做一些工作保证你repo的安全性。Dependabot可以为你repo做的事情主要分成三大类:

  • Keep all your dependencies updated: 实时检测你的repo,并keep你所有的dependency都能被updated
  • Detection of vulnerable dependencies send Dependabot alert:检测vulnerable dependencies并发出Dependabot alert
  • Stop using vulnerable dependencies and keep security updates: 帮助你停止使用有vulnerable的dependencies

Keep all your dependencies updated

Dependabot除了可以帮助我们处理漏洞以外,还有一个非常重要的作用,就是帮助我们检测我们所使用的dependency中是否有可以更新的版本,如果有,它也可以帮助我们实现自动更新。 在repo中enable了Dependabot之后,可以时刻的保证我们repo中使用的dependency都是up to date的

Reference

  1. Dependabot 介绍