目 录CONTENT

文章目录

高频 Git 命令集

俊阳IT知识库
2023-03-15 / 0 评论 / 0 点赞 / 390 阅读 / 7,235 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2023-03-15,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
广告

文章已同步至掘金:https://juejin.cn/post/6844904015654813710
欢迎访问😃,有任何问题都可留言评论哦~

Git 常用命令

初始化一个Git(本地)仓库 (只需初始一次)

git init

设置用户名和邮箱 (只需设置一次)

用户名:git config --global user.name 你的用户名
邮箱:git config --global user.email 你的邮箱

把工作区的文件添加到暂存区 (需按自己的需求添加N次)

git add 文件名,文件名····    
git add *  (把当前工作区所有文件添加到暂存区)     
git add ./  (把当前工作区所有文件添加到暂存区)   

commit版本

提交commit

git commit -m "说明文字"

提交(commit)时不进行eslint校验(不建议使用)

git commit --no-verify -m "描述信息"

追加版本,不重新生成commit:

git commit —amend

如果本地commit没有推送到远程仓库,则可以直接使用git commit —amend追加

由于之前已经将该commit推送到远程仓库,导致修改后推送失败。

原因:如果你的commit已经push到了远程仓库,那么使用--amend修改commit后,git push时定要使用 --force-with-lease参数来强制推送,否则就会报错。

流程:

  1. 确认最近一次commit节点是你要修改的commit节点
  2. 修改代码
  3. 修改完毕后执行:git commit --amend -m "新修改的提交信息" -m加一下比较好,跟上一次提交的-m一样也行,不然会出现vim界面(也是让你写注释)所以没必要
  4. git push --force-with-lease

查看相关信息

查看用户名或邮箱等一系列设置 (可自行修改,按Q键退出)
git config --list

查看文件版本
git log (查看分支上都有哪些版本)
git log --oneline (查看分支上的版本,相对简洁)

查看文件状态
git status

查看文件版本id
git reflog

以图文形式查看文件版本
gitk

查看具体提交文件版本的信息
git show commit_id

查看执行 git status 的结果的详细信息
git diff

  • 尚未缓存的改动:git diff
  • 查看已缓存的改动: git diff --cached
  • 查看已缓存的与未缓存的所有改动:git diff HEAD
  • 显示摘要而非整个 diff:git diff --stat

撤回暂存区文件

撤回在暂存区的文件
git reset HEAD -- (撤回所有)
git reset HEAD -- 文件名 (撤回指定文件)

git checkout . #本地所有修改的。没有的提交的,都返回到原来的状态
git stash #把所有没有提交的修改暂存到stash里面。可用git stash pop回复。

git reset --hard HASH #返回到某个节点,不保留修改,已有的改动会丢失。
git reset --soft HASH #返回到某个节点, 保留修改,已有的改动会保留,在未提交中,git status或git diff可看。

git clean -df #返回到某个节点,(未跟踪文件的删除)
git clean 参数
    -n 不实际删除,只是进行演练,展示将要进行的操作,有哪些文件将要被删除。(可先使用该命令参数,然后再决定是否执行)
    -f 删除文件
    -i 显示将要删除的文件
    -d 递归删除目录及文件(未跟踪的)
    -q 仅显示错误,成功删除的文件不显示

注:
git reset 删除的是已跟踪的文件,将已commit的回退。
git clean 删除的是未跟踪的文件

克隆仓库代码

克隆远程仓库的代码到本地
git clone 远程仓库地址

注:一般第一次用 git clone 远程仓库地址 进行拷贝,以后都用 git pull 进行拉取

克隆远程仓库指定分支的代码到本地

git clone -b 分支名 远程仓库地址

从远程仓库拉取代码到本地(master为主分支)
git pull 远程仓库地址 master

推送代码

推送本地代码到远程仓库(第一次同步时需输入密码)
git push 远程仓库地址 master

一般使用git push就ok了

简便方式(一般不用这个,不用看):
 添加远程仓库:git remote add origin 远程仓库地址
 查看远程仓库:git remote
如果显示 origin 则说明添加成功,以后再推送代码到远程仓库时,只需输入 git push origin master 就可以推送代码。
当使用代码 git push -u origin master 时,表示把origin设置为默认主机,则再次推送代码时可简写为 git push
    
注:如果当前分支与多个主机存在追踪关系,则可以使用 -u 选项指定一个默认主机,这样后面就可以不加任何参数使用 git push

  • 删除设置的origin(origin名称需根据你本地查询出来的名字进行删除)
    查询:git remote -v
    删除:git remote rm origin

打标签

查看本地分支标签

git tag
或者
git tag -l
或者
git tag --list

查看远程所有标签

git ls-remote --tags
或者
git ls-remote --tag

给当前分支打标签

  • 轻量标签在Git中,是不存储任何的信息,只是一个特定提交的引用。
  • 附注标签存储在Git数据中,且附注标签中包含了打标签者的名称、电子邮件,日期等信息,一般情况我们都会使用附注标签。

创建轻量标签(git tag + 标签名称

git tag 《标签名》
例如
git tag v1.1.0

创建附注标签(需要在创建轻量标签的方式上,添加选项-a

git tag -a 《标签名》
例如
git tag -a v1.1.0

使用-m选项来指定存储在标签中的信息,如果添加了-m选项,那么Git会绕过配置的编辑器

git tag -a v1.0.0 -m "发布版本v1.0.0"

给特定的某个commit版本打标签,比如现在某次提交的id为 02f498d

git tag v1.0.0 02f498d
或者可以添加注释
git tag v1.0.0 -m "add tags information" 02f498d
或者
git tag v1.0.0 02f498d -m "add tags information"

删除本地某个标签

git tag --delete v1.0.0
或者
git tag -d v1.0.0
或者
git tag --d v1.0.0

删除远程的某个标签

git push -d origin v1.0.0
或者
git push --delete origin v1.0.0
或者
git push origin -d v1.0.0
或者
git push origin --delete v1.0.0
或者
git push origin :v1.0.0

将本地标签一次性推送到远程

git push origin --tags
或者
git push origin --tag
或者
git push --tags
或者
git push --tag

将本地某个特定标签推送到远程

git push origin v1.0.0

查看某一个标签的提交信息

git show v1.0.0

切换到标签

git checkout [tagname]

基于线上tag拉分支new_branch

git branch new_branch v1.2.0

Git 分支命令

注:origin是你的默认仓库地址,你也可以换成你的仓库地址链接(https://git…git)

查看分支

查看本地分支
git branch

查看远程分支
git branch -r

查看所有分支
git branch -a

创建分支

创建本地分支
git branch 分支名

创建远程分支
git push --set-upstream origin 分支名

根据某个commit创建本地分支
git checkout commit_id -b newBranch

切换分支

切换分支
git checkout 分支名

拉取远程分支并切换到该分支
git checkout -b 本地分支名 origin/远程分支名 或者 git checkout --track origin/远程分支名 或者 git checkout -t origin/远程分支名 或者 git fetch(获取远程所有分支),假设有个分支叫origin/Test,直接git checkout Test即可,会在本地新建一个同名分支,并与远程分支关联

创建并切换分支
git checkout -b 分支名

合并分支

合并分支(合并分支之前需要切换到master分支上,合并完解决冲突需要push一下)

git merge 分支名 或者 git pull origin 分支名

但是我们平常不用这个指令来合并分支,我们通常使用git merge --squash 分支名
–squash选项的含义是:本地文件内容与不使用该选项的合并结果相同,但是不提交、不移动HEAD,因此需要一条额外的commit命令。其效果相当于将分支上的多个commit合并成一个,放在当前分支上,原来的commit历史则没有拿过来。
判断是否使用–squash选项最根本的标准是,待合并分支上的历史是否有意义。如果没有意义,就可以直接使用带–squash这个指令。
使用这个命令之后,我们需要commit一次,在提交的我们最好加上标识,然后再进行push
如:git commit -m feat:"新功能"

  • feat:新功能(feature)
  • fix:修补bug
  • docs:文档(documentation)
  • style: 格式(不影响代码运行的变动)
  • refactor:重构(即不是新增功能,也不是修改bug的代码变动)
  • test:增加测试
  • chore:构建过程或辅助工具的变动

删除分支

删除本地分支
git branch -d 分支名

删除远程仓库的分支
git push origin --delete 分支名

  • 同步远程分支到本地

有很多在远程仓库已经删除的分支在本地依然可以看到
使用命令 git remote show origin,可以查看remote地址,远程分支,还有本地分支与之相对应关系等信息
使用 git remote prune origin 命令,这样就删除了那些远程仓库不存在的分支

两个分支合并部分代码

master主分支、develop测试分支(包含全部代码)
现在只把develop分支的部分代码合到master上 (需保持两个仓库的代码为最新)

操作步骤:

  1. 基于master分支建立一个临时分支(feature)并切换到该分支上 git checkout -b feature
  2. develop指定文件或文件夹替换feature的相应文件 git checkout develop <目标文件夹或目标文件名>, 例如:此次开发只涉及 (src/pages/pools/) 文件夹下的文件,则执行:git checkout develop src/pages/pools/,执行完此命令后,develop分支的 (src/pages/pools/) 下的文件会替换feature分支下相应的文件
  3. 将本次 checkout 内容提交到feature分支上 git commit -m "描述信息"git push --set-upstream origin feature
  4. 切换至master分支并合并feature分支代码到master分支上 git checkout mastergit merge featuregit push,或者使用操作面板合并
  5. 删掉临时分支

拉取指定分支的指定文件

git checkout 「branch」<file_name>

临时保存文件信息stash

用来临时地保存一些还没有提交的工作,以便在分支上不需要提交未完成工作就可以清理工作目录
git stash

添加备注,方便查找

git stash save "save message"

恢复未完成的工作状态

// 默认第一个
git stash pop

// 应用其他
git stash pop stash@{$num}

查看所有的stash

git stash list

查看stash具体内容

// 显示第一个储存
git stash show -p 

// 查看其他存储
git stash show -p stash@{$num}

应用某个存储但不会把存储从存储列表中删除

// 默认第一个
git stash apply

// 其他
git stash apply stash@{$num}

丢弃某个stash

git stash drop stash@{$num}

删除所有缓存的stash

git stash clear

同一个项目,当你本地代码更改后,如果你的远程仓库的代码也更改了,这时候你要拉取远程仓库的代码,同时保证本地代码不被覆盖。
这时候就可以操作步骤:git stash(保存当前的工作状态),git pull(拉取远程仓库代码),git stash pop(恢复之前的工作状态)

merge时忽略某个文件或文件夹

git 开启忽略文件配置

git config merge.ours.driver true    //开启忽略文件配置

在项目根目录下新建文件.gitattributes,然后文件中写入需要忽略的文件名 + merge=ours, 一个文件占一行

readme.txt merge=ours
/public/scm/** merge=ours

git rebase使用

注意:

  1. 不要通过rebase对任何已经提交到公共仓库中的commit进行修改(你自己一个人玩的分支除外)
  2. 除非你可以肯定该分支只有你自己使用,否则请谨慎操作。

合并本地多次commit记录

本地开发的时候,在确认功能没问题之前,先不要推送到远程分支,除非测试需要,到时候可以往commit上面追加,尽量保证一个commit为一个功能等

命令:

git rebase -i  [startpoint]  [endpoint]

其中-i的意思是--interactive,即弹出交互式的界面让用户编辑完成合并操作,[startpoint]

[endpoint]则指定了一个编辑区间,如果不指定[endpoint],则该区间的终点默认是当前分支

HEAD所指向的commit(注:该区间指定的是一个前开后闭的区间)

或者也可以使用:git rebase -i HEAD~3来合并前三次提交

每一个commit id 前面的pick表示指令类型,git 为我们提供了以下几个命令:

  • pick:保留该commit(缩写:p)
  • reword:保留该commit,但我需要修改该commit的注释(缩写:r)
  • edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)
  • squash:将该commit和前一个commit合并(缩写:s)
  • fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)
  • exec:执行shell命令(缩写:x)
  • drop:我要丢弃该commit(缩写:d)

例如:合并前三次提交,保留第一次提交可以使用:

p d2cf1f9 fix: 第一次提交

s 47971f6 fix: 第二次提交

s fb28c8d fix: 第三次提交

wq 保存退出

修改合并之后commit的描述信息,wq 保存退出即可

然后push推送到你的远程分支,如果出现推送失败,则可以使用--force-with-lease 强推,前提是这个分支只有你一个人在开发,否则可能会覆盖别人的代码

或者是用:

git merge --squash 分支名
git commit -m '修复了xxx'
git push

分支合并

rebase做了什么操作呢?

首先,git会把本地分支里面的每个commit取消掉;

其次,把上面的操作临时保存成patch文件,存在.git/rebase目录下;

然后,把本地分支更新到最新的master分支

最后,把上面保存的patch文件应用到本地分支上

示例

  • 远程主分支master
  • 本地开发分支dev

当你在本地开发完成并且提交本地commit后(没有提交到远程仓库),这时候master分支有人已经把代码合上去了,所以现在master分支是领先于你的dev分支

这时候,使用rebase来操作一波,切到master分支,pull下代码,切到你的分支,执行git rebase master ,这时候看下log信息,你的commit是在master最新提交的commit之后的。

在 rebase的过程中,也许会出现冲突 conflict。在这种情况,git会停止 rebase并会让你去解决冲突。在解决完冲突后,用 git add命令去更新这些内容。

注意:你无需执行 git-commit,只要执行 continue,git rebase --continue ,这样 git会继续应用余下的 patch补丁文件。

然后推送到远程,但是会报一个错,因为远程分支的commit跟你本地的commit是不一样的,如果这个分支只有你一个人在开发,那么强制推送即可,git push --force-with-lease

在任何时候,我们都可以用 --abort参数来终止 rebase的行动,并且分支会回到 rebase开始前的状态。git rebase —abort

版本回退(分支亦可)

如果在开发中进行了错误提交,那么我们需要使用版本回退(回滚),使自己的工作树和远程仓库回到之前的版本。
对于版本回退,经常会用到两个命令:git resetgit revert 具体有什么区别呢?

git reset参数:

  • 使用soft参数,恢复git commit的操作
  • 使用hard参数,恢复到最原始状态,本地代码也会更改
  • 使用mixed参数,默认参数,恢复git add的操作,包含恢复git commit的操作
  • 示例:使用reset参数,工作区的代码也会相应改变

git reset --hard HEAD^/commit_id
git reset --hard HEAD^ / HEAD~1 (表示回到上一个版本)
git reset --hard HEAD^^ / HEAD~2 (表示回到上上一个版本,依次类推)
git reset --hard 版本id (回到指定的版本,一般用这个)

注:本地版本回退之后,远程仓库不回退(可push到远程仓库中,可能会报错,可以使用git push -f强推上去,不推荐,建议看我下面版本回退方法)

  • 回到未来版本(需通过git log查看版本id)
    git reset --hard 版本id

git reset

假如我们的仓库有如下几个提交:

git-command-4

其中:A 和 B 是正常提交,而 C 和 D 是错误提交。现在,我们想把 C 和 D 回退掉。而此时,HEAD 指针指向 D 提交(5lk4er)。我们只需将 HEAD 指针移动到 B 提交(a0fvf8),就可以达到目的。
上面已经介绍过了,可以使用 git reset --hard a0fvf8 即可把HEAD指针移动B提交下,如图:

git-command-5

而这个时候,虽然本地仓库的HEAD指针变了,但是远程仓库的 HEAD 指针依然不变,仍在 D 提交上。所以,如果直接使用 git push 命令的话,将无法将更改推到远程仓库(报错)。此时,只能使用 -f 选项将提交强制推到远程仓库:git push -f

采用这种方式回退代码的弊端显而易见,那就是会使 HEAD 指针往回移动,从而会失去之后的提交信息。将来如果突然发现,C 和 D 是有用的代码,然而却已经无法复原了。但是我们可以使用 git revert 命令来解决这个问题。

git revert

使用git revert会遇到两种情况,一种是回到提交(commit)之前,另一种是回到合并(merge)之前,两者使用方式不同。

回到提交(commit)之前

git revert的作用是通过反做创建一个新的版本,这个版本的内容与我们要回退到的目标版本内容一样,但是HEAD指针是指向这个新生成的版本,而不是目标版本。

使用 git revert 命令来实现上述例子的话,我们可以这样做:先 revert D,再 revert C (有多个提交需要回退的话需要由新到旧进行 revert)

git revert 5lk4er
git revert 76sdeb

这里会生成两个新有提交:D’ 和 C’,如图:

git-command-1

这里只有两个提交需要 revert,我们可以一个个回退。但如果有几十个呢?一个个回退肯定效率太低而且容易出错。我们可以使用以下方法进行批量回退:git revert OLDER_COMMIT^..NEWER_COMMIT,(例如:git revert 76sdeb^..5lk4er

这时,错误的提交 C 和 D 依然保留,将来进行甩锅的时候也有依可循。而且,这样操作的话 HEAD 指针是往后移动的,可以直接使用 git push 命令推送到远程仓库里。

回到合并(merge)之前

如果你进行了合并(merge)操作,那么使用上面的方式会报错error: commit commit_id is a merge but no -m option was given.,原因是 :merge commit 和普通 commit 的不同之处在于 merge commit 包含两个 parent commit,代表该 merge commit 是从哪两个 commit 合并过来的。

可以使用git show merge_commit_id来查看是从哪两个分支合并来的,例如(9834b9a是我合并后的commit_id):

-> git show 9834b9a
commit 9834b9abf40d4687ceed8616b86f906fbd249a74 (HEAD -> dev, origin/dev)
Merge: 1d3dc50 3b93623
Author: fanjunyang <996597002@qq.com>
Date:   Sun Aug 30 13:18:38 2020 +0800

这代表该 merge commit 是从 1d3dc50 和 3b93623 两个 commit 合并过来的,而普通的 commit 则没有 Merge 这行。

这时候我们就需要添加-m选项以代表这次 revert 的是一个 merge commit,这时需要指定一个 parent number 标识出"主线",主线的内容将会保留,而另一条分支的内容将被 revert。

从上面 git show 命令的例子中可以看到,merge commit 的 parent 分别为 1d3dc50 和 3b93623,其中 1d3dc50 代表 dev 分支(我的主分支,从图中可以看出),3b93623 代表 will-be-revert 分支(这里是dev1分支,我把dev1分支上的代码合到dev中了)。需要注意的是 -m 选项接收的参数是一个数字,数字取值为 12,也就是 Merge 行里面列出来的第一个还是第二个。

我们要 revert will-be-revert 分支上的内容,即 保留主分支(dev),应该设置主分支为主线,操作:git revert -m 1 9834b9a

中间删除,两边保留

假如现在有三个提交,但很不巧的是,那个错误的提交刚好位于中间。如图:
git-command-2

这时,直接使用 git reset 命令将 HEAD 指针重置到 A 提交显然是不行的,因为 C 提交是正确的,需要保留的。这时候我们要先把 C 提交 及 B 批次全部回退,再使用 cherry-pick 命令(挑拣的意思)将 C 提交重新再生成一个新的提交 C’',这样就实现了将 B提交回退的需求。完整的过程如图所示:

git-command-3

合并某个分支上单个commit

使用git log或查git log --graph --pretty=oneline --abbrev-commit 查看提交的信息,记住commit id.

git checkout [branch-name] 切换到合并的分支
git cherry-pick <commit-id> 把某个commit id提交合并到当前分支

如:

dd2e86 - 946992 -9143a9 - a6fd86 - 5a6057 [master]
    \
    76cada - 62ecb3 - b886a0 [feature]

比如,feature 分支上的commit 62ecb3 非常重要,它含有一个bug的修改,或其他人想访问的内容。无论什么原因,你现在只需要将62ecb3 合并到master,而不合并feature上的其他commits,所以我们用git cherry-pick命令来做:

git checkout master  先切换到master分支
git cherry-pick 62ecb3  再使用cherry-pick命令

现在62ecb3 就被合并到master分支,并在master中添加了commit(作为一个新的commit)。cherry-pick 和merge比较类似,如果git不能合并代码改动(比如遇到合并冲突),git需要你自己来解决冲突并手动添加commit。

合并某个分支上的一系列commits

在一些特性情况下,合并单个commit并不够,你需要合并一系列相连的commits。这种情况下就不要选择cherry-pick了,rebase 更适合。

git checkout -b <newBranchName> <to-commit-id>
创建一个新的分支,指明新分支的最后一个commit

git rebase --onto <branchName> <from-commit-id>
变基这个新的分支到最终要合并到的分支,指明从哪个特定的commit开始

如: 还以上面的为例,假设你需要合并feature分支的commit 76cada ~62ecb3 到master分支。 首先需要基于feature创建一个新的分支,并指明新分支的最后一个commit:

git checkout -b <newbranch> 62ecb3

然后,rebase这个新分支的commit到master(–onto master)。76cada^ 指明你想从哪个特定的commit开始。

git rebase --onto master 76cada^

得到的结果就是feature分支的commit 76cada ~62ecb3 都被合并到了master分支。

在合并的过程中可能出现冲突,出现冲突,必须手动解决后,然后 运行

git add .
git rebase --continue

大小写敏感

如果你修改文件夹名(大写 → 小写 or 小写 → 大写),然后 git status 检测不到,这是因为 git 默认没开启大小写敏感,这时候需要全局开启。
设置本地git环境识别大小写: git config --global core.ignorecase false

重命名文件

直接使用以下命令重命名文件,在 git 中不要直接修改文件名,最好的办法是使用下面的方式

git mv -f [你想要删掉的文件] [你想要留下的文件]
git mv -f a.js A.js

等同于:

git rm a.js
git add A.js

修改文件夹名称

修改文件夹名称,全部改为大(小)写(F2重命名修改即可),然后push到远程仓库。这时仓库上就会有重名的文件(文件夹)了。(大小写各一份)

然后需要删除多余的文件(文件夹),执行命令:

# 删除header文件夹下的所有文件
$ git rm --cached src/components/header -r
# 删除footer文件夹下的所有文件
$ git rm --cached src/components/footer -r

如果显示如下,说明操作成功:

rm 'src/components/header/index.js'
rm 'src/components/header/index.less'
...

然后同步,提交到远程仓库

# 添加在缓存
$ git add .
# 提交到本地
$ git commit -m'rm files'
# 提交到远程仓库 origin
& git push origin master

查看当前分支是从哪个分支check出来的?

在当前本地分支里,执行如下命令:

git log --oneline --graph --decorate

或者执行如下命令:

git reflog show 分支名

// git reflog --date=local | grep 分支名

仓库迁移保留commit和分支等信息

// 老仓库执行
git clone --bare https://xxx.git
cd xxx.git
// 在新的仓库创建空项目(什么都没有)
git push --mirror https://new-xxx.git

异常处理

处理大文件

如果分支中文件比较大的话,则需要安装 git lfs

其他

git推送到远程仓库时提示错误
remote: Incorrect username or password ( access token )
fatal: Authentication failed for 'https://gitee.com/***/***.git/'
解决方法:
  清除本地仓库的用户名和密码:git config --system --unset credential.helper
  再执行推送,重新输入用户名和密码


当我们对远程仓库里的文件进行了在线的修改,但是没有对本地库进行同步。
这个时候当我们再次用commit想要从本地库提交到远程库中时就会出现push失败的问题,错误信息:
error:failed to push some refs to https://gitee.com/***/***.git/

解决方法:

  1. 强推(不推荐):git push -f
  2. 把远程库同步到本地库:git pull --rebase
    这条指令的意思是把远程库中的更新合并到本地库中,–rebase的作用是取消掉本地库中刚刚的commit,并把他们接到更新后的版本库之中。

简单来讲正常的解决冲突过程是:
1:git add *
2:git commit -m "XXX"
3:git push时因为本地仓库代码与远程仓代码有冲突,所以接下来
4:git pull拉取远程代码,而冲突需要手动解决
5:解决好后重新进行git add * git commit -m "XXX" git push
而如果 git pull 这一步加上了 --rebase 的选项,那么第5步操作将变成如下 git add * git rebase --continue git push

^_<

0

评论区