banner
NEWS LETTER

git学习

Scroll down

Git基础知识

1. 什么是Git

Git是一个用于管理源代码的分布式版本控制系统,对修改文件时记录并保存,可以随时恢复以前的工作版本。

git可以看到文件修改记录,如何修改以及修改的人,git历史存储在共享存储库中

Examples of team works before a version control system and after a version control system

1.1 git组件

git主要包括三个组件:

  • 存储库:跟踪所有文件修改的容器,保存着团队的所有提交。
1
2
3
4
#创建存储库
git init
# 日志命令
git log
  • 工作树:由正在处理的文件组成,可以查看修改其中的文件。
1
2
3
4
# 显示工作树状态
git status
添加-s选项将只显示已更改的文件名
添加-s选项,后面再接-b选项,将在输出中包含分支名称
  • 索引:暂存后,工作树中的文件将与存储库中的文件进行比较。对工作树中文件的更改在提交之前被标记为已修改。

Work tree and index

1.2 工作流程

  1. 修改工作树中的文件
    这一步是指对工作目录中的文件进行编辑或更改。假设您要修改一个名为example.txt的文件,您可以使用任何文本编辑器打开它并进行更改。

  2. 暂存要包含在下一次提交中的更改
    修改文件后,您需要将这些更改添加到暂存区(也称为索引)。暂存是准备提交的更改的过程。使用以下命令将更改添加到暂存区:

    1
    git add example.txt

    这条命令会将example.txt文件中的更改添加到暂存区。

  3. 提交您的更改
    一旦更改被暂存,您就可以提交这些更改。提交会将暂存区的内容作为一个新的快照永久地存储到Git仓库的历史记录中。使用以下命令提交更改:

    1
    git commit -m "这是我对example.txt的更改"

    这里的-m选项后面跟着的是提交消息,它是一个描述您此次更改的简短说明。

1.3 git文件的三种状态

  • 已修改(Modified):修改后端文件必须使用git add进行暂存
  • 已暂存(Staged):使用git commit存储到新快照中
  • 已提交(committed)

Git components

  1. Untracked

    • 当文件初次创建在工作目录中,但还未被Git跟踪时,它是处于Untracked状态。要开始跟踪文件,您需要使用以下命令:
      1
      git add <file>
      这将文件状态从Untracked转变为Staged。
  2. Staged

    • 文件已经准备好被提交。这意味着它已经被添加到暂存区,等待下一次提交。提交这些暂存的文件,使用:
      1
      git commit -m "Your commit message"
      提交后,文件状态变为Committed。
  3. Modified

    • 文件已经被修改但尚未暂存。这通常发生在已跟踪的文件被编辑后但还没有被重新暂存。要暂存这些更改,使用:
      1
      git add <file>
      这会再次将文件状态变为Staged。
  4. Committed

    • 文件的更改已被永久记录在Git仓库的历史中。一旦文件提交,它返回到Tracked但未修改的状态。如果这些文件再次被修改,则转为Modified状态。
  5. 其他操作

    • 如果需要查看文件状态,可以使用:
      1
      git status
    • 如果想删除暂存区中的文件(使之回到未跟踪状态),可以使用:
      1
      git rm --cached <file>
    • 要查看自上次提交以来你或其他人修改了哪些文件(差异),可以使用:
      1
      git diff

2.存储库

存储库 (即 repository) 是用于存储代码的位于中心的文件夹。一旦拥有包含文件和目录的 Git 存储库,就可以开始跟踪更改和版本。

2.1 远程存储库与本地存储库

  • 远程存储库:托管在远程服务器上 (这可以在互联网上或异地服务器上;它甚至可以是不同路径中的同一台机器) 并在多个团队成员之间共享。
  • 本地存储库:为单个用户托管在本地机器上。

写作功能只能在远程存储库上完成

Remote vs local repositories

2.2 创建存储库

创建和管理Git存储库涉及几个关键步骤,从创建本地存储库到设置远程存储库,再到克隆远程存储库的复制,以下是详细指南。

创建本地存储库

  1. 初始化新仓库
    1
    2
    3
    mkdir my-project
    cd my-project
    git init
    这些命令创建一个新目录并初始化为Git仓库。

创建远程存储库

  1. 在GitHub上创建远程存储库
    • 登录到GitHub账户。
    • 点击“New repository”。
    • 填写仓库名称、描述,选择是否公开。
    • 点击“Create repository”。

链接本地和远程存储库

  1. 添加远程仓库地址

    1
    git remote add origin https://github.com/your-username/my-project.git

    这条命令将远程仓库添加到本地仓库,origin是远程仓库的默认名称。

  2. 推送更改到远程存储库

    1
    2
    3
    4
    echo "# My Project" >> README.md
    git add README.md
    git commit -m "Initial commit"
    git push -u origin master

    这会将本地的更改推送到GitHub,并设置默认推送分支。

克隆存储库

  1. 复制远程存储库
    使用git clone命令克隆已有的远程存储库:
    1
    git clone https://github.com/username/repository.git
    这将在本地创建一个完整的存储库副本,包括所有分支和提交历史。

查看和操作提交历史

  1. 查看提交历史
    1
    git log
    这条命令列出所有提交,可以看到每次提交的详细信息,包括作者和日期。

3.记录变更

Git 不会自动记录您所做的每个更改。您必须通过在索引中暂存这些更改来告诉 Git 您想要记录哪些更改。暂存后,您可以提交这些更改,以便将它们记录在存储库中。

3.1 进行更改

工作树(Working Tree)

  • 定义:工作树是您的文件系统中一个特定的目录,其中包含了当前Git项目的所有文件。这是您进行日常工作的地方,比如编辑文件、添加新文件以及删除不再需要的文件。
  • 功能:工作树反映了文件的当前状态,包括已经提交的文件和尚未暂存或提交的更改。

索引(Index 或 Staging Area)

  • 定义:索引,也称为暂存区,位于工作树和Git存储库之间。它是一个中间层,用于存储即将被提交的更改。
  • 功能:当您在工作树中执行更改(如修改、添加或删除文件)时,这些更改首先影响的是工作树。要将这些更改提交到存储库,您需要先将它们加入到索引中。

image-20240705201732504

提交更改到存储库

  • 过程:一旦更改被加入到索引(即执行了git add命令),它们就被标记为准备提交。索引中的状态反映了下一次执行git commit时将保存到存储库的内容。
  • 提交:只有当您执行git commit命令时,索引中的更改才会被永久保存到存储库的历史记录中。

查看工作树状态

1
git status
  • 显示当前工作树的状态,包括哪些文件被修改了、哪些文件已经被暂存等。

添加文件到索引

1
2
git add <文件名>
git add .
  • 这些命令将工作树中的更改添加到索引中。

从索引中移除文件

1
git reset <文件名>
  • 这个命令可以将文件从索引中移除,但不会影响工作树中的文件。

提交索引中的更改到存储库

1
git commit -m "提交信息"
  • 将索引中的所有更改提交到存储库的历史记录中。

通过理解和应用这些组件及命令,您可以有效地使用Git来管理您的项目代码和文档,确保您的开发工作高效、有序。

3.2 提交更改

提交命令允许您在存储库的 Git 历史记录中记录文件更改。

您提交的每个更改都可以在相应的文件或目录中按时间顺序查看。

Git committing changes

40 个字符的校验和哈希可唯一标识每个提交。您可以使用校验和哈希来检索您的存储库中给定提交的状态或更改。每次提交时,Git都会生成一个40字符的哈希值,您可以使用这个哈希值来引用特定的提交。

将不同类型的更改—例如错误修复、新功能和改进—分离到不同的提交集中,将使您和您的团队成员能够理解为什么以及如何快速进行这些更改。

3.3 git提交消息

git commit

这种方法不在命令行直接提供提交消息,而是打开系统默认的文本编辑器供您编写提交消息。

步骤:
  1. 执行 git commit
  2. 在打开的文本编辑器中输入提交消息,包括标题和详细描述。
  3. 保存并关闭编辑器以完成提交。
优点:
  • 允许详细编写多行提交消息,便于详尽描述更改内容及其原因。
  • 适合需要详细注释和文档化的复杂提交。
使用场景:
  • 需要提供详细提交说明的场合,尤其是涉及多个文件或复杂更改的提交。

git commit -m

这种方法通过命令行直接附加简短的提交消息,通常用于快速提交小更改。

步骤:
  1. 执行 git commit -m "提交消息"
  2. 可以使用多个 -m 选项添加更详细的描述。
优点:
  • 快速简便,适合日常的小更改。
  • 避免打开文本编辑器,加快提交过程。
使用场景:
  • 日常开发中需要快速提交的情况。
  • 更改较小或不需要多行详细说明的提交。

示例

  • 使用 git commit:

    提交更改时,您需要输入提交信息。提交消息应该简洁准确地描述您所做的更改。

    1
    git commit

    为了使消息一致且易于理解,请尝试以下 Git 提交消息模板:

    • 第 1 行:提交更改的内容摘要ts changed by commits
    • 第 2 行:空行
    • 第 3 行:变更原因
  • 使用 git commit -m:

    1
    git commit -m "修正了用户登录表单的输入验证错误"

结论

选择使用 git commitgit commit -m 应基于提交的复杂性、需要的详细程度以及团队的工作流程。清晰和详细的提交消息是推荐的做法,有助于未来的代码维护和项目的可追溯性。

4. 还原变更

当您进行新的提交时,Git 会存储项目的快照,以便您可以在需要时返回到较早的版本。撤消更改的方法主要有两种:git revertgit reset

4.1 撤销提交

使用git revert 命令撤消以前的提交。这是撤消更改的最常用方法。

Revert 命令可创建一个新的提交,用于恢复先前提交所做的更改。它允许您撤消不需要的更改,而无需完全移除提交或修改存储库的历史记录。它是一个有用的工具,用于管理对 Git 存储库的更改,同时保留其历史记录。

虽然你可以用git resetgit rebase -i 命令,从历史记录中删除先前的提交,但一般不建议这样做,因为这会导致远程存储库与其他成员的本地存储库不同。

Diagram of reverting commits.

4.2 移除提交

使用 git reset 命令使 HEAD 指向先前的提交。您可以通过进入重置模式来指定重置命令的范围。

Diagram of removing commits.

4.3 重置模式

在Git中,git reset 是一个强大的命令,用于撤销提交或更改。它有三种主要的模式:混合(Mixed)、软(Soft)和硬(Hard),每种模式适用于不同的场景。以下是每种模式的详细解释和示例。

Diagram showcasing reset modes.

1. 混合(Mixed)模式

  • 描述git reset --mixed 是默认的重置模式。它会重置索引(暂存区)到指定的提交,但不会更改工作目录中的文件。已暂存的更改会被撤销,但工作目录中的更改会保留下来。
  • 用途:当你想取消暂存的更改,但不想丢失对文件所做的任何修改时,使用混合模式。

示例

假设你有多个文件暂存准备提交,突然意识到需要重新审查一些更改:

1
git reset --mixed HEAD~1

这会将HEAD指针回退到前一次提交,所有暂存的更改将返回到工作目录。

2. 软(Soft)模式

  • 描述git reset --soft 只会重置HEAD到指定的提交,但不会更改索引(暂存区)或工作目录。这意味着所有当前暂存的更改仍然保持暂存状态。
  • 用途:适用于重新提交。例如,如果你的提交消息不正确或者提交了错误的文件,你可以用这个命令撤销提交,但保留更改以便重新提交。

示例

你提交了一个更改,但立即意识到提交消息写错了:

1
git reset --soft HEAD~1

然后你可以重新暂存你的更改(如果需要)并使用新的提交消息再次提交:

1
git commit -m "正确的提交消息"

3. 硬(Hard)模式

  • 描述git reset --hard 会重置HEAD、索引和工作目录。任何暂存或未暂存的更改都将被清除,回退到指定的提交状态。
  • 用途:当你想彻底撤销所有更改,包括工作目录中的更改时使用。这是一个危险的操作,因为它会丢失所有未提交的更改。

示例

假设你正在实验一些代码更改,但结果完全不如预期,你决定放弃这些更改:

1
git reset --hard HEAD~1

这会将你的项目状态回退到前一次提交,丢弃所有当前的更改。

注意

使用 git reset 时要非常小心,特别是使用 --hard 选项。一旦执行了硬重置,未提交的更改就会永久丢失。在进行任何重置操作之前,确保已经正确备份了必要的数据。

5. 同步到存储库

远程存储库可以位于私人服务器、与您不同的计算机上,或者通过某些项目管理软件托管,例如 Backlog

无论您在哪里托管,都需要经常将本地存储库与远程存储库同步,以便与其他团队成员共享更改内容。

您可以使用三个命令同步存储库:

5.1 推送更改

要与他人共享更改,必须使用 git push命令。这将更新远程存储库并将其与本地存储库同步。

Diagram of pushing changes.

5.2 拉取更改

每当有人将他们的更改推送到共享的远程存储库时,您的本地存储库就会过时。要将本地存储库与新更新的远程存储库重新同步,只需运行 git pull 命令

当运行拉取命令时,最新的修订历史记录会从远程存储库下载并导入到您的本地存储库。

5.3 合并更改

如果本地的存储库过时,则远程推送会被拒绝。当您的本地存储库版本落后于远程存储库时,尝试向远程存储库推送更改确实可能会遇到问题。这通常发生在其他人已经向远程存储库提交了新的更改,而您的本地存储库尚未更新这些更改时。在这种情况下,Git 会拒绝推送,以防止您无意中覆盖别人的工作。

解决方案:拉取远程更改并合并

为了解决这个问题,您需要先将远程存储库的更改拉取到本地存储库中,解决可能的冲突,并在本地测试更改,确保一切正常后,再尝试推送。这里是解决步骤:

  1. 拉取远程存储库的更改
    使用 git pull 命令。这个命令实际上是 git fetchgit merge 的组合。它首先从远程存储库抓取最新的分支状态,然后将这些更改合并到您当前的分支中。

    1
    git pull origin your-branch-name
  2. 解决合并冲突
    如果存在冲突,Git 将提示您解决。您需要手动打开冲突的文件,并决定如何合并更改。编辑完毕后,您需要添加已解决冲突的文件到暂存区:

    1
    git add <冲突文件>
  3. 完成合并
    一旦冲突解决并且所有更改都已暂存,您可以通过以下命令完成合并:

    1
    git commit

    这通常会打开一个编辑器让您输入合并提交的消息,但如果您使用的是默认设置,通常会有一个自动生成的合并提交消息。

  4. 再次推送
    解决冲突并合并更改后,您应该能够成功推送到远程存储库:

    1
    git push origin your-branch-name

Diagram of a ouddated repo.

在这种情况下,您可以使用 git merge 命令在推送前整合远程分支的本地副本的最新修改。Git 强制执行此操作以确保其他成员所做的更改可保留在版本历史记录中。

为什么这样做?

Git 鼓励开发者频繁地同步他们的工作,这有助于减少合并冲突的复杂性,也确保了团队成员之间的工作是协调一致的。当您试图推送过时的分支时,Git 拒绝推送是一种安全措施,以防止潜在的代码丢失或覆盖。

总之,保持您的本地存储库与远程存储库同步是良好的版本控制实践。当遇到推送拒绝时,通过 git pull 来合并远程更改通常是解决这种问题的标准方法。

Diagram of a merging latest changes.

在合并期间,Git 将尝试自动应用历史更改并将它们与当前分支合并。但是如果有冲突,会报错提示你手动解决。

5.4 解决合并冲突

在正确完成合并之前,您可能会遇到需要解决的冲突。例如,如果两个或多个成员在两个不同的分支 (即远程和本地分支) 中对文件的同一部分进行更改,Git 无法自动合并它们。

发生这种情况时,Git 会在冲突文件中添加冲突解决标记。这些标记可帮助您确定文件的哪些部分需要手动处理。

Diagram of a merging change.

Git用<<<<<<<=======>>>>>>>标记出不同分支的内容,在继续创建合并提交之前,您必须依照下列所示方式解决冲突部分。

Diagram of a merging change.

6. 管理git 历史记录

有时需要修改本地提交历史记录。示例场景包括需要更改您的提交信息,更新提交顺序,或将提交压缩在一起。

6.1 修改提交

您可以通过运行 git commit –amend 命令修改同一分支中的最新提交。这个命令可以方便地将新的或更新的文件添加到上一次提交中。这也是一种编辑提交消息或将提交消息添加到上一次提交的简便方法。

Diagram using the git ammend command.

6.2 将提交复制到新分支

变基是将在一个分支上提交的所有更改复制到新分支的过程。

运行 git rebase 命令并加上-i选项以重写、替换、删除和合并历史记录中的个别提交。

您也可以使用变基命令来:

  • 重写过去的提交信息
  • 将一组提交压缩在一起
  • 添加尚未提交的文件

Diagram of reabsing.

6.3 将提交复制到其他分支

您可以使用 git cherry-pick 命令将现有提交从另一个分支复制到存储库中的当前分支。

Cherry-picking 可以让您:

  • 将提交从错误的分支移动到正确的分支。
  • 根据另一个分支的现有提交,为当前分支添加提交。

Diagram using the cherry-pick command.

6.4 合并提交

压缩是将多个提交合并为一个提交的过程。

如果你运行 git merge 命令--squash选项,一个新的提交会将来自一个分支的所有提交组合在一起。然后该提交可以合并到当前分支中。

Diagram using the squash command.

其他文章
目录导航 置顶
  1. Git基础知识
    1. 1. 什么是Git
      1. 1.1 git组件
      2. 1.2 工作流程
      3. 1.3 git文件的三种状态
    2. 2.存储库
      1. 2.1 远程存储库与本地存储库
      2. 2.2 创建存储库
        1. 创建本地存储库
        2. 创建远程存储库
        3. 链接本地和远程存储库
        4. 克隆存储库
        5. 查看和操作提交历史
    3. 3.记录变更
      1. 3.1 进行更改
        1. 工作树(Working Tree)
        2. 索引(Index 或 Staging Area)
        3. 提交更改到存储库
        4. 查看工作树状态
        5. 添加文件到索引
        6. 从索引中移除文件
        7. 提交索引中的更改到存储库
      2. 3.2 提交更改
      3. 3.3 git提交消息
        1. git commit
        2. git commit -m
      4. 示例
      5. 结论
    4. 4. 还原变更
      1. 4.1 撤销提交
      2. 4.2 移除提交
      3. 4.3 重置模式
        1. 1. 混合(Mixed)模式
        2. 示例
        3. 2. 软(Soft)模式
        4. 示例
        5. 3. 硬(Hard)模式
        6. 示例
      4. 注意
    5. 5. 同步到存储库
      1. 5.1 推送更改
      2. 5.2 拉取更改
      3. 5.3 合并更改
        1. 解决方案:拉取远程更改并合并
        2. 为什么这样做?
      4. 5.4 解决合并冲突
    6. 6. 管理git 历史记录
      1. 6.1 修改提交
      2. 6.2 将提交复制到新分支
      3. 6.3 将提交复制到其他分支
      4. 6.4 合并提交