【Git】一文看懂Git


Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。

参考:https://www.runoob.com/git/git-tutorial.html


一、简介

1. Git 与 SVN 区别

Git 不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。

1.1 Git 是分布式的,SVN 不是

这是 Git 和其它非分布式的版本控制系统,例如 SVN,CVS 等,最核心的区别。

1.1.1 分布式版本控制系统Git
  • 本地完整版本库:每个开发者的本地工作目录都是一个完整的版本库,包含了项目的所有历史记录。这意味着即使没有网络连接,开发者也可以在本地进行所有的版本控制操作(如提交、分支、合并等)。
  • 本地操作:开发者可以在本地进行提交(commit),这些提交只会影响本地版本库。只有在开发者主动推送(push)变更时,远程仓库才会更新。
  • 协作方式:开发者之间通过推送(push)和拉取(pull)来共享变更。每个开发者的本地仓库都是独立的,只有在需要时才与远程仓库同步。
1.1.2 集中式版本控制系统SVN
  • 中央版本库:所有的版本历史记录都存储在中央服务器上。开发者的本地工作目录只是当前版本的一个副本,不包含完整的历史记录。
  • 依赖网络:开发者需要从中央服务器检出(checkout)代码,进行修改后再提交(commit)到服务器。提交操作需要网络连接,因为所有的变更都直接提交到中央服务器。
  • 协作方式:所有开发者都在同一个中央版本库上进行操作,变更会立即反映在中央服务器上。开发者需要频繁地更新(update)本地工作目录,以获取其他人的最新变更。

1.2 Git 把内容按元数据方式存储,而 SVN 是按文件

  1. Git:将文件的内容存储为快照(snapshot),每次提交时,Git会保存项目的当前状态,并生成一个唯一的SHA-1哈希值作为标识。Git的元数据存储在.git目录中。
  2. SVN:按文件存储,每个文件和目录都有一个版本号,元信息存储在.svn目录中。

1.3 Git 分支和 SVN 的分支不同

  1. Git:分支是轻量级的,创建和切换分支非常快速。分支是项目的一个指针,指向某个提交对象。
  2. SVN:分支实际上是版本库中的一个目录,创建分支相当于复制整个项目目录,因此操作相对较慢。

1.4 Git 没有一个全局的版本号,而 SVN 有

  1. Git:每次提交都会生成一个唯一的SHA-1哈希值作为标识,但没有一个全局递增的版本号。
  2. SVN:每次提交都会生成一个全局唯一的递增版本号,整个版本库的状态可以通过这个版本号来标识。

1.5 Git 的内容完整性要优于 SVN

Git 的内容存储使用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
在这里插入图片描述

二、Git工作流程

在这里插入图片描述

1. 克隆仓库

如果你要参与一个已有的项目,首先需要将远程仓库克隆到本地:

git clone https://github.com/username/repo.git
cd repo

2. 创建新分支

为了避免直接在 main 或 master 分支上进行开发,通常会创建一个新的分支:

git checkout -b new-feature

3. 工作目录

在工作目录中进行代码编辑、添加新文件或删除不需要的文件。

4. 暂存文件

将修改过的文件添加到暂存区,以便进行下一步的提交操作:

git add filename
# 或者添加所有修改的文件
git add .

5. 提交更改

将暂存区的更改提交到本地仓库,并添加提交信息:

git commit -m "Add new feature"

6. 拉取最新更改

在推送本地更改之前,最好从远程仓库拉取最新的更改,以避免冲突:

git pull origin main
# 或者如果在新的分支上工作
git pull origin new-feature

7. 推送更改

将本地的提交推送到远程仓库:

git push origin new-feature

8. 创建 Pull Request(PR)

在 GitHub 或其他托管平台上创建 Pull Request,邀请团队成员进行代码审查。PR 合并后,你的更改就会合并到主分支。

9. 合并更改

在 PR 审核通过并合并后,可以将远程仓库的主分支合并到本地分支:

git checkout main
git pull origin main
git merge new-feature

10. 删除分支

如果不再需要新功能分支,可以将其删除:

git branch -d new-feature

或者从远程仓库删除分支:

git push origin --delete new-feature

三、Git工作区、暂存区和版本库

1. 基本概念

我们先来理解下 Git 工作区、暂存区和版本库概念:

  • 工作区:就是你在电脑里能看到的目录。
  • 暂存区:英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
  • 版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。
    下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:
    在这里插入图片描述
  • 图中左侧为工作区,右侧为版本库。在版本库中标记为 “index” 的区域是暂存区(stage/index),标记为 “master” 的是 master 分支所代表的目录树。
  • 图中我们可以看出此时 “HEAD” 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
  • 图中的 objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,里面包含了创建的各种对象及内容。
  • 当对工作区修改(或新增)的文件执行 git add 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
  • 当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
  • 当执行 git reset HEAD 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
  • 当执行 git rm --cached <file> 命令时,会直接从暂存区删除文件,工作区则不做出改变。
  • 当执行 git checkout . 或者 git checkout -- <file> 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区中的改动。
  • 当执行 git checkout HEAD . 或者git checkout HEAD <file>命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

1.1 工作区(Working Directory)

工作区是你在本地计算机上的项目目录,你在这里进行文件的创建、修改和删除操作。工作区包含了当前项目的所有文件和子目录。

特点:

  • 显示项目的当前状态。
  • 文件的修改在工作区中进行,但这些修改还没有被记录到版本控制中。

1.2 暂存区(Staging Area)

暂存区是一个临时存储区域,它包含了即将被提交到版本库中的文件快照,在提交之前,你可以选择性地将工作区中的修改添加到暂存区。

特点:

  • 暂存区保存了将被包括在下一个提交中的更改。
  • 你可以多次使用git add命令来将文件添加到暂存区,直到你准备好提交所有更改。

常用命令:

git add filename # 将单个文件添加到暂存区
git add . # 将工作区中的所有修改添加到暂存区
git status # 查看哪些文件在暂存区中

1.3 版本库(Repository)

版本库包含项目的所有版本历史记录。

每次提交都会在版本库中创建一个新的快照,这些快照是不可变的,确保了项目的完整历史记录。

特点:

  • 版本库分为本地版本库和远程版本库。这里主要指本地版本库。
  • 本地版本库存储在 .git 目录中,它包含了所有提交的对象和引用。

常用命令:

git commit -m "Commit message" # 将暂存区的更改提交到本地版本库
git log # 查看提交历史
git diff # 查看工作区和暂存区之间的差异
git diff --cached # 查看暂存区和最后一次提交之间的差异

2. 工作区、暂存区和版本库之间的关系

2.1 工作区 -> 暂存区

使用 git add 命令将工作区中的修改添加到暂存区。

git add filename

2.2 暂存区 -> 版本库

使用 git commit 命令将暂存区中的修改提交到版本库。

git commit -m "Commit message"

2.3 版本库 -> 远程仓库

使用 git push 命令将本地版本库的提交推送到远程仓库。

git push origin branch-name

2.4 远程仓库 -> 本地版本库

使用 git pull 或 git fetch 命令从远程仓库获取更新。

git pull origin branch-name
# 或者
git fetch origin branch-name
git merge origin/branch-name

四、Git 创建仓库

1. git init

Git 使用 git init 命令来初始化一个 Git 仓库。
在执行完成 git init 命令后,Git 仓库会生成一个 .git 目录,该目录包含了资源的所有元数据,其他的项目目录保持不变。

1.1 使用方法

git init

该命令执行完后会在当前目录生成一个 .git 目录。所有 Git 需要的数据和资源都存放在这个目录中。
如果当前目录下有几个文件想要纳入版本控制,需要先用 git add 命令告诉 Git 开始对这些文件进行跟踪,然后提交.

: 在 Linux 系统中,commit 信息使用单引号',Windows 系统,commit 信息使用双引号 "
所以在 git bash 中 git commit -m '提交说明' 这样是可以的,在 Windows 命令行中就要使用双引号 git commit -m "提交说明"

2. git clone

使用 git clone 从现有 Git 仓库中拷贝项目(类似 svn checkout)。
克隆仓库的命令格式为:

git clone <repo>

克隆到指定的目录,可以使用以下命令格式:

git clone <repo> <directory>

参数说明:

  • repo:Git 仓库。
  • directory:本地目录。

3. git config

git 的设置使用 git config 命令。

显示当前的 git 配置信息:

$ git config --list
credential.helper=osxkeychain
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true

编辑 git 配置文件:

$ git config -e # 针对当前仓库
或者
$ git config -e --global # 针对系统上所有仓库

设置提交代码时的用户信息:

$ git config --global user.name "runoob"
$ git config --global user.email test@runoob.com
如果去掉 --global 参数只对当前仓库有效。

五、Git基本操作

Git 的工作就是创建和保存你项目的快照及与之后的快照进行对比。
Git 常用的是以下 6 个命令:git clonegit pushgit addgit commitgit checkoutgit pull
在这里插入图片描述
说明

  • workspace:工作区
  • staging area:暂存区/缓存区
  • local repository:版本库或本地仓库
  • remote repository:远程仓库

1. 提交与修改

1.1 git add

添加文件到暂存区

  1. 添加一个或多个文件到暂存区:
    git add [file1] [file2] ...

  2. 添加指定目录到暂存区,包括子目录:
    git add [dir]

  3. 添加当前目录下的所有文件到暂存区:
    git add .

1.2 git status

查看仓库当前的状态,显示有变更的文件。

$ git status
On branch master

Initial commit

Changes to be committed:
(use “git rm --cached <file>…” to unstage)

new file: README
new file: hello.php

git status 命令会显示以下信息:

  • 当前分支的名称。
  • 当前分支与远程分支的关系(例如,是否是最新的)。
  • 未暂存的修改:显示已修改但尚未使用 git add 添加到暂存区的文件列表。
  • 未跟踪的文件:显示尚未纳入版本控制的新文件列表。

1.3 git diff

比较文件的不同,即暂存区和工作区的差异。

  1. 显示暂存区和工作区的差异:
    git diff [file]

  2. 显示暂存区和上一次提交(commit)的差异:
    git diff --cached [file]git diff --staged [file]

  3. 显示两次提交之间的差异:
    git diff [first-branch]...[second-branch]

1.4 git difftool

使用外部差异工具查看和比较文件的更改。

  1. 查看当前工作目录中的更改与最近提交之间的差异:
    git difftool

  2. 查看暂存区中的更改与最近提交之间的差异:
    git difftool --staged

  3. 查看指定文件的更改:
    git difftool [file]

  4. 使用指定工具查看差异
    使用 meld 工具查看差异(需要在 Git 配置中设置 meld 为差异工具):
    git difftool --tool=meld

  5. 在目录中查看更改,而不是逐个文件:
    git difftool --dir-diff

  6. 跳过确认提示
    自动打开工具查看所有文件的差异,而不进行确认:
    git difftool --no-prompt

1.5 git commit

提交暂存区到本地仓库。

  1. 提交暂存区到本地仓库中:
    git commit -m 'message'
    message是备注信息。

  2. 提交暂存区的指定文件到仓库区:
    git commit [file1] [file2] ... -m 'message'
    -a 参数设置修改文件后不需要执行 git add 命令,直接来提交
    git commit -a

1.6 git reset

回退版本。

git reset [--soft | --mixed | --hard] [HEAD]

  • --mixed 为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变。
    --soft 参数用于回退到某个版本
    --hard 参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交

$ git reset HEAD^ # 回退所有内容到上一个版本
$ git reset HEAD^ hello.php # 回退 hello.php 文件的版本到上一个版本
$ git reset 052e # 回退到指定版本

$ git reset --soft HEAD~3 # 回退上上上一个版本

$ git reset --hard HEAD~3 # 回退上上上一个版本
$ git reset –hard bae128 # 回退到某个版本回退点之前的所有信息。
$ git reset --hard origin/master # 将本地的状态回退到和远程的一样

谨慎使用 –-hard 参数,它会删除回退点之前的所有信息。

HEAD 说明:

  • HEAD 表示当前版本
  • HEAD^ 上一个版本
  • HEAD^^ 上上一个版本
  • HEAD^^^ 上上上一个版本

可以使用 ~数字表示:

  • HEAD~0 表示当前版本
  • HEAD~1 上一个版本
  • HEAD^2 上上一个版本
  • HEAD^3 上上上一个版本

1.7 git rm

将文件从暂存区和工作区中删除。
如果只是简单地从工作目录中手工删除文件,运行 git status 时就会在 Changes not staged for commit 的提示。

  1. 将文件从暂存区和工作区中删除:
    git rm [file]
    如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f

  2. 如果想把文件从暂存区域移除,但仍然希望保留在当前工作目录中,换句话说,仅是从跟踪清单中删除,使用 --cached 选项即可:
    git rm --cached [file]

  3. 可以递归删除,即如果后面跟的是一个目录做为参数,则会递归删除整个目录中的所有子目录和文件:
    git rm –r *

1.8 git mv

移动或重命名工作区文件。
git mv [file] [newfile]
如果新文件名已经存在,但还是要重命名它,可以使用 -f 参数:
git mv -f [file] [newfile]

1.9 git checkout

分支切换。

注意:git checkout 命令在 Git 2.23 版本后引入了 git switch 和 git restore 命令,分别用于分支切换和文件恢复,以提供更清晰的语义和错误检查。如果你使用较新的 Git 版本,可以考虑使用这些命令代替 git checkout。

  1. 从当前分支切换到指定的分支 [branch-name]:
    git checkout [branch-name]

  2. 创建一个新分支 [new-branch-name] 并立即切换到新创建的分支:
    git checkout -b [new-branch-name]

  3. 切换回前一个分支,无需记住分支名称:
    git checkout -

  4. 将指定文件 [file] 恢复到最新的提交状态,丢弃所有未提交的更改,这对于撤销不需要的更改非常有用:
    git checkout -- [file]

  5. 切换到特定提交:
    你可以使用提交的哈希值 [commit-hash] 来切换到特定的提交状态。这将使你进入"分离头指针"状态,只能查看历史记录,而不能进行分支操作。通常情况下,不建议在分离头指针状态下工作,因为更改可能会丢失。
    git checkout [commit-hash]

  6. 切换到标签:
    如果你有一个标签 [tag-name],你可以使用这个命令来切换到该标签所指向的提交状态。
    git checkout tags/[tag-name]

2. 提交日志

2.1 git log

查看历史提交记录
git log [选项] [分支名/提交哈希]

3. 远程操作

3.1 git remote

远程仓库操作

  • git remote:列出当前仓库中已配置的远程仓库。
  • git remote -v:列出当前仓库中已配置的远程仓库,并显示它们的 URL。
  • git remote add <remote_name> <remote_url>:添加一个新的远程仓库。指定一个远程仓库的名称和 URL,将其添加到当前仓库中。
  • git remote rename <old_name> <new_name>:将已配置的远程仓库重命名。
  • git remote remove <remote_name>:从当前仓库中删除指定的远程仓库。
  • git remote set-url <remote_name> <new_url>:修改指定远程仓库的 URL。
  • git remote show <remote_name>:显示指定远程仓库的详细信息,包括 URL 和跟踪分支。

3.2 git fetch

从远程获取代码库

  1. 假设你配置好了一个远程仓库,并且你想要提取更新的数据,你可以首先执行:
    git fetch [alias]

  2. 以上命令告诉 Git 去获取它有你没有的数据,执行完后需要执行 git merge 远程分支到你所在的分支:
    git merge [alias]/[branch]

3.3 git pull

下载远程代码并合并
git pull 其实就是 git fetchgit merge 的简写,先从远程仓库获取最新的提交记录,然后将这些提交记录合并到你当前的分支中。

git pull [远程仓库名] [分支名]

  • [远程仓库名] 通常是 origin,是默认的远程仓库名。
  • [分支名] 是你要合并的远程分支,比如 main 或 master。

3.4 git push

上传远程代码并合并

命令格式如下:
git push <远程主机名> <本地分支名>:<远程分支名>
如果本地分支名与远程分支名相同,则可以省略冒号:
git push <远程主机名> <本地分支名>

六、Git 分支管理

几乎每一种版本控制系统都以某种形式支持分支,一个分支代表一条独立的开发线。

使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。
在这里插入图片描述
Git 分支实际上是指向更改快照的指针。

有人把 Git 的分支模型称为必杀技特性,而正是因为它,将 Git 从版本控制系统家族里区分出来。

1. 创建新分支

创建新分支并切换到该分支:
git checkout -b <branchname>

切换分支命令:
git checkout (branchname)

2. 查看分支

查看所有分支:
git branch

查看远程分支:
git branch -r

查看所有本地和远程分支:
git branch -a

3. 合并分支

将其他分支合并到当前分支:
git merge <branchname>

4. 解决合并冲突

当合并过程中出现冲突时,Git 会标记冲突文件,你需要手动解决冲突。
打开冲突文件,按照标记解决冲突。
标记冲突解决完成:
git add <conflict-file>

提交合并结果:
git commit

5. 删除分支

删除本地分支:
git branch -d <branchname>

强制删除未合并的分支:
git branch -D <branchname>

删除远程分支:
git push origin --delete <branchname>

6. 列出分支

列出分支基本命令:
git branch

没有参数时,git branch 会列出你在本地的分支。
$ git branch
* master

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值