目录
一:Git的基本认识
1.实例引入
在日常当中我们常常会遇到这样的事,就是在做实验报告或者课设的时候,往往是一次性不能让老师满意的,需要我们反复的修改,如果有这样的情况,就是你的每次实验报告都是在上次的报告里直接修改的,没有对上次的实验报告进行保存,如果改到最后,老师让你拿前面写的实验报告的话,此时你肯定会拿不出来,因此为了防止这样的事情发生你需要保存每次修改的实验报告,但如果保存的次数多的话,对于每个版本都修改了什么,就会很容易导致不知道,对于项目中的代码也是如此
为了解决上述问题,就提出了版本控制器,用来记录每个版本的修改以及管理这些版本,而最主流的版本控制器就是Git
Git的再次认识:
Git是一个分布式版本控制系统,可以记录文件的修改历史,方便用户查看不同时间的版本
二:Git的安装
1.在Linux的centos下安装
查看在Linux下安装的Git版本: git --version
没有安装的话,就会显示找不到,安装有Git的话,就会显示对应的Git版本
卸载Git :sudo yum remove git -y
安装Git: sudo yum install git -y
2.在Linux的ubuntu下安装
查看安装的Git的版本: git --version
卸载Git : sudo apt-get remove git -y
安装Git : sudo apt-get install git -y
三:Git的基本操作
1.创建本地仓库
创建本地仓库的原因:经过上面的介绍,可以得知Git是一个版本控制器.如果想要对电脑/服务器上的文件进行一些记录,如修改的内容,版本迭代的详细内容时,就可以使用Git来追踪管理,但如果追踪或管理的文件在电脑/服务器的任意位置的话,Git是不能进行追踪管理的,要想追踪管理的话,就需要将文件放在Git的仓库当中,在仓库中的文件才能被Git追踪管理。即仓库是进⾏版本控制的⼀个⽂件⽬录。我们要想对⽂件进⾏版本控制,就必须先创建⼀个仓库出来。
在一个文件目录下创建仓库的操作
创建⼀个Git本地仓库对应的命令: git init
[mjwl@hcss-ecs-889f ~]$ mkdir gitcode #创建目录
[mjwl@hcss-ecs-889f ~]$ cd gitcode
[mjwl@hcss-ecs-889f gitcode]$ git init #创建本地仓库
Initialized empty Git repository in /home/mjwl/gitcode/.git/
[mjwl@hcss-ecs-889f gitcode]$ ls -la
total 12
drwxrwxr-x 3 mjwl mjwl 4096 Oct 15 23:22 .
drwx------ 15 mjwl mjwl 4096 Oct 15 23:22 ..
drwxrwxr-x 7 mjwl mjwl 4096 Oct 15 23:22 .git
[mjwl@hcss-ecs-889f gitcode]$ tree .git
.git
├── branches
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
当前⽬录下多了⼀个 .git 的隐藏⽂件, .git ⽬录是Git来跟踪管理仓库的
2.配置Git
当安装Git后⾸先要做的事情是设置你的⽤⼾名称和e-mail地址,这是⾮常重要的,如果不配置的话,在后面对本地仓库进行操作时就会出现一系列的问题以及报错
配置指令
git config (--global) user.name "对应用户名"
git config (--global) user.email "用户名对应邮箱"
查看配置选项的指令
git config -l
删除对应的配置选项指令
git config (--global) --unset user.name
git config (--global) --unset user.email
对应的--global是⼀个可选项。如果使⽤了该选项,表⽰这台机器上所有的Git仓库都会使⽤这个
配置,若配置时带--global的话,删除时必须带--global
3.⼯作区、暂存区、版本库
引例:在对应的有.git的本地仓库目录下创建一个普通的文件
[mjwl@hcss-ecs-889f gitcode]$ touch readme
[mjwl@hcss-ecs-889f gitcode]$ ls -a
. .. .git readme
此时是否可以直接使用Git来管理readme文件,答案是不可以,需要经过add和commit两步
⼯作区:在电脑上要写代码或⽂件的⽬录,此处readme文件所在的gitcode目录成为工作区
暂存区:英⽂叫stage或index。⼀般存放在 .git ⽬录下的index⽂件(.git/index)中,我们
把暂存区有时也叫作索引(index)
版本库:⼜名仓库,⼯作区有⼀个隐藏⽬录 .git ,它不算⼯作区,⽽是Git的版本库。这个版本库⾥⾯的所有⽂件都可以被Git管理起来,每个⽂件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”
三者之间的关系:
注:(1)在创建Git版本库时,Git会为我们⾃动创建⼀个唯⼀的master分⽀,以及指向master的⼀个指针叫HEAD
(2)通过新建或粘贴进⽬录的⽂件,并不能称之为向仓库中新增⽂件,⽽只是在⼯作区新增了⽂件。必须要通过使⽤ git add 和 git commit 命令才能将⽂件添加到仓库中进⾏管理
1.git add 与git commit操作
添加⼀个或多个⽂件到暂存区: git add file1 (file2) (file3) ...
添加指定⽬录到暂存区,包括⼦⽬录: git add dir
添加当前⽬录下的所有⽂件改动到暂存区: git add .
提交暂存区全部内容到本地仓库中: git commit -m "日志"
提交暂存区的指定⽂件到仓库区: git commit (file1) (file2)... -m "日志'
查看历史提交记录: git log /git log --pretty=oneline
我们看到的⼀⼤串类似 23807c5...56eed6 的是每次提交的 commit id (版本号),Git的 commit id 不是1,2,3……递增的数字,⽽是⼀个SHA1计算出来的⼀个⾮常⼤的数字,⽤⼗六进制表⽰
2.查看.git文件
我们先来查看.git的目录结构
[mjwl@hcss-ecs-889f gitcode]$ tree .git
.git
├── branches
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
在上述的readme文件中写入对应内容,通过git add和git commit操作将工作区的修改内容添加到本地仓库当中,再tree .git查看.git文件
[mjwl@hcss-ecs-889f gitcode]$ vim readme
[mjwl@hcss-ecs-889f gitcode]$ cat readme
hello git
[mjwl@hcss-ecs-889f gitcode]$ git add .
[mjwl@hcss-ecs-889f gitcode]$ git commit -m "add file"
[master (root-commit) 989741d] add file
1 file changed, 1 insertion(+)
create mode 100644 readme
[mjwl@hcss-ecs-889f gitcode]$ tree .git
.git
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ └── master
├── objects
│ ├── 6e
│ │ └── 84d6a5ed71a327ba3376cac9801558d9ea2e80
│ ├── 8d
│ │ └── 0e41234f24b6da002d962a26c2495ea16a425f
│ ├── 98
│ │ └── 9741d5c4d2f8a9ef91ad5343bc04eedcdb0288
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
└── tags
1).index 就是我们的暂存区,add后的内容都是添加到这⾥的。
2). HEAD 就是我们的默认指向master分⽀的指针,我们可以查看一下
[mjwl@hcss-ecs-889f gitcode]$ cat .git/HEAD
ref: refs/heads/master
那么上述HEAD指针指向的master中保存的是什么呢?
[mjwl@hcss-ecs-889f gitcode]$ cat .git/refs/heads/master
989741d5c4d2f8a9ef91ad5343bc04eedcdb0288
保存的就是当前最新的 commit id ,此时我们此时来打印日志来确认的
[mjwl@hcss-ecs-889f gitcode]$ git log
commit 989741d5c4d2f8a9ef91ad5343bc04eedcdb0288
Author: mjw <[email protected]>
Date: Wed Oct 16 19:07:56 2024 +0800
add file
而一个commit id也可以看作一个git对象 ,我们可以来打印一下这个git对象中的内容
[mjwl@hcss-ecs-889f gitcode]$ git cat-file -p 989741d5c4d2f8a9ef91ad5343bc04eedcdb0288
tree 6e84d6a5ed71a327ba3376cac9801558d9ea2e80
author mjw <[email protected]> 1729076876 +0800
committer mjw <[email protected]> 1729076876 +0800
add file
其中的parent后面的commit id是上次提交的commit id
对于打印的第一行还有个commit id,我们使用相同的方法进行查看得
[mjwl@hcss-ecs-889f gitcode]$ git cat-file -p 6e84d6a5ed71a327ba3376cac9801558d9ea2e80
100644 blob 8d0e41234f24b6da002d962a26c2495ea16a425f readme
//对readme文件对应的commit id进行查看得
[mjwl@hcss-ecs-889f gitcode]$ git cat-file -p 8d0e41234f24b6da002d962a26c2495ea16a425f
hello git //这就是对readme文件的修改,在这里都被git保存了下来
每个提交的文件都对应一个commit id,commit id也是可以作为一种索引的,可以使用 git cat-file -p来查看这个索引所对应git对象中的内容,这个git对象也是被维护在对象库当中的,里面包含的是修改的内容
3).objects为Git的对象库,⾥⾯包含了创建的各种版本库对象及内容。当执⾏git add 命令时,暂存区的⽬录树被更新,同时⼯作区修改(或新增)的⽂件内容被写⼊到对象库中的⼀个新的
对象中,就位于".git/objects"⽬录下 ,我们可以查看得
[mjwl@hcss-ecs-889f gitcode]$ ls .git/objects/
6e 8d 98 info pack
查找object时要将 commit id 分成2部分,其前2位是⽂件夹名称,后38位是⽂件名称
总结在本地仓库中的几个特殊文件/目录
index:暂存区, git add 后会更新该内容。
• HEAD:默认指向master分⽀的⼀个指针。
• refs/heads/master:⽂件⾥保存当前 master 分⽀的最新 commit id 。
• objects:包含了创建的各种版本库对象及内容,可以简单理解为放了git维护的所有修改
3).对添加文件的再次理解
[mjwl@hcss-ecs-889f gitcode]$ touch file1
[mjwl@hcss-ecs-889f gitcode]$ git add file1
[mjwl@hcss-ecs-889f gitcode]$ touch file2
[mjwl@hcss-ecs-889f gitcode]$ git commit -m "add file"
[master bce0eaf] add file
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file1
这里是新增两个文件,但改变的只有一个文件,这是因为 git add 是将⽂件添加到暂存区, git commit 是将暂存区的内容添加到本地仓库中 ,但我们没有进行git add file2,因此file2文件不被暂存区所维护的。所要解决的话,就是再执行git add file2 和git commit 操作
4. 修改文件
在这里我们可以在readme文件中新增一行,新增后我们该如何查看当前仓库的状态呢?
git status 命令⽤于查看在你上次提交之后是否有对⽂件进⾏再次修改
git diff [file] 命令⽤来显⽰暂存区和⼯作区⽂件的差异,显⽰的格式正是Unix通⽤的diff格
式。也可以使⽤ git diff HEAD -- [file] 命令来查看版本库和⼯作区⽂件的区别
当使用git diff命令后就可以查看到文件具体哪些地方做了修改,然后在进行git add和git commit操作提交到master分支下被Git追踪管理
[mjwl@hcss-ecs-889f gitcode]$ git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: readme
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# file2
no changes added to commit (use "git add" and/or "git commit -a")
[mjwl@hcss-ecs-889f gitcode]$ git add .
[mjwl@hcss-ecs-889f gitcode]$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: file2
# modified: readme
#
git add 之后,就没有看到上⾯ no changes added to commit (use "git add"and/or "git commit -a") 的消息了。接下来让我们继续? git commit 即可
5.版本回退
Git是一个版本控制器,是可以管理文件的历史版本的,如果有需要是可以回退到以前的版本的,对应命令为 git reset,可以指定回退到某个提交的版本,接下来介绍具体的语法与用法
git reset 命令语法格式为: git reset [--soft | --mixed | --hard] [HEAD]
HEAD 说明:
◦ 可直接写成commit id,表⽰指定退回的版本
◦ HEAD 表⽰当前版本
◦ HEAD^ 上⼀个版本
◦ HEAD^^ 上上⼀个版本
◦ 以此类推...
可以使⽤ 〜数字表⽰:
◦ HEAD~0 表⽰当前版本
◦ HEAD~1 上⼀个版本
◦ HEAD^2 上上⼀个版本
◦ 以此类推...
对于上述的readme文件,第一版只有hello git,第二版(当前版本)是有hello git 和hello world,我们以此为例
实例二:
这时就不能根据commit id 进行回退了,因此我们可以采用git reflog来查询commit id进行回退,reflog是用来记录本地每次提交的命令
Git的版本回退速度⾮常快,因为Git在内部有个指向当前分⽀(此处是master)的HEAD指针, refs/heads/master ⽂件⾥保存当前 master 分⽀的最新 commit id 。当我们在回退版本的时候,Git仅仅是给refs/heads/master 中存储⼀个特定的version ,可以理解为以下的图
6.撤销修改
当我们不想操作当前版本,想直接回退到上个版本开始操作
对于撤销回退是分为三种情况的
情况⼀:对于⼯作区的代码,还没有 add
情况⼆:已经 add ,但没有 commit
情况三:已经 add ,并且也 commit 了(还没有进行push操作)
在这里在readme文件中添加一行xxx code的内容,具体这三种情况的解决方法为
git checkout -- [file] 命令让⼯作区的⽂件回到最近⼀次 add 或 commit 时的状态
7.删除文件
因为删除也是对文件的修改,所以删除文件有两种方式
1.使用rm命令删除文件,还需要 git add和git commit操作
2.使用git rm命令删除文件,再进行git commit操作