Git 基础使用
最近更新:2025-10-20   |   字数总计:7.2k   |   阅读估时:28分钟   |   阅读量:
  1. Git 基础使用
    1. 版本控制
    2. Git 基础(本地)
      1. 获取 Git 仓库
      2. 检查当前文件状态
      3. 跟踪新文件
      4. 暂存已修改的文件
      5. 状态简览
      6. 忽略文件
      7. 查看已经暂存和未暂存的修改
      8. 提交更新
      9. 跳过暂存区域
      10. 移除文件
      11. 移动文件
      12. 文件状态
        1. 未跟踪(Untracked)
        2. 已跟踪(Tracked)
          1. 已修改(Modified)
          2. 暂存(Staged)
          3. 已提交(Committed)
        3. 示例
      13. 查看提交历史
      14. 撤销操作
        1. git reset
          1. 常用选项
          2. 用途
          3. 示例
        2. git checkout
          1. 用途
          2. 示例
          3. 注意
        3. git commit --amend
          1. 用途
          2. 示例
        4. 比较
        5. 小结
    3. 远程仓库
      1. git remote add <name> <url>
        1. 多个远程仓库协作
        2. 镜像仓库
      2. git push origin main
    4. 分支
      1. 分支的基本操作
        1. 查看分支
        2. 创建分支
        3. 切换分支
        4. 合并分支
        5. 删除分支
        6. GUI 图示
      2. 解决合并冲突
      3. Rebase 合并分支
      4. 分支的使用场景
        1. 功能开发
        2. 错误修复
        3. 代码评审
      5. 分支工作流程示例
    5. 分支管理
      1. Git分支工作流模型
        1. Git Flow
          1. 分支类型
          2. 工作流
        2. GitHub Flow
      2. 分支命名
      3. 分支管理习惯
      1. 为 Git 添加代理

Git 基础使用

此博客记录针对 Git 的学习,整合资料。

参考:

  1. Git - Documentation (git-scm.com)

  2. 【GeekHour】一小时Git教程

  3. Git 教程和培训 | Atlassian Git Tutorial

版本控制

版本控制工具是软件开发中不可或缺的一部分。它们用于记录文件的变化,使开发者能够回溯到之前的任何版本,并跟踪和管理项目的历史版本。这对于团队协作开发尤为重要,因为它能够帮助团队成员在不同的功能分支上独立工作,最后再将各自的工作合并到一起。

传统的版本控制系统(如 SVN)通常是集中式的,所有版本控制操作都通过一个中央服务器来完成。这种方法有一个显著的缺点:如果中央服务器出现问题,所有人都无法工作。这时,分布式版本控制系统(Distributed Version Control System,简称 DVCS)应运而生。

在 DVCS 中,如 Git、Mercurial 以及 Darcs,客户端并不只是提取最新版本的文件快照,而是把整个代码仓库完整地镜像下来,包括完整的历史记录。每个开发者都有一个完整的代码库副本,包含所有的分支和提交记录。

这样一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。

具体实例

假设你有一个使用 DVCS 的项目,当你克隆(clone)一个远程仓库时,你得到的不是仅仅一个最新版本的代码快照,而是整个仓库的完整副本,包括所有的分支和历史记录。这意味着你可以在本地执行几乎所有的版本控制操作,而不需要依赖网络连接。

在团队协作中,每个开发者可以独立地在自己的分支上工作,当一个功能完成时,可以将其合并到主分支中。而且,如果一个开发者的工作出现问题,不会影响其他人的工作,因为每个人都有自己的代码库副本。

Git 基础(本地)

获取 Git 仓库

通常有两种获取 Git 项目仓库的方式:

  1. 将尚未进行版本控制的本地目录转换为 Git 仓库;

    进入项目目录,再执行 git init命令

    1
    2
    $ cd /my_project
    $ git init
  2. 从其它服务器 克隆 一个已存在的 Git 仓库。

    1
    $ git clone <url> 

    克隆远程仓库到本地,还可以通过额外的参数指定克隆到本地的仓库的名字。

克隆之后,可以开始追踪仓库中的文件,使用git add命令,热案后执行git commit

1
2
3
$ git add *.c
$ git add LICENSE
$ git commit -m 'initial project version'

检查当前文件状态

可以使用 git status 命令查看哪些文件处于什么状态。

跟踪新文件

使用命令 git add 开始跟踪一个文件。

暂存已修改的文件

如果修改了一个已经被跟踪的文件,再执行git status命令,就会出现Changes not staged for commit,说明跟踪文件内容发生了变化,但是没有放到暂存区,如果要暂存这次更新,还需要运行一次git add

git add

这是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。 将这个命令理解为“精确地将内容添加到下一次提交中”而不是“将一个文件添加到项目中”要更加合适。

运行了 git add 之后又作了修订的文件,需要重新运行 git add 把最新版本重新暂存起来

状态简览

git status 命令的输出十分详细,但是内容有一点繁琐。

可以使用git status -s命令得到更精简的输出。

1
2
3
4
5
6
$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt

新添加的未跟踪文件前面有 ?? 标记,新添加到暂存区中的文件前面有 A 标记,修改过的文件前面有 M 标记。 输出中有两栏,左栏指明了暂存区的状态,右栏指明了工作区的状态。例如,上面的状态报告显示: README 文件在工作区已修改但尚未暂存,而 lib/simplegit.rb 文件已修改且已暂存。 Rakefile 文件已修改,暂存后又作了修改,因此该文件的修改中既有已暂存的部分,又有未暂存的部分。

忽略文件

在 Git 仓库目录下,有一些文件可能还会随着项目的编译运行而产生,比如说日志或者编译产生的临时文件,我们并不想这些文件被 Git 标记为未跟踪状态,这时就可以创建一个名为.gitignore文件,列出要忽略的文件模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 忽略所有的 .a 文件
*.a

# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a

# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO

# 忽略任何目录下名为 build 的文件夹
build/

# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt

# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf

查看已经暂存和未暂存的修改

使用git status可以大致知道那些文件被修改了,但却不能精确知道修改的内容与位置。

要查看尚未暂存的文件更新了哪些部分,这时可以使用git diff命令。

git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。

git diff --staged 这条命令将比对已暂存文件与最后一次提交的文件差异

提交更新

现在的暂存区已经准备就绪,可以提交了。 在此之前,请务必确认还有什么已修改或新建的文件还没有 git add 过, 否则提交的时候不会记录这些尚未暂存的变化。 这些已修改但未暂存的文件只会保留在本地磁盘。 所以,每次准备提交前,先用 git status 看下,你所需要的文件是不是都已暂存起来了, 然后再运行提交命令 git commit

还可以添加-m选项,将提交信息与命令放在同一行。

跳过暂存区域

尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁琐。 Git 提供了一个跳过使用暂存区域的方式, 只要在提交的时候,给 git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤。

移除文件

要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用 git rm 命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。

如果只是简单地从工作目录中手工删除文件,运行 git status 时就会在 “Changes not staged for commit” 部分(也就是 未暂存清单)看到:

1
2
3
4
5
6
7
8
9
10
11
$ rm PROJECTS.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

deleted: PROJECTS.md

no changes added to commit (use "git add" and/or "git commit -a")

上面命令会将工作区的文件也删除,如果需要将文件从Git仓库中删除,但并不想从工作区中移除,就需要用到如下命令。

1
git rm --cached filename

移动文件

如果在 Git 中重命名了某个文件,仓库中存储的元数据并不会体现出这是一次改名操作。

要在 Git 中对文件改名,可以这么做:

1
$ git mv file_from file_to

运行 git mv 就相当于运行了下面三条命令:

1
2
3
$ mv README.md README
$ git rm README.md
$ git add README

所以在使用其他工具重命名文件时,记得在提交前 git rm 删除旧文件名,再 git add 添加新文件名。

文件状态

Git 文件在版本控制过程中的状态主要有以下三种:未跟踪、已跟踪(包括已修改和暂存)。

1
2
3
4
5
6
7
Untracked --- git add ---> Staged --- git commit ---> Committed
| |
v |
Modified ----------------------
^ git add |
|---------------------|

Git 下文件生命周期图。

未跟踪(Untracked)

未跟踪的文件是指在 Git 仓库中尚未被 Git 跟踪的文件。它们通常是新添加到工作目录中的文件,但还没有被添加到版本控制中。

  • 状态:未跟踪
  • 操作:使用 git add <file> 命令将文件添加到暂存区,使其进入已跟踪状态。

已跟踪(Tracked)

已跟踪的文件是指已经被 Git 仓库跟踪的文件。已跟踪的文件分为以下三种状态:

已修改(Modified)

已修改的文件是指文件内容发生了变化,但这些变化尚未被记录到暂存区。

  • 状态:已修改
  • 操作:使用 git add <file> 命令将文件的修改添加到暂存区。
暂存(Staged)

暂存的文件是指文件的修改已经被添加到暂存区,将在下一次提交中被记录。

  • 状态:暂存
  • 操作:使用 git commit -m "message" 命令将暂存区的修改提交到本地仓库。
已提交(Committed)

已提交的文件是指文件的修改已经被提交到本地仓库,成为项目历史的一部分。

  • 状态:已提交
  • 操作:文件已经被提交,不需要额外操作,除非进行新的修改。

示例

git status 命令查看哪些文件处于什么状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 初始化 Git 仓库
git init

# 创建一个新文件
echo "Hello, Git" > example.txt

# 检查文件状态
git status
# 输出:Untracked files: example.txt

# 将文件添加到暂存区
git add example.txt

# 检查文件状态
git status
# 输出:Changes to be committed: new file: example.txt

# 提交文件
git commit -m "Add example.txt"

# 检查文件状态
git status
# 输出:nothing to commit, working tree clean

# 修改文件
echo "Update example.txt" >> example.txt

# 检查文件状态
git status
# 输出:Changes not staged for commit: modified: example.txt

# 将修改添加到暂存区
git add example.txt

# 检查文件状态
git status
# 输出:Changes to be committed: modified: example.txt

# 提交修改
git commit -m "Update example.txt"

# 检查文件状态
git status
# 输出:nothing to commit, working tree clean

查看提交历史

使用git log命令查看提交历史。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700

changed the version number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sat Mar 15 16:40:33 2008 -0700

removed unnecessary test

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sat Mar 15 10:31:28 2008 -0700

first commit

不加任何参数,git log会按照时间先后顺序列出所有的commit,最新的在上面。会列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明。

git log还有很多功能选项:

选项 说明
-p 按补丁格式显示每个提交引入的差异。
--stat 显示每次提交的文件修改统计信息。
--shortstat 只显示 –stat 中最后的行数修改添加移除统计。
--name-only 仅在提交信息后显示已修改的文件清单。
--name-status 显示新增、修改、删除的文件清单。
--abbrev-commit 仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。
--relative-date 使用较短的相对时间而不是完整格式显示日期(比如“2 weeks ago”)。
--graph 在日志旁以 ASCII 图形显示分支与合并历史。
--pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline、short、full、fuller 和 format(用来定义自己的格式)。
--oneline --pretty=oneline --abbrev-commit 合用的简写。

Git - 查看提交历史 (git-scm.com)

撤销操作

git reset

git reset 用于重置当前分支的 HEAD 到指定的提交,并可以选择性地重置暂存区和工作目录中的文件。

常用选项
  1. **git reset --soft**:重置 HEAD 到指定提交,但保留暂存区和工作目录中的更改。
  2. git reset --mixed(默认):重置 HEAD 和暂存区到指定提交,但保留工作目录中的更改。
  3. **git reset --hard**:重置 HEAD、暂存区和工作目录到指定提交,丢弃所有更改。
用途
  • 撤销提交:撤销一个或多个提交,同时选择保留或丢弃更改。

  • 撤销文件暂存:git reset HEAD filename

    这个命令用于取消对特定文件的暂存,但保留工作目录中的更改。这在你已经使用 git add 将文件添加到暂存区,但又希望将其从暂存区移除时非常有用。

示例
1
2
3
4
5
6
7
8
# 撤销最后一个提交,保留更改在暂存区和工作目录中
git reset --soft HEAD~1

# 撤销最后一个提交,并取消暂存区中的更改,但保留工作目录中的更改
git reset HEAD~1

# 撤销最后一个提交,并丢弃所有更改
git reset --hard HEAD~1
1
2
# 取消暂存文件
git reset HEAD filename

git checkout

git checkout 主要用于切换分支和恢复工作目录中的文件。

用途
  • 切换分支:在不同分支之间切换。
  • 恢复文件:从某个提交或分支中恢复文件到工作目录中。
示例
1
2
3
4
5
6
7
8
# 切换到分支
git checkout branch_name

# 恢复工作目录中的文件到最近的提交
git checkout -- filename

# 恢复工作目录中的文件到指定的提交
git checkout commit_hash -- filename
注意

git checkout 在 Git 2.23.0 之后,被推荐使用 git switchgit restore 命令来替代,以减少命令的歧义。

git commit --amend

git commit --amend 用于修改最近一次的提交。它允许你在不创建新提交的情况下更新上一次提交的内容或提交信息。

用途
  • 修改提交信息:修正最近一次提交的提交信息。
  • 添加遗漏的更改:将遗漏的更改添加到最近一次提交中。

当你在修补最后的提交时,与其说是修复旧提交,倒不如说是完全用一个 新的提交 替换旧的提交, 理解这一点非常重要。从效果上来说,就像是旧有的提交从未存在过一样,它并不会出现在仓库的历史中。

示例
1
2
3
4
5
6
# 修改最近一次提交的提交信息
git commit --amend

# 添加遗漏的更改并修改最近一次提交
git add forgotten_file
git commit --amend

比较

  • **git reset**:重置当前分支的 HEAD、暂存区和工作目录到指定的提交。适用于撤销一个或多个提交,可以选择保留或丢弃更改。
  • **git checkout**:切换分支或恢复文件到工作目录。适用于切换分支和恢复文件。
  • **git commit --amend**:修改最近一次的提交。适用于修正提交信息或添加遗漏的更改。

小结

  • 撤销提交git resetgit commit --amend 都可以用于撤销提交,但 git reset 更强大,可以撤销多个提交。
  • 修改提交git commit --amend 专用于修改最近一次提交。
  • 恢复文件git checkout 用于从某个提交或分支恢复文件。

记住,在 Git 中任何 已提交 的东西几乎总是可以恢复的。 甚至那些被删除的分支中的提交或使用 --amend 选项覆盖的提交也可以恢复

远程仓库

在使用 Git 的过程中,远程仓库是一个非常重要的概念。远程仓库是托管在互联网上或其他网络上的 Git 仓库,它使得我们可以与其他开发者协同工作,共同开发项目。

为什么使用远程仓库?

协作开发:远程仓库允许多个开发者同时对同一个项目进行开发,团队成员可以各自提交自己的更改,并将这些更改推送到远程仓库。这样,所有人都可以同步到最新的代码状态。

备份代码:将代码推送到远程仓库可以作为代码的备份。即使本地仓库发生故障或丢失,也可以从远程仓库中恢复代码。

git remote add <name> <url>

多个远程仓库协作

在团队协作中,不同的开发者可能会有各自的远程仓库进行开发。你可以将他们的仓库添加为远程仓库,以便拉取他们的更改并与他们协作。

例如,你的同事 Alice 有一个仓库,你可以将她的仓库添加为 alice

1
git remote add alice https://github.com/alice/repository.git

这样你可以从 Alice 的仓库中获取代码:

1
git fetch alice

git fetch <remote> 从远程仓库获取数据,但不进行合并。它会更新本地存储的远程分支信息。

git pull <remote> <branch> 从远程仓库获取数据并自动合并到当前分支。它实际上是 git fetchgit merge 的组合。

镜像仓库

有时候,你可能需要将你的代码推送到多个远程仓库。比如,你可以同时推送到 GitHub 和 GitLab:

1
2
git remote add github https://github.com/username/repository.git
git remote add gitlab https://gitlab.com/username/repository.git

然后你可以分别推送代码到两个远程仓库:

1
2
git push github main
git push gitlab main

git push <remote> <branch> 将本地分支的更新推送到远程仓库

git push origin main

git push origin main 命令用于将本地的 main 分支的更新推送(push)到远程仓库 originmain 分支上。

具体含义如下:

  • git push: 用于将本地仓库的提交推送到远程仓库。
  • origin: 远程仓库的名称,通常默认为 origin,它是你本地仓库与远程仓库的关联名字。
  • main: 本地的分支名称,在这个例子中指的是你的本地 main 分支。

但是若果是协作,提交时必须将上游的工作拉下来合并进自己的工作之后才能推送。

git remote rename 远程仓库重命名

git remote remove 移除远程仓库

分支

分支让工作者可以从开发主线分离出来,在不影响主线的情况下进行开发、修复错误或尝试新的想法。分支是轻量级的,可以很容易地创建和删除。理解和使用分支对于高效的版本控制和团队协作非常重要。

分支的基本操作

查看分支

1
git branch

这个命令会列出所有的本地分支,并在当前所在的分支前加上 * 标记。

创建分支

1
git branch <branch-name>

切换分支

1
git checkout feature

或者可以使用 -b 选项同时创建并切换到新分支:

1
git checkout -b <branch-name>

git checkout还有恢复目录和文件的功能,为了避免混淆。

有一个专门用于切换分支的命令git switch (Git 2.23.0 版本之后)

切换到现有分支

1
git switch <branch-name>

创建并切换到新分支

1
git switch -c <new-branch-name>

注意:切换分支会导致工作区也发生变化。

合并分支

当你在一个分支上完成开发后,可以将这个分支合并到另一个分支。例如,合并 feature 分支到 main 分支:

首先切换到目标分支(例如 main):

1
git checkout main

然后执行合并操作:

1
git merge feature

删除分支

如果一个分支不再需要,可以将其删除:

1
git branch -d <branch-name>

例如,删除 feature 分支:

1
git branch -d feature

注意:如果分支未被合并到主分支中,-d 命令会拒绝删除。要强制删除,可以使用 -D 选项:

1
git branch -D <branch-name>

GUI 图示

main分支和dev分支共同开发。

image-20240715142226054

切换到main分支,执行git merge dev命令,Git 会自动为我们产生一次提交,将dev分支的内容合并到main分支中。

image-20240715150541479

注意:分支在合并之后并不会自动被删除,如果需要删除不再需要的分支需要手动删除分支。

解决合并冲突

如果两个分支的修改内容没有重合部分,那么合并分支非常简单且顺利。

但是如果两个分支修改了同一个文件的同一行代码,Git 就不知道应该保留哪个分支的内容了,这就是合并分支时产生的冲突,需要手动解决冲突。

示例:

假设你有两个分支:mainfeature,它们对同一个文件 example.txt 进行了不同的修改。

1
2
git checkout main
git merge feature

Git 会显示合并冲突的提示,告诉你哪些文件存在冲突:

1
2
3
Auto-merging example.txt
CONFLICT (content): Merge conflict in example.txt
Automatic merge failed; fix conflicts and then commit the result.

打开冲突的文件 example.txt,你会看到冲突的标记:

1
2
3
4
5
6
<<<<<<< HEAD
这是 main 分支的修改。
=======
这是 feature 分支的修改。
>>>>>>> feature

<<<<<<< HEAD======= 之间的部分是 main 分支的内容。

=======>>>>>>> feature 之间的部分是 feature 分支的内容。

根据需要手动编辑冲突的文件,保留你想要的修改,直接修改example.txt文件内容。

编辑完冲突的文件后,保存并关闭文件。然后使用 git add 命令将解决冲突的文件标记为已解决:

1
git add example.txt

最后,提交合并的结果:

1
git commit

Rebase 合并分支

Rebase 的基本思想是将一个分支的所有提交(公共祖先节点之后)重新应用到另一个分支的顶部。这样可以避免产生不必要的合并提交,从而保持历史记录的线性

所以也可以通过rebase命令进行分支的“合并”。

image-20240715154610291

如果遇到冲突,还是需要手动解决并暂存更改,然后使用git rebase -- continue命令或者git rebase --abort中止操作。

分支的使用场景

功能开发

在开发新功能时,可以创建一个新的分支来进行开发。这样可以确保主分支保持稳定,并且可以随时在新分支上进行试验和修改。

错误修复

在修复错误时,可以创建一个新的分支来进行修复工作。完成修复后,可以将修复分支合并回主分支。

代码评审

在团队协作中,分支可以用来提交代码进行评审。在提交代码之前,可以将代码推送到一个单独的分支,并请求团队成员进行评审和测试。

分支工作流程示例

  1. 创建新分支并切换到新分支

    1
    git checkout -b feature-branch
  2. 在新分支上进行开发: 修改文件并提交更改:

    1
    2
    git add .
    git commit -m "Add new feature"
  3. 将新分支推送到远程仓库

    1
    git push -u origin feature-branch

    这会在远程仓库 origin 中创建一个名为 feature-branch 的分支,并将本地的 feature-branch 分支内容推送到远程分支中。

  4. 创建拉取请求:在 GitHub 或其他托管平台上创建拉取请求,请求团队成员评审代码。

    团队成员可以使用 git fetchgit pull 命令将这个远程分支拉取到本地:

    1
    git fetch origin

    然后切换到该分支:

    1
    git checkout feature-branch

    这样将远程分支拉取到本地,允许团队成员共同访问和协作

  5. 合并分支:代码评审通过后,将新分支合并到主分支:

    1
    2
    git checkout main
    git merge feature-branch
  6. 删除本地和远程分支

    1
    2
    git branch -d feature-branch
    git push origin --delete feature-branch

通过使用分支,你可以有效地管理不同的开发任务,保持代码库的整洁和有序。分支提供了灵活性,使你可以在不影响主分支的情况下进行各种尝试和开发工作。

分支管理

Git分支工作流模型

Git Flow

分支类型
  • **main**:主分支,永远保持稳定和可发布状态。
  • **develop**:开发分支,所有的开发功能都基于这个分支。
  • **feature/***:功能分支,从 develop 分支创建,用于开发新功能。
  • **release/***:发布分支,从 develop 分支创建,用于准备新版本的发布。
  • **hotfix/***:修复分支,从 main 分支创建,用于修复生产环境的紧急问题。
工作流
  1. 新功能开发

    • develop 分支创建一个 feature 分支。
    • feature 分支上进行开发。
    • 开发完成后合并回 develop 分支。
    1
    2
    3
    4
    5
    6
    7
    git checkout develop
    git checkout -b feature/my-new-feature
    # 开发新功能
    git add .
    git commit -m "Add new feature"
    git checkout develop
    git merge feature/my-new-feature
  2. 发布准备

    • develop 分支创建一个 release 分支。
    • release 分支上进行发布前的准备工作(例如,修复bug、更新文档)。
    • 准备完成后合并回 maindevelop 分支,并打上标签。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    git checkout develop
    git checkout -b release/1.0.0
    # 准备发布
    git add .
    git commit -m "Prepare release 1.0.0"
    git checkout main
    git merge release/1.0.0
    git tag -a 1.0.0 -m "Release 1.0.0"
    git checkout develop
    git merge release/1.0.0
  3. 修复紧急问题

    • main 分支创建一个 hotfix 分支。
    • hotfix 分支上进行修复。
    • 修复完成后合并回 maindevelop 分支,并打上标签。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    git checkout main
    git checkout -b hotfix/1.0.1
    # 修复问题
    git add .
    git commit -m "Fix urgent issue"
    git checkout main
    git merge hotfix/1.0.1
    git tag -a 1.0.1 -m "Release 1.0.1"
    git checkout develop
    git merge hotfix/1.0.1

Git Flow

GitHub Flow

GitHub Flow 是一种更简单的工作流模型,适用于发布频繁的项目。它只有一个长期存在的主分支 main,所有开发都在单独的功能分支上进行。

可参考:GitHub 流 - GitHub 文档

官方推荐流程:

  • 第一步:根据需求,从main拉出新分支,不区分功能分支或补丁分支。
  • 第二步:新分支开发完成后,或者需要讨论的时候,就向main发起一个pull request(简称PR)。
  • 第三步:Pull Request既是一个通知,让别人注意到你的请求,又是一种对话机制,大家一起评审和讨论你的代码。对话过程中,你还可以不断提交代码。
  • 第四步:你的Pull Request被接受,合并进main,重新部署后,原来你拉出来的那个分支就被删除。(先部署再合并也可。)

Git Flow example

分支命名

推荐使用带有意义的描述性名称来命名分支

版本发布分支/Tag示例:v1.0.0

功能分支示例:feature-login-page

修复分支示例: hotfix-#issueid-desc

分支管理习惯

定期合并已经验证成功的分支,即使删除已经合并的分支

保持合适的分支数量

为分支设置合适的管理权限

为 Git 添加代理

国内网络直接 Git clone可能会出现网络错误

1
2
3
4
5
6
7
PS C:\Users\23351\Desktop> git clone https://github.com/jay1an/jay1an.github.io.git jay1an
Cloning into 'jay1an'...
fatal: unable to access 'https://github.com/jay1an/jay1an.github.io.git/': Failed to connect to github.com port 443 after 21075 ms: Couldn't connect to server
PS C:\Users\23351\Desktop> git clone https://github.com/jay1an/jay1an.github.io.git jay1an
Cloning into 'jay1an'...
error: RPC failed; curl 28 Recv failure: Connection was aborted
fatal: expected flush after ref listing

需要在 Git 配置中添加代理

1
2
PS C:\Users\23351\Desktop> git config --global http.proxy 127.0.0.1:7890
PS C:\Users\23351\Desktop> git config --global https.proxy 127.0.0.1:7890

端口与本机的代理程序一致。

image-20240713155436633

配置完之后就可以解决连接问题了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PS C:\Users\23351\Desktop> git clone https://github.com/jay1an/jay1an.github.io.git jay1an
Cloning into 'jay1an'...
error: RPC failed; curl 28 Recv failure: Connection was aborted
fatal: expected flush after ref listing
PS C:\Users\23351\Desktop> git config --global http.proxy 127.0.0.1:7890
PS C:\Users\23351\Desktop> git config --global https.proxy 127.0.0.1:7890
PS C:\Users\23351\Desktop> git clone https://github.com/jay1an/jay1an.github.io.git jay1an
Cloning into 'jay1an'...
remote: Enumerating objects: 2264, done.
remote: Counting objects: 100% (904/904), done.
remote: Compressing objects: 100% (245/245), done.
remote: Total 2264 (delta 364), reused 846 (delta 324), pack-reused 1360
Receiving objects: 100% (2264/2264), 63.95 MiB | 2.55 MiB/s, done.
Resolving deltas: 100% (648/648), done.
Updating files: 100% (807/807), done.