在实际项目中git的基本使用方法

2,982 阅读11分钟

了解git的基本指令

在这一部分,我会列出一些在git中最常使用的命令,并解释它们的作用

想要将本地代码上传到远程仓库最基本的三条命令

  1. git add .

    将当前目录下修改的所有代码从工作区添加到暂存区.代表当前目录,进入待提交状态(Staged)

  2. git commit -m '这里写此次提交代码的注释'

    将暂存区的内容添加到本地仓库中,注意这一步并没有上传到远程仓库

  3. git push -u origin master

    将本地仓库中的内容推送到远程仓库的master分支上,origin就是远程仓库的意思,第一次使用需要加-u指令设置远程仓库的上流分支(这里的-u--set-upstream的简写),后续不需要再使用-u

这三条是最基本的将本地代码上传的指令,但在一个多人协同的项目开发过程中,很多时候,大家都是分工,把不同的模块交由不同的人去开发,当我们去开发一个新的功能时,为了不影响已经部署的项目正常运作,我们往往需要在远程仓库中新建分支,去开发自己的功能模块,每次上传代码也是上传到自己的分支

关于分支的命令

  1. git branch [branchName]

    本地创建新的分支,[branchName]为自己定义的分支名称

  2. git checkout [branchName]

    切换到[branchName]分支

    1,2两条命令也可以合成一个

    git checkout -b [branchName]

    如果本地没有该分支则新建并切换,有该分支则直接切换

  3. git branch

    查看本地仓库的分支,如果写成git branch -a 则是查看所有分支,包括本地和远程仓库

  4. git fetch

    获取远程仓库的内容,比如说查看远程仓库里的分支有哪些,但是不会将远程仓库的内容直接与本地内容合并,这是该命令与git pull的区别

  5. git pull <远程主机名> <远程分支名>:<本地分支名>

    若远程仓库的分支有所修改,可以使用该命令将分支拉到本地进行合并

项目中常见的问题及解决方法

本地创建的项目与远程已有仓库进行连接

使用场景

直接从别人的仓库下载代码压缩包,而非通过git clone的方式进行下载,此时不会将本地代码与远程仓库自动关联

解决步骤

  1. git init 创建本地仓库
  2. git remote add origin [远程仓库地址]
  3. 在本地创建一个分支,并让远程也有此分支(具体方法见下面)
  4. git add .
  5. git commit -m 'blabla'
  6. git push -u origin [远程的分支]

本地上传分支(远程仓库中没有该分支)到远程仓库的步骤

  1. 先创建或切换到一个分支 git checkout -b aaabranch

  2. 编写代码

  3. git add .

  4. git commit -m '这是第一次提交'

  5. 第一次上传分支时因为远程仓库中没有该分支,所以

    git push --set-upstream origin aaabranch

    --set-upstream origin就是指设置远程仓库中的上流分支

  6. 后续上传到该分支

    git push

从远程仓库拉取别人的分支

使用场景

比如说自己电脑上还没有该项目,但是想要下载某个开发版本的分支

解决步骤

  1. git init

  2. git remote add origin [远程仓库地址]

  3. 拉取别人的分支,首先要获取远程仓库有哪些分支

    git fetch

  4. 注意,不使用git fetch指令是无法拉取远程仓库中的分支的,因为git checkout通常来说都是切换本地里的分支,他不会想着切换远程仓库的分支,试想每次checkout都还要去访问远程仓库,这不符合git的设计理念,我们应该把代码的编写部分全部在本地完成,只有最后上传到远程仓库时,才会使用网络

  5. git checkout [remotebranch])

    此时切换分支,就可以切换远程仓库里的分支了(实际上就是把远程仓库里的分支当作模板复制到本地的分支上了)

  6. git pull

    直接拉取分支到本地仓库中

远程仓库的 dev 分支发生更新

使用场景

多人协作场景下,会遇到别人写好代码提交到主分支的情况(这里主分支是 dev),而我们此时在另一个分支开发功能,在我们上传功能到主分支的时候,需要先把 dev 分支上已有的更新拉取下来

解决步骤

  1. git merge origin/dev这一步是把远程主分支的代码拉到自己本地开发功能的分支上
  2. 解决可能存在的冲突,没有最好
  3. git push (此时上传到的是远程仓库中你所在的功能分支)
  4. 通过提 pr 提交到主分支 以上是一种保险的做法,你当然也可以直接在第三步使用 git push origin/dev 提交到 dev 分支

远程仓库的 dev 分支发生更新的第二种情况

使用场景

如果上面的方法无法拉取远程分支的更新,这个时候需要我们本地切换到主分支然后执行 git pull 操作,但在这时会有一个问题,一旦我们切换到了另一个分支,那么功能分支所有更新的内容都会被删除,这个时候使用 git push 也不是一个好的办法,因为功能还没有开发完成,所以有没有一种办法,可以把修改的部分储藏起来,等到需要用的时候再拿出来用呢,答案就是使用 git stash

需要注意的是 git stash 储存的是所有被跟踪的文件,如果一个文件之前从未使用过 git add 进行追踪,那么该文件不会被暂储,如果一个文件之前使用 git add 添加过追踪,那么修改了该文件之后,即使不使用 git add 把它的最新内容添加到暂存区,其修改的最新内容仍旧会被暂储,因为该文件处于已追踪状态

解决步骤

  1. git stash 先将本地修改的内容进行暂储
  2. git checkout dev 切换到本地 dev 分支
  3. git pull 拉取远程该分支中最新的内容
  4. git checkout [你自己的分支]
  5. git merge dev 将 dev 分支合并到你的分支
  6. git stash pop 将本地修改内容重新应用
  7. 功能完成后 git add,省略后面的步骤......

同时开发多个功能分支,切换分支时保留修改内容

使用场景

多个需求并行的情况下,有些时候可能出现,这个功能还没开发完成,但是另外一个需求优先级更高,需要先开发那个需求,这个时候就需要切换分支,但就会导致本地修改内容消失,解决步骤同上,不再重复叙述

git reset 的使用

使用场景

比方说你的分支上有个版本1,在版本1的基础上开发了新的版本2,然后你发现版本2有错误,现在想要修改版本2中的错误,那么你需要做的就是回退到版本1进行修改(注意回退到的版本是要修改版本的上一个版本),并且舍弃之前提交的版本2,上传一个新的版本2

使用方法

  1. git reset 什么都不加的情况,回退到对应版本,并且修改的部分仍旧会有,此时文件处于尚未 git add 的状态

    举个例子,比如说此时回退到了版本1,那么从版本1到版本2之间的所有修改内容都会被保留,并且处于未提交 git add 的状态(2023/4/12更新,这里说的再准确点,实际上假如本地已经基于版本2又做了一些开发,并且把版本2的错误做了修正,那么这些所有的改动也依旧会保留),此时如果修改相关代码,并使用 git push -f 推送至远端后,你就会发现之前的版本2不见了,取而代之的是你新提交的版本,并且版本1的代码仍旧存在

  2. git reset --soft 加 soft 的情况,与什么都不加的情况类似,但区别在于此时的文件处于已提交 git add,尚未提交 git commit 的状态

  3. git reset --hard 加 hard 的情况,此时修改的部分不会被保存,也就是所有在版本2上的修改都会丢失

解决步骤

  1. git log 查询日志找到版本1的hash码,复制前六位然后使用git reset --hard xxxxxx
  2. 此时你就会发现已经回退到了版本1,并且版本2的所有改动都不见了
  3. 进行修改后重新 add 和 commit,注意这个时候使用 push 是不行的,需要使用git push -f强制推送到远程仓库,请谨慎使用该命令! 我这里只是给出一种使用场景,最好不要直接在主分支上使用该命令。

git fetch 无法拉取远程分支

问题原因

目前还不清楚原因,一开始考虑是 SSH 的问题,可设置多次以后仍是无法通过 git fetch 拉取分支,且此时可以正常上传修改远程分支,不知有无小伙伴解惑

解决方法

使用 git branch -a 获取所有的分支包括远程仓库的分支,此时不需要通过 git fetch 拉取远程仓库的分支到本地就可以切换相应分支

.gitignore 文件的使用

使用场景

当某些文件你不想要上传到远程仓库时,可以把文件名或者文件夹名写在 .gitignore 中,比如说像 node_modules 这样的文件夹。试想这样一种情况,假如一开始没有配置 .gitignore 文件,那么 node_modules 就会被从上传到远程仓库中,那么该怎样做才能将 node_modules 从远程仓库中删除呢?

解决方法

以 github 举例,远程仓库中找到 node_modules 文件夹,进入后选择删除,然后提交 commit,删除完成后,本地 git pull 拉取一下远程仓库的变化,完成

文件匹配规则

  • gitignore 只匹配其所在目录及子目录的文件。所以不需要在每个子目录下都创建一个 gitignore 文件,它会去寻找外层是否有该文件,一直找到 git 仓库根目录
  • 已经被 git track 的文件不受 gitignore 影响。当我们使用 git add 时文件就会被标记为已跟踪状态
  • 子目录的 gitignore 文件规则会覆盖父目录的规则,也就是所谓的就近原则

关于文件匹配我之前不明白的点是,如果父目录写了一个 gitignore 文件,那么子目录是不是也可以应用到这个规则,经过查询文章了解到,这种情况是适用的,并且遵循就近原则,如果此时子目录中也有一个 gitignore 文件,那么相同的规则会遵循最近的 gitignore 文件,所以在一个 git 仓库下如果有多个类似的项目文件夹,比如说都有 node_modules,那么其实只需要在根目录下写一个 gitignore 文件即可忽略所有子目录下 node_modules 文件夹的上传

git rebase 和 git merge 的区别

rebase 相比于 merge,rebase 的合并会使得提交在同一条线上,属于剔除枝叶,维护主干的方式,使得提交记录非常简洁,使用 merge 的话,会留下枝叶,可以保留较为完整的工作痕迹,二者各有好坏吧

git stash 的使用

git stash 先将本地修改的内容进行暂储,需要使用的时候使用 git stash apply 或者 git stash pop ,两者的区别是,pop 会删除栈中记录,具体看这篇文章

不同代码仓库使用不同的用户名提交代码

首先可以通过 git config user.[name/email] 去查看当前仓库的用户名或邮箱

如果想查看全局用户名或邮箱需要这样执行 git config --global user.[name/email]

注意这里 --global 放的位置,不能放在最后,要不然会被当作设置用户名或邮箱

设置用户名/邮箱 git config [--global] user.[name/email] [你的用户名/邮箱]

相关文章

juejin.cn/post/712412…

juejin.cn/post/712382…

segmentfault.com/a/119000001…

juejin.cn/post/715945…