目录

Git安装(ubuntu环境)

Git基本操作

创建本地仓库

配置本地仓库

对修改进行版本控制

 了解工作区、暂存区、版本库

版本回退

撤销修改

删除文件

Git分支管理

创建,切换,合并分支

删除分支

解决分支合并冲突

分支合并模式

分支不隔离

优秀Git管理示范例子:

Git远程操作

创建远程仓库

克隆远程仓库到本地

理解远程推送和拉取

向远程仓库推送

拉取远程仓库内容

了解一下.gitignore文件

标签管理

操作标签

给远程仓库推送标签

附录

会看git diff命令的输出

会看git reflog日志

一、短哈希值(abc1234)

二、括号

三、操作序号(HEAD@{n})

四、操作类型(commit/reset/checkout)

五、操作描述

会看git log --graph --abbrev-commit 的输出

给命令取别名


Git有什么用

对文件进行本地/云端保存以及本地/云端版本管理

  • 将文档保存在云端或者本地备份,文件丢失后可以恢复
  • 文档被修改多次后,Git帮我们保存每个版本的文档并指出其相对于上一个版本的修改之处。用户也可以自己添加对这个版本的相应描述。方便查看恢复。

Git安装(ubuntu环境)

终端输入:

sudo apt-get install git -y

查看安装是否成功以及安装版本:

git --version

Git基本操作

创建本地仓库

计算机上的文件非常多,Git并不知道要对哪些文件进行管理。因此我们需要创建一个Git本地仓库,只有在本地仓库下的文件才会被Git管理。

新建本地仓库命令

git init

实操:

配置本地仓库

本地仓库必须要配置的就是name和email,这是文件提交者的身份标识符,Git会把提交者的身份记录下来,追溯历史,注意:他和Git账号密码没有任何关系!!!

配置本地仓库命令:

//只配置本仓库
git config uer.name "你的名字"  //新建配置

git config uer.email "你的邮箱"

git config --unset uer.name   //删除一个配置

git config --unset uer.email


//配置这台机器上的所有仓库
git config --global uer.name "你的名字"  //新建配置

git config --global uer.email "你的邮箱"

git config --global --unset uer.name   //删除一个配置

git config --global --unset uer.email


//获取本仓库的配置信息
git config -l

实操:

对修改进行版本控制

这一步是把修改的部分从工作区添加到暂存区,接着添加到版本库中进行版本控制

相关命令:

git add 文件名(或者“.”表示添加全部修改)

git commit -m "在这儿可以填写你对这个版本的描述"

git log //查看提交日志

实操:

 了解工作区、暂存区、版本库

通过.git目录的内容也可以简单验证一下这一点:

总结一下:

  • 实际上,仓库中每一个版本的文件集都用tree对象组织起来,tree中的每个文件的内容都保存在blob对象中,tree存放的就是blob对象对应的哈希标识符。
  • commit代表一个版本,每个commit对象都有一个tree对象,以及上一个版本commit对象的哈希标识符。
  • blob对象存放了每个文件的每个版本的文件内容,维护他们就相当于进行版本控制
  • 如果一个文件在一次提交中没有被修改,那么stage中缓存的文件名-哈希值映射关系没有被覆盖,那么就不用创建新的blob对象,而是复用上一版本创建的blob对象
  • commit后暂存区的内容暂时不会清空,所以暂存区一般保存的就是最新版本的完整的记录(包括所有文件-哈希值的映射以及目录结构),

关于查看工作区、暂存区、已提交版本之间差异以及objects对象内容的命令:

git status //查看当前git仓库的状态:有被添加但是没提交的?有没被添加的修改?

git cat-file -p objectds对象哈希值 //这是git提供的用来查看objects对象内容的命令

git diff 文件名 //工作区 vs stage的差异,add 之后一定没输出,因为add之后两个区的内容同步了
git diff --staged 文件名 //stage vs commit的差异,add之后有输出但是commit之后没输出

版本回退

版本回退可以让我们把仓库中的文件恢复到前某个版本的样子

相关命令:

//不同于git log 命令只显示当前版本及之前的提交记录,git reflog命令会显示
//历史所有的操作日志,包括历史所有的提交记录以及版本回退记录,可以用于回退
//后恢复到回退之前的版本(即撤销回退)
//git reflog其实就是用户对仓库改变操作的完整记录而git log只是当前版本之前的所有日志的快照

git reflog 


//soft表示只回退commit对象,也就是转换master指向的commit对象
//mixed表示不仅回退commit对象,还回退暂存区
//hard表示除了回退以上两者,还回退工作区,一旦使用这个,我们看到的的文件内容就会改变
git reset [--soft | --mixed | --hard]  要回退的版本commit对象的哈希值

实操:

为什么版本回退这么快

  • 因为版本回退其实就是修改master文件里存放的哈希值为上一个版本commit对象的哈希值,这种简单的修改是很快的,就算是使用"--hard"也不过就是把修改的部分覆盖到暂存区以及工作区罢了。

撤销修改

撤销修改其实也就是版本回退,但是撤销修改发生在不同情况下对应的撤销操作是不同的,上面的版本回退其实是撤销修改的一种情况

相关命令:

//这个命令会使用暂存区的内容来对工作区的内容进行恢复
git checkout -- 文件名

//之前讲过,也是恢复命令,但这里要介绍一个其他用法
git reset [--soft | --mixed | --hard] HEAD  //回退到当前版本(不改变master内容)
git reset [--soft | --mixed | --hard] HEAD^  //回退到上一版本
git reset [--soft | --mixed | --hard] HEAD^^  //回退到上上版本
以此类推......

三种情况:

其实这个很灵活,只要明白三个分区,以及checkout命令和reset命令分别对哪些分区进行操作就可以按照自己的思路来恢复

实操:

删除文件

删除也是一种修改,想要进行版本控制和修改一样,这里只是介绍一个命令:

git rm 文件名//相当于 rm 文件名 + git add 文件名

而且要注意,如果新建一个文件,然后使用git chekout -- 文件名进行回退,结果文件不会如预料的一样被删除,需要我们手动删除。因为新建的文件属于Git未跟踪的文件,Git找不到历史记录也就不会擅自去改动它。


Git分支管理

分支可以让我们可以在不同的分支下开发同时开发不同的功能最后合并(多人协作开发),而不用担心分支互相影响。

创建,切换,合并分支

相关命令:

git branch 新分支的名称  //创建一个新分支

git checkout 要进入的分支名 //切换到目标分支工作

git checkout -b 新的分支名 //创建分支并在切换到这个分支下

git merge 要合并的分支名 //合并分支

git branch //查看所有分支以及当前工作分支

实操:

图形化模拟一下分支过程:

总结一下:

  • HEAD指向的是当前工作分支,控制Git的工作对象
  • master,dev等存放的是当前分支的最新版本的commit对象的哈希值,HEAD指向的就是他们
  • 两个分支不论各自提交多少次,都能沿着commit对象中的parent指针回到开始分支时的commit对象,也就是说,多个分支相当于树的多个分叉。
  • 合并之前各分支不会看到对方的修改
  • 分支合并如果一方没有修改,那这一方就直接指向修改了的分支的最新commit对象,这样合并会很快

删除分支

相关命令:

git branch -d 要删除的分支名
git branch -D 要删除的分支名 //分支有提交未被合并是不可以直接删除的,需要用D选项

实操:

解决分支合并冲突

如果两个分支修改了同一行内容,那么在合并分支的时候git并不知道要保留谁,因此就会产生冲突,此时我们需要手动解决冲突然后在进行一次提交

实操:

补充可以查看分支提交与合并状况的图形化界面的命令:

分支合并模式

分支合并模式有两种,一种是Fast-Forward模式,一种是非Fast-Forward模式。

  • 一般来说,Fast-Forward用于一个分支修改了,另一个分支没有修改的情况,那么此时合并就是把没有修改的分支对应的最新commit对象更换为修改了的分支对应的最新commit对象。不会也没必要创建新的commit对象
  • 而一般多个分支都有修改的情况用非Fast-Forward模式,会创建一个新的commit对象

在log中,看不出来Fast-Forward合并和普通master分支提交的区别,这样就会导致分支上的所有提交和主分支提交混在一起,难以区分(一般来说一个分支就是一个功能,混在一起的话要剥离出来就比较麻烦)

因此无论有没有必要,最好都使用非Fast-Forward模式进行合并,有利于团队协作,强制指定Git进行非Fast-Forward合并命令如下:

git merge -no-ff -m "提交信息" 要合并的分支名

分支不隔离

分支隔离的原理是,进入某分支后,把当前分支最新的commit对象的内容覆盖到暂存区,工作区,因此我们在两个分支看到的内容是不一样的

但假如工作区、暂存区有修改未提交(这两个区域是共享的),转换分支后就不会触发上述机制,因为Git要尽可能保护我们的修改内容不丢失,因此两个分支修改的内容就会混在一起,失去了隔离性(谁提交修改就算在谁头上)。

解决这个问题的方法就是Git提供的相关命令:

//将工作区的被git追踪管理了(add之后)的并且做出了修改的文件的修改保存到git仓库中的某文件中
//然后删除修改的内容,工作区此时是干净的
git stash

//查看本分支stash文件的内容有什么
git stash list

//切换回本分支后再把内容拷贝到工作区
git stash pop

这种情况常见于:当开发一个新功能还未提交的时候,主分支突然出现了bug,修复bug的时候不希望看到新功能的代码。或者说开发者在开发过程中想看一眼修改之前的代码

实操:

优秀Git管理示范例子:


Git远程操作

到目前为止,我们都是在自己的电脑上进行版本控制,但无法多人协作开发(虽然说有分支的机制,但是总不可能两个人用一台电脑交换着开发吧)。

Git提供一个中央服务器(充当用户的远程仓库),他有如下用处:

  • 代码云端存储,本地丢失后还能恢复
  • 同一个仓库可以被多个用户克隆到本地,实现多用户协同开发:各个用户在本地仓库进行开发每个用户都可以把自己的仓库修改的部分推送到远程仓库,其他用户可以把远程仓库的代码拉取到本地仓库,这就实现了数据同步。

创建远程仓库

  • README 文件:选中该选项后,Git 会在仓库根目录自动生成一个标准的 README 模板文件。项目维护者可以在文件中详细说明程序的功能、使用方法、运行环境、编译步骤等关键信息;其他使用者查看仓库时,能通过阅读这份文件快速了解项目并正确使用程序。
  • Issue 模板文件:Git 仓库自带一个问题反馈模块,使用者可以在这里提交使用疑问、功能建议或发现的 Bug。项目维护者收到反馈后,会进行答疑和问题修复。如果勾选 Issue 模板,使用者提交问题时会自动套用固定格式,让反馈内容更规范、信息更完整,方便维护者快速定位和解决问题。
  • Pull Request 模板文件:master 是项目的主发布分支,必须保持稳定可用,不能直接合并代码。若要将新功能或修复内容合并到 master,必须先提交合并申请,经过管理员审核通过后才能合并,避免直接合并引入 Bug 导致项目无法使用。勾选该模板后,提交合并申请时会自动生成规范格式,让修改内容、目的、测试情况更清晰,降低审核成本。

创建完成结果如下:

点开.gitee目录,可以发现两个文件:

点开看看这两个文件的内容:

克隆远程仓库到本地

Https协议克隆实操:

SSH协议克隆实操:

理解远程推送和拉取

在讲解本地仓库向远程仓库推送修改/拉取修改(也就是本地和远程的数据同步)之前,我想先让读者理解一件事情:无论是拉取还是推送,都是本地分支对应的commit链->远程分支对应的commit链,而不是仓库->仓库(即,不是说一拉取本地仓库就合远程仓库一模一样了)。下面我举几个例子来帮助读者理解这个问题:

关于拉取,我想放到下面再具体解释

向远程仓库推送

相关命令:

//eg. git push origin master:master   (origin是远程仓库的默认名字)
git push [要操作的远程仓库名] [要推送的本质分支名]:[要把分支推送给远程的哪个分支]

//如果本地仓库的某分支和远程仓库的某分支已经建立了关联,那么我们可以直接进行push操作,这次的话会尝试对所有有关联关系的分支进行变动的推送,本地和远程的master分支是自动关联的
git push

//查看哪些分支之间有关联关系
git branch -vv

//让本地某分支和远程仓库某分支建立关联关系
git branch --set-upstream-to origin/分支名

什么是关联关系:

我们已经知道,都是本地分支对应的commit链->远程分支对应的commit链之间的操作,所以一般我们要推送就要写很长的命令:“git push [要操作的远程仓库名] [要推送的本质分支名]:[要把分支推送给远程的哪个分支]”。但如果本地分支和远程仓库建立起一一对应的关系,那么只需要使用git push,git也就知道要把那个分支推送向哪个远程分支了。

实操:

可以再举个例子:

拉取远程仓库内容

要理解拉取,首先要明白一件事:本地仓库中包含了远程仓库的快照。下面简单说明一下:

相关命令:

//把远程的所有分支的变动一次性拉取到本地创建的远程仓库的快照中,但是不会对本地仓库做出任何修改!
git fetch


//这个命令可以让我们看到本地包括远程仓库的快照中的所有分支
git branch -a 


//把远程某分支的commit链拉取下来并与本地的某分支合并
git pull [要操作的远程仓库名] [要从远程仓库拉取的分支名]:[本地仓库的某分支名]


//这个命令,只会做一件事:把当前所在分支对应的远程仓库中的某分支拉取下来,并与当前分支合并。注意,git pull针对的是当前分支而不是关联了的所有分支(这个和git push不一样),也就是说假设现在本地仓库的当前分支没有关联任何远程分支,git pull就会失败,即使其他本地分支与远程分支有关联关系
git pull

实操:

了解一下.gitignore文件

没错,我们之前遇到过这个,就是在创建远程仓库的时候勾选一个选项就可以让远程仓库自动生成与某种语言相匹配的.gitignore文件,它的作用就是告诉本地仓库哪些文件你不要去管他比如我刚才选的是C++类型的.gitignore文件,它的内容如下:

在克隆远程仓库的时候,这个文件也是被克隆下来的:

当然,我们也可以在本地仓库自己编写一个名字是.gitignore的文件,同样会生效

实操:

如果你想给一个文件免死金牌,就是强制添加(管理)它,有两种方式:

  • git add -f 文件名(即,加-f选项)
  • 在.gitignore文件中添加一行:![文件名]

实操:

还可以通过命令查看某文件是因为ignore文件中的哪一行而被忽略:


标签管理

标签就是给某一次提交的hash值取一个别名,这样一来就可以不用查找或记忆它的hash值就能操作本次提交。

操作标签

相关命令:

//给提交取别名,如果要为最新提交打标签,可以省略最后一个参数
git tag [标签名] [要取别名的版本的hash值]

//查看当前的所有标签
git tag 

//在打标签的同时给这个标签添加一些描述
git tag -a [标签名] -m "对这个标签的描述" [要取别名的版本的hash值]

//显示标签以及标签对应的版本的详细信息,包括对这个标签的描述等
git show [标签名]


//删除一个标签
git tag -d [标签名]

实操:

给远程仓库推送标签

相关命令:

//推送某个标签
git push origin [标签名]

//推送所有标签到远程
git push origin --tags

//删除远程仓库中的某标签
git push origin :[标签名]

实操:


附录

会看git diff命令的输出

  • a/xxx 表示修改之前的文件,b/xxx表示修改之后的文件,ab符号用来区分旧文件和新文件。
  • 445a69c:旧文件在 Git 中的哈希值(blob 对象 ID)。
  • 4f8b653:新文件的哈希值。
  • 100644:文件权限,100 表示普通文件,644 表示所有者可读可写、其他用户只读(这样的权限表示方式Bash中也用到)。
  • --- a/dir1/profile2  +++ b/dir1/profile2 :说明-代表修改之前的文件,+代表修改之后的文件
  • -1:表示旧文件从第 1 行开始,有 1 行内容被修改 / 删除。
  • +1,4:表示新文件从第 1 行开始,有 4 行内容被修改 / 添加。
  • 红色 - 开头的行:表示旧文件中被删除的内容,这里是删除了 hahaha 这一行。
  • 绿色 + 开头的行:表示新文件中新增 / 替换的内容,这里是新增了 hahxixixkkk666 四行。

会看git reflog日志

整行输出分为 四大核心字段,从左到右依次为:短哈希值、括号、操作序号、操作类型、操作描述,下面逐一拆解。

一、短哈希值(abc1234)

每一次 Git 操作对应的唯一提交标识,是版本还原的核心依据。我们恢复丢失代码、回退指定版本时,直接复制该哈希值即可。如果需要完整哈希值,可执行 git reflog --full 查看。

二、括号

括号中一般是指向当前版本的分支,或者是当前版本对应的标签

三、操作序号(HEAD@{n})

代表本地操作的时间顺序,是 reflog 最具辨识度的标识:

  • HEAD@{0}:最近一次的本地操作;

  • HEAD@{1}:上一次操作;

  • HEAD@{2}:上上次操作;

简单记:数字越大,操作时间越早。

四、操作类型(commit/reset/checkout)

记录当前行对应的 Git 操作命令,常见类型如下:

  • commit:本地新建代码提交;

  • reset:执行了版本回退操作;

  • checkout:切换分支或切换代码版本;

  • merge:执行了分支合并操作;

  • rebase:执行了变基操作;

  • pull:拉取远程仓库代码。

五、操作描述

对当前操作的补充说明:提交操作会显示自定义的提交备注,重置操作会显示回退目标,切换分支操作会显示切换的源分支和目标分支,直观还原操作场景。

会看git log --graph --abbrev-commit 的输出

这个命令就是以图形化方式显示出当前所在分支(不是所有分支哦)commit提交链

*号代表的是一次提交,红绿色的线条代表的是分支。

给命令取别名

相关命令:

git config alias.[别名] '[被取别名的命令或选项]'

//在config后面加上--global就是全局配置

实操:

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐