😍Git😍,嘎嘎好用!谈一谈我对Git的理解与使用心得

老板说你Git玩不明白,要被裁了,怎么办?我来祝你一臂之力!

掌握接下来所讲的Git基础知识与技巧,希望能帮助大家在日常工作和学习中可以轻松使用这个强大的代码管理工具😏

先讲讲Git是个什么东东,以下内容直接CV大法,有所了解的朋友们选择性跳过

简介

Git 是一款免费、开源的分布式版本控制系统,用于高效地处理任何或小或大的项目。是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件

优点

版本控制,多人协同开发,适合分布式开发,强调个体,公共服务器压力和数据量都不会太大

速度快、灵活,任意两个开发者之间可以很容易的解决冲突

对于刚上手的新手来说,不推荐直接使用Git的相关GUI工具,好用归好用,建议在使用之前,对Git有一定程度的了解,并且熟练操作Git的常用命令。熟练之后,用GUI对比代码,解决冲突等其它操作,非常方便,嘎嘎香😍

正篇开始

以下命令代码涉及到的远程源默认名为origin双引号内为自定义内容

以下内容是我个人对这个工具的了解与心得,如有错误,欢迎各位大佬纠正

最基本流程

workspace:工作区,开发,变更代码所在位置,也就是你的项目文件所存放区域

staging area:暂存区,当执行git add命令后,工作区的文件就会转移到暂存区,暂存区标记了当前工作区中哪些内容被git管理

local repository:本地仓库,执行git commit命令后,将提交一个新的版本至本地仓库

remote repository:远程仓库,代码托管平台,例如gitee、github、gitlab等,也可以是个人搭建的git私服。通过git push命令同步代码到远程仓库

大体流程

bash 复制代码
使用git clone命令将远程仓库上的文件克隆到本地仓库之中
将所修改的或者新添加的文件加入暂存区
将暂存区中的内容提交到本地仓库
将本地仓库中的内容推送到远程仓库之中

常用命令

git add命令

作用:添加文件(新增或修改)至暂存区

添加部分文件到暂存区

git add [file1] [file2] ...

添加当前目录下的所有文件到暂存区

git add .

取消暂存操作,并不会修改文件内容也不会删除文件,只是将文件变为未暂存的状态

git rm --cached [file1]

取消所有文件暂存状态

git reset(后续将具体详细介绍该命令)

git commit命令

将暂存区内容提交到版本库,形成一个新的Commit

git commit -m [message]

修改上一次提交记录

git commit --amend

很有用的命令,可以减少提交版本次数,日志更加清晰整洁

本质上就是生成了新的commit,携带新的变更文件并替代了上一次commit的位置

git log命令与git reflog

查看git提交日志

git log

每一条提交压缩到只有一行,仅保留短哈希、提价说明等最必要的信息

git log --oneline

git 操作的一道安全保障,它能记录你使用过的git操作,大胆放心的操作git,可以配合reset进行操作回退

git reflog

git cherry-pick命令

git cherry-pick <commit>

场景:A分支提交了一个新的Commit,如何在B分支中,吧A分支这个新提交的Commit也拿过来,并入到B分支的代码中

解决方案:git log 查看A分支的日志,获得新提交Commit的Commit ID,运用git cherry-pick命令将A分支中的新Commit应用到B分支中 当然,如果B分支也改动了A分支新的Commit里所修改的文件,那样必然会产生冲突,代码冲突解决我将在后文继续阐述

示例代码:

bash 复制代码
git init
echo "A" > "A.txt"
git add .
git commit -m "A.txt"
echo "B" > "B.txt"
git add .
git commit -m "B.txt"
git checkout -b "test"
echo "C" > "C.txt"
git add .
git commit -m "C.txt"
// 查看test分支最新的关于C的提交
git log test
git switch master
git cherry-pick "test分支上提交的commit版本号"

未进行遴选(cherry-pick)之前

遴选之后

git rebase命令

git rebase <commit> | <branch>

变基变基,以选择的分支为基,同步该分支的Commit,再自动将自己提交的Commit放在后面

采用交互式变基

常用的场景之一:将多个Commit合并成为一个Commit,使得代码的提交历史更加简洁清晰,获得一个干净的提交历史

注意:如果使用HEAD~n来指定最近的n次提交,是无法指定到第一次Commit提交的,需要使用**--root**,才能涵盖第一次提交

示例代码

sql 复制代码
git init
echo "A" > "A.txt"
git add .
git commit -m "A.txt"
echo "B" > "B.txt"
git add .
git commit -m "B.txt"
echo "C" > "C.txt"
git add .
git commit -m "C.txt"
git rebase -i --root

采用squash进行压缩

执行git rebase -i --root后,控制台会提供操作面板,仅需要修改Commit版本号之前的指令,:wq退出即可

没有交互式变基之前

采用交互式变基之后

以上代码实现了,如何将3个Commit合并为1个Commit,此外git rebase -i 提供了丰富的交互式指令

几个较为常用的指令

p,pick(默认):选择此Commit,可以通过重新安排pick命令的顺序,来改变提交的顺序。

r,reword:与pick类似,但使用后,重新设置过程将暂停并为你提供修改Commit中信息的机会

e,edit:你可以选择在该Commit后,进行更多次的提交,或者更改提交

s,squash:该命令可以将两个或多个提交合并为一个提交

d,drop:删除此次提交

git pull命令

同步本地仓库与远端仓库,获取当前分支的最新提交

最常用两种模式

一种是fetch + merge(默认情况)

git pull

一种是fetch + rebase(推荐)

git pull --rebase

git push命令

将本地仓库推送到远端仓库

git push <远程主机名> <本地分支名>:<远程分支名>

本地分支名和远程分支名相同的情况下可以省略只写一个

git push -f <远程主机名> <本地分支名>:<远程分支名> (慎用) 强制覆盖远端代码

在新建的仓库中,第一次push到远端需要指定上游分支,建立跟踪关系

例如git push -u origin master命令,-u是--set-upstream 的缩写,告诉git设置本地分支和远程分支之间的关联,这样以后你就可以在该分支上(master分支)使用git pull或者git push而不需要指定具体的远程仓库和分支

git reset命令

版本回退命令

HEAD 说明

  • HEAD 表示当前版本
  • HEAD^ 上一个版本
  • HEAD^^ 上上一个版本
  • HEAD^^^ 上上上一个版本
  • 以此类推...

可以使用 ~数字表示

  • HEAD~0 表示当前版本
  • HEAD~1 上一个版本
  • HEAD^2 上上一个版本
  • HEAD^3 上上上一个版本
  • 以此类推...

git reset [--soft | --mixed | --hard] [<commit> | [HEAD]]

版本回退三种模式 mixed soft hard 的区别

本质上都是回退到某个Commit版本,区别上主要体现在暂存区和工作区文件变化不同 ,平时开发中一般就使用默认的--mixed,只不过在通过git add . 将文件添加到暂存区就变成了--soft

--hard 参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交,不保留你新写的代码(慎用),完全回到所需变更版本的状态

--mixed 为默认,用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变

--soft 跟mixed很相似,跟mixed区别就是soft,保留暂存区中的内容

示例代码

sql 复制代码
git init
echo "A" > "A.txt"
git add .
git commit -m "A.txt"
echo "B" > "B.txt"
git add .
git commit -m "B.txt"
echo "C" > "C.txt"
git add .
git commit -m "C.txt"
// 执行以上代码后,将该项目文件复制2份,每一份分别执行以下中的一条语句,可以进行比较,看看差异
git reset HEAD~2 --hard
git reset HEAD~2 --soft
git reset HEAD~2 --mixed

git revert命令

git revert <commit>

相比git reset命令,在团队开发中,git revert命令更为常用,git reset命令会改变git之前的历史记录 ,如果和同事没配合好,很容易会导致版本冲突问题,而git revert命令则是在之前的历史记录之上,往后去进行撤销操作,会生成并提交一个撤销的提交版本,让其他同事可以更好的了解撤销的原因,并且可以很容易同步到撤销后的版本,也可以回到撤销之前的版本

git stash命令

将当前未提交的修改(工作区的修改和暂存区的修改)先暂时储藏起来

该命令也非常非常的常用,当你开发的过程中,遇到紧急bug修复,想优先解决掉这个bug

一种解决方式是使用新创建分支,将你已经修改的代码提交一个新的Commit,再切回原来的分支,新建个bug分支开始解决bug....

用stash的话就灰常方便了,直接执行git stash (push) 命令将已经修改过的文件缓存起来,工作区就回到了没有修改过的样子,然后就可以愉快的修改bug了,最后git stash pop恢复一下之前还没写完的代码,如果git stash pop冲突了,解决完冲突后,可以git stash drop来清除已经缓存的旧代码

注意

如果产生冲突,缓冲区代码是不会因为pop而删除的,需要手动清除

此外git stash是不会缓存新建文件的,需要使用git stash --include-untracked缓存新创建的文件

git stash可以多次stash,类似栈的结构,后进先出结构

stash常用命令

kotlin 复制代码
// 缓存所有文件,包括新创建
git stash --include-untracked 
// 缓存所有文件,不包括新创建的文件
git stash
// 查看存放列表
git stash list
// 添加备注
git stash save "备注信息"
// 弹出缓存文件,恢复之前存储的工作目录
git stash pop
// 显示改动信息,默认为第一个,index代表存储索引,默认从0开始
git stash show stash@{index}
// 删除第index个队列,默认从0开始
git stash drop stash@{index}  

冲突解决

有很多种情况都会导致代码冲突,merge合并代码、stash pop弹出、rebase变基、cherry-pick遴选等,遇到冲突不用慌,git会自动在冲突文件中标明冲突的地方,在与同事沟通解决掉冲突后,需要重新提交一个新的Commit即可。以下将举例三种冲突情况

stash pop弹出缓存冲突

示例代码

csharp 复制代码
git init
echo A > "A.txt"
git add .
git commit -m "A.txt"
echo AA >> "A.txt"
git add .
git stash 
echo AAA >> "A.txt"
git add .
git stash pop
// 修改冲突文件之后,可以执行以下语句,清空暂存区
// 如果产生冲突,缓冲区代码是不会因为pop而删除的,需要手动清除
git stash drop stash@{0}

解决冲突后,提交一个新的Commit

最后通过git stash drop stash@{0}删除缓存即可

cherry-pick遴选冲突

csharp 复制代码
git init
echo "A" > "A.txt"
git add .
git commit -m "A.txt"
git checkout -b "test"
echo "A test分支修改了A文件" >> "A.txt"
git add .
git commit -m "test分支修改了A文件"
git switch master
// 查看test分支修改A文件对应的版本号Hash值
git log test
echo "A master分支也修改了A文件" >> "A.txt"
git add .
git commit -m "master分支也修改了A文件"
git cherry-pick <test分支修改A文件对应的版本号Hash值>
// 修改冲突文件后执行以下命令
git add .
// 可以commit提交一个新的版本后执行下边指令,也可以直接执行下边指令(控制台会弹出一个文件供你修改commit的message)
git cherry-pick --continue

rebase变基冲突

sql 复制代码
git init
echo "A" > "A.txt"
git add .
git commit -m "A.txt"
git checkout -b "test"
echo "A test分支修改了A文件" >> "A.txt"
git add .
git commit -m "test分支修改了A文件"
git switch main
echo "A master分支也修改了A文件" >> "A.txt"
git add .
git commit -m "master分支也修改了A文件"
git rebase test
// 修改冲突后的文件执行以下命令即可
git add .
git commit -m "fix conflict"
git rebase --continue

遇到冲突不要慌,跟同事协商修改好冲突后,重新提交一个新的版本,git merge --continue git rebase --continue git cherry-pick --continue等命令,git会给出非常清晰的提示与命令,根据提示进行代码冲突解决即可

误区

误区一

每一次Commit迭代,只是提交你本次代码的变更,改动的文件

比如说你工作目录下有两个文件A文件和B文件,你修改了一个A文件并提交了一个Commit,另外一个同事吧B文件更改了并且push到了远端代码仓库,此时你本地的B文件相比远端的B文件已经产生了差异,那么此时你在进行push操作,会产生冲突吗,可以push成功吗?

答案:并不会产生冲突但push至远端失败 ,因为此次你的Commit只是修改了A文件内容,Git不会比较跟这个Commit里无关的文件,只会给你提示,你当前的版本落后(新提交Commit之前的Commit与远端对应不一致),导致push远端失败

推荐操作:先将本地文件stash push,再rebase远端代码仓,然后将本地文件stash pop,最后提交一个新的Commit,push至远端就行了。这样既保证了远端代码与本地代码同步,又可以提交你的新的修改

误区二

当你还有未暂存/已暂存的文件 时,切换分支并不会将未暂存/已暂存的文件 保留到原来的分支,而是一并转移到新的分支

小技巧

日常摸鱼的时候,想偷偷完善一下自己的项目😏,一提交发现,邮箱和作者都是公司的账号,但为了保护隐私,不用公司账号邮箱, 可以在提交Commit的时候,来修改你的提交记录

本次提交可以直接

git commit -m "xxxx" --author="名字 <你的邮箱>"

修改上一次提交

git commit --amend --author="名字 <你的邮箱>"

修改前N次提交

git rebase -i HEAD~N

将需要修改的提交pick改为edit即可

并开始针对需要修改的Commit依次进行以下操作

git commit --amend --author="名字 <你的邮箱>"

最后使用以下命令

git rebase --continue

Git为特定项目设置用户名/邮箱

在这之上为有一个坑,提交后,在git log 日志中会发现作者和邮箱都已经改了,但是在推向远端后,神奇的发现,怎么会有两个作者(一个是Global全局的作者,另外一个是你修改的作者)

解决方法,在你的项目目录之下 git config user.name "Your Name" git config user.email "Your Email"

修改完了,你可以通过进入你的项目目录下的**.git文件夹**,通过以下指定进行查看是否更改完成 cat config

后续操作按正常提交即可,无需指定用户和邮箱

如何在本地,新建一个分支并与远程某分支保持同步

更新远程仓库信息 git fetch 创建本地分支并拉取远程分支到本地 git checkout -b 本地分支名称 origin/远程分支名称

fetch命令拉取远程最新变更

当你的小伙伴提交了新的Commit或者新的分支时,你不想着急着同步远程代码,想看看小伙伴做了哪些变更,你可以先通过git fetch命令进行拉取远程最新变更,这里需要注意的是,这并不会影响你本地工作区的文件内容,文件不会有任何改动 ,执行该命令之后,你可以通过git diff命令来比较最新 远端和本地代码之间的差异。这是git pull命令和git fetch命令之间的差异

git pull = git fetch + git merge

git pull 命令会拉取远程最新变更,自动将这些最新变更合并到本地所指定的分支中,而git fetch命令则只会拉取远程最新变更(存储在项目目录下的.git/objects文件夹之中,并不会影响工作区的内容)

番外

SSH绑定远端

以下以Github为例

本地生成ssh密钥

ssh-keygen -t rsa -C "youremail@example.com"

会默认生成再默认用户路径之下的.ssh文件夹之中

id_rsa.pub文件中为我们所需添加的公钥

登陆Github,右上角头像->Settings->SSH and GPG keys->New SSH Key

Title随意,Key type选择Authentication Key,Key则为id_rsa.pub中的内容

通过SSH连接到Git服务器是否成功,可以使用ssh命令来尝试建立连接

ssh -T git@github.com

测试某仓库是否可以连接,这个命令将返回仓库的引用列表,包括分支和标签

git ls-remote git@github.com:username/repo.git

还有非常多的Git命令以及小技巧在本文没有阐述,只是大致讲了一些比较常用的指令,如有不足之处,欢迎大佬指出,能有所帮助那就再好不过👍

参考文献

Git简介

如何修改第一个 commit 的提交信息

学习网站

Git命令练习网站

推荐一下这个Git教程,非常友好,图文动画讲解,通俗易懂~

【GeekHour】一小时Git教程

相关推荐
也无晴也无风雨1 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang2 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、5 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤6 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui