什么是 Git
? Git
是目前世界上最先进的分布式版本控制系统!!!什么?啥意思?不懂,没关系,你只要记住,它很重要,非常重要,程序猿的必备技能即可。
Git
的命令非常非常多,这里强调一下,不要傻傻的去背这些命令,没啥卵用,有些命令可能你这辈子你都未必使得上。
本章的目的是教你如何通过命令行完成 Git
的日常基操,并会适当介绍命令的意义,加深你的理解。
在介绍这些命令之前,我们先来看一张灰常重要的图:
图中有四个空间,是 Git
工作流程的精髓所在,分别是:
Github
或者 Gitee
等平台上创建的项目仓库;.git
文件夹;.git
文件夹里面的 index
文件,它保存即将提交到本地仓库的文件列表信息;VS code
或者 WebStorm
编译器正在编写的代码。拉取项目是开始搬砖的第一步,一般创建好项目远程仓库,你就能获取到一个 .git
结尾的地址,或者这个地址可能由公司同事给到你,之后你随便找个目录,通过 Git Bash 输入下面命令即可拉取到项目到本地。
git clone 你的项目地址.git
一般拉取完项目后,我们是处于 master/main
主分支,不要着急就去编写代码,先要查看一下项目的远程分支情况,根据要求看是否需要切换到某个分支进行特定开发。
git branch -r
一般本地创建的分支情况应该是和远程分支一一对应,当然,在未进行发布或者和远程分支建立关联,本地分支并不会影响到远程分支,你可以随意创建、删除和修改。
git branch
git branch dev(分支名称, 可以随便取)
通过上面的命令,你会创建好一个本地分支,当然,该分支是基于你当前所在分支创建的。你可以再次敲命令去查看远程分支和本地分支各自的情况(多敲,很快命令就记住了-〇-)。
对远程仓库分支并不会有任何影响
git branch -m newBranchName
对远程仓库分支并不会有任何影响
git branch -d dev
创建好本地分支,我们就可以切换到该分支上。
git checkout dev
创建和切换两个操作也可以一起做:
git checkout -b xxx
(创建并切换到该本地分支)
当我们创建好一个本地分支的时候,这个时候还是不要着急去开始编码,我们要把该分支发布到远程仓库去,让远程仓库也拥有该分支,且让它和你本地分支进行关联,方便我们后续直接进行 git pull
或者 git push
操作。
git push origin dev
发布完本地分支后,你可以同样通过 git branch -r
去查看你远程仓库的分支列表是否多了新的分支。
本地分支与远程分支关联这步不是必须,但后续就能很方便的直接使用 git pull
或者 git push
获取或提交该分支的代码,而不用去指定分支。
git push --set-upstream origin dev
如果你不关联两者分支的关系,强行去使用,你可能会遇到图中的情况,大致意思就是让你指定目标分支或者去关联分支情况再进行操作。(Git
的提示信息还是很友好的)
完成上面的几步,我们就能开始搬砖了。在对代码更改后,要把提交代码到远程仓库,我们就要先把代码添加到暂存区,之后提交到本地仓库,最后才能提交到远程仓库。
src/main.js
文件,则 git add src/main.js
git add xxx(文件路径)
# 多个
git add xxx(文件路径) xxx(文件路径) xxx(文件路径) ...
git add .
这里你可能会在想,为什么要先添加到暂存区,再本地仓库之后才提交到远程仓库呢? 如果你是从
SVN
转过来,可能会稍微有点不了解暂存区,这里涉及暂存区的意义,网上有很多解释,这里就不做过多的解释了。
但你可以简单的怎么理解,假如你在开发中开发了用户的添加功能和文章的添加功能,两个功能都同时开发完了,因为都互不影响,完全独立,你想分成两次提交分别写上对应的commit
信息说明,这个时候就可以使用到暂存区,先将用户添加功能添加到暂存区,然后commit
到本地仓库,再进行文章添加功能的提交,最后在一起push
到远程仓库即可。
当你误把文件添加进暂存区,也不要慌,有添加,就肯定有删除。
git rm --cached xxx(文件路径)
.git
目录下的 index
文件,将此文件删除,那么就认为暂存区被清空。rm .git/index
当然,这只是把暂存区中跟踪的文件移除而已,不会改动原文件的内容,原先更改的内容还在。
这个命令用于查看工作区和暂存区的状态,能看到哪些文件被修改了,它修改后是否被暂存了,又或者还没有暂存。这个暂存的过程,专业的叫法是 Git tracked
,也就是是否被跟踪。
git status
通过下图,我们能查看到所有改动过的文件,绿色的文件是已经添加进暂存区的,红色的文件则是未添加到暂存区的,而且每个文件前都有对应的操作说明,如果是新文件则是 new file
,修改的文件则是 modified
,删除的是 deleted
, 如果是未添加进暂存区的新文件,则没有。
git commit -m "说明信息"
通过上面的命令,我们就将暂存区的文件提交到本地仓库了,我们可以通过 git status
再次查看暂存区的情况。
Git
的提示真的是非常友好的。
这个命令可以显示提交过的记录。
git log
进入提交记录日志列表后,可以按 q
退出。
上面的命令会显示所有的
commit
记录,如果你想要显示最近几条记录,你可以通过git log -n(n为数字, 可以随意指定)
命令完成。
git push
执行这条命令的前提是进行过第7步骤才行哦。
把本地仓库文件提交到远程仓库后,我们再次查看提交日志。
git pull
这个命令同样也是建立在第7步骤之前的。
将本地分支与远程保持同步,如果你使用 git branch -a
查看远程分支发现有些分支没有,则可以执行此命令进行同步。
git fetch
当我们拉取 git pull
速度特别慢,或者出现以下提醒:
warning: There are too many unreachable loose objects; run 'git prune' to remote them.
我们可以执行以下命令:
git gc --prune=now
它能帮助我们清理 git
一些缓存,gc
指的是垃圾收集(garbage collect
)。
记住上面15个命令,Git
的日常基操基本也满足了,当然现在各种编辑器功能强大,基本都集成了 Git
的可视化操作,不用命令行来操作,也完全没有问题。
但是程序猿使用命令行不是一件很酷的事情吗?不为别的,只为装13也是可以搞一搞的,哈哈哈。下面再来讲一些命令,虽然使用频率不高,但是也是很重要的。
git config --global -l
# or
git config --global --list
git config --global user.name
git config --global user.email
git config --global user.name "你自己的用户名"
git config --global user.email "你自己的邮箱"
要在当前项目根目录下执行。
git config user.name
git config user.email
要在当前项目根目录下执行。
git config user.name "你自己的用户名"
git config user.email "你自己的邮箱"
当别人删除了一些远程分支,而你本地用 git branch -r
或者 git branch -a
命令查看远程分支的时候,这些被删除的分支还是可以看到,你可以使用以下这个命令来更新最新的分支情况。
git remote update origin --prune
这个命令对于一些未设有保护的重要分支来说,如master/release等等,是挺危险的操作,要慎重执行。
git push --delete origin dev(分支名称)
或者
git push -d origin dev(分支名称)
修改远程仓库分支的名称过程是:先修改本地分支名称 - 删除远程分支 - 重新发布本地分支到远程仓库
# 修改本地分支名称
git branch -m 旧分支名称 新分支名称
# 删除远程分支
git push --delete origin 分支名称
# 发布新分支
git push origin 新分支名称
# 重新建立关联
git push --set-upstream origin 新分支名称
合并分支是一个比较常见的操作了,当你在一个分支开发完新功能后,很多时候这些分支最终都要合并到 master/main
这个主分支上,这个主分支拥有所有分支的代码,并且它是稳定且在生产环境上跑的,所以在你确定要将分支合并到主分支上之前,一定要确保这个分支代码是没有问题。
# 切换到稳定的目标分支
git checkout master
# 更新最新代码,防止本地仓库对应分支代码不够新而出现问题
git pull
# 合并分支到本地仓库
git merge dev
# 发布合并后的新代码到远程分支
git push
合并后,你可以通过 git log
去查看是否有相关的 commit
记录。
git merge xxx(A分支名称) xxx(B分支名称)
git merge --abort
当代码冲突时,可使用此命令恢复到冲突之前。
有时候我们只想合并某一个 commit
来满足一些特定需要,这也是可以做到的。
# 切换到稳定的目标分支
git checkout master
# 合并某个commit到本地仓库
git cherry-pick xxx(commitId)
# 发布合并后的新代码到远程分支
git push
commitId
是一个 commit
的唯一标识,你可以通过 git log
来找到它,它是一串很长不重复的字符。
当然,你也可以去到 Github
或者 Gitee
平台对应项目里面找。
合并单个
commit
你可能会遇到冲突的情况,如:在我执行合并某一个commit
给我报了一个错,大致意思就是代码冲突了,需要去调整后,才能提交。代码冲突是件非常蛋疼的事情,不仅仅合并的时候会发生冲突,比较频繁发生的场景是多人共同开发的时候,因为两人负责同个项目,就有极大的可能会改到相同的文件,相同的代码,这就会造成冲突。一般这个时候
Git
会阻止你的提交,让你先去整改,这时候就需要你非常谨慎细心的去处理,因为一旦粗心,就极有可能干掉同伴的代码或者自己的代码,这会造成很严重的后果。(不要问我怎么知道的,都是血的教训︶︿︶)解决代码冲突一般我会借助编辑器等工具来完成,就不通过命令行操作了,这样比较方便,不容易出错。我使用的是
VS code
编辑器,在编辑器内冲突的文件一般都会标红,点开文件,会发现里面会有写<<<<
的符号,被符号包围的内容就是冲突的地方。编辑器一般会提供四个选项帮助你快速操作,当然你也可以手动删除修改。
- Accept Current Change:接收当前更改,也就是冲突部分以旧的为准。
- Accept Incoming Change:接受传入的更改,也就是冲突部分以新的为准。
- Accept Both Changes:接受两个更改,也就是新旧都存在,可能会出现重复。
- Compare Changes:比较变化,会分成两个文件,让你更直观的查看两者的冲突内容。
当你解决完冲突后,你可以保存文件,再执行以下操作,提交代码。
# 添加更改进入暂存区 git add . # 提交暂存区到本地仓库 git commit -m "" # 提交本地仓库commt到远程仓库 git push
git reset --soft HEAD^
这个命令用于撤销本地仓库最近的一个 commit
,撤销后会回到暂存区中,通过 git log
可以查看 commit
记录会减少,但不影响远程仓库。
还有另一个相似的撤销 commit
命令,但它比较危险,撤销后的内容是直接就删除的,不会回到暂存区,要慎重使用!!!
git reset --hard HEAD^
这个命令可以让你更加直观的查看你需要的信息。
git log --pretty=oneline
其实这些信息都存放在
.git
文件夹中,在.git\logs\refs\heads
下记录了所有分支的commit
版本号。
这是一个神奇的命令,特别对项目分支比较多的情况,是非常有用的,他的使用场景大致是:当你正在A分支中开发功能,你临时接到一个紧急的需求,需要优先切换到B分支中去开发,这个时候A分支中已经改动的代码要怎么办呢?这时就能使用 stash
来备份代码了。
git stash
执行命令后,当前工作区会回到最近的一次 commit
状态,并将更改的代码保存在 Git
栈中,这样你就能先切换到B分支中去开发,等B分支功能开发完成,再切换回A分支,通过下面的命令取回原来的更改的代码,继续进行A分支的功能开发了。
git stash pop
是不是非常的 nice!!!
git stash list
git stash clear
如果你在 github
或 gitee
创建了一个新的仓库,你想把你现有的本地代码提交到你的 git
仓库中,这时常用的方式有2种:
clone
下远程仓库,再把本地代码丢进去,然后 push
到远程仓库中。首先在你的本地项目根目录初始化一下你的 .git
目录:
git init
然后添加远程仓库地址就大功告成:
git remote add origin xxx.git
git remote -v
git remote set-url origin xxx(新仓库地址)
更改远程仓库地址有另外的两种方式
# 删除项目的远程仓库地址
git remote rm origin
# 添加项目的远程仓库地址
git remote add origin xxx(新仓库地址)
或者去改配置文件
git diff
这个命令是对比工作区和暂存区的所有差异,但个人感觉不太直观,也可能只是比较少用吧,关于对比我更愿意借助编辑器工具来查看。
对比工作区单个文件和暂存区的区别:
git diff xxx(文件地址)
git checkout xxx(文件地址)
# 批量还原
git checkout xxx(文件地址) xxx(文件地址) xxx(文件地址) ...
git commit -n
如果进入 vim
模式,可直接输入 :wq
回车退出。
commitId
git log --pretty=oneline
git reset --soft commitId
git push origin branchName --force
# or
git push -f origin branchName
此时你的本地项目应该处于你未提交之前的暂存状态,你可以重新进行相关操作
有时候在执行 git pull
的时候会出现这样的错误:
$ git pull
error: cannot lock ref 'refs/remotes/origin/(branchName)': 'refs/remotes/origin/(branchName)' exists; cannot create 'refs/remotes/origin/(branchName)'
From https://gitee.com/...
! [new branch] branch -> origin/branch (unable to update local ref)
我们可以执行以下命令来解决,先清理一下 git
缓存:
git gc --prune=now
再同步本地与远程仓库的分支情况:
git remote prune origin
其实造成这个错误的主要原因是因为远程的分支会经常在合并后删除,但是本地的分支一直没有人去管,时间久了,本地的分支就积累了一堆,造成两端分支不同步,这个命令就是将本地还没有删除的分支一起清理掉。
当你执行了 reset
或者 checkout
等操作的时候,这些操作会被记录在 reflog
中,我们可以通过以下命令来查询。
git reflog
如果你想撤销这些操作,你可以执行一下命令:
git reset --hard 98abc5a
小编日常使用的 Git
命令就这些,虽然我一直坚持使用命令行的方式来操作 Git
,但还是经不住工具的香,对于解决代码冲突、文件对比等操作我还是会优先选择借助编辑器工具集成的功能来解决,会更加直观、快速,也不容易出错。但是,这里强调一下,命令才是本质,适当了解掌握,百利而无一害,哈哈哈。
至此,本篇文章就写完啦,撒花撒花。
希望本文对你有所帮助,如有任何疑问,期待你的留言哦。
老样子,点赞+评论=你会了,收藏=你精通了。