Skip to content

Git常见操作

设置仓库

初始化本地仓库(init)

我们可以使用git init命令在当前或指定目录中初始化一个新的本地仓库,创建.git目录并设置仓库的基本配置。初始化仓库完成后,你可以使用其他 Git 命令来进行版本控制、提交更改以及与远程仓库进行交互。

命令

shell
git init [<dir>] [--template=<template_directory>]
  • <dir>(可选):指定需要初始化仓库的本地位置,如果不指定则默认为命令执行的当前目录。
  • --template=<template_directory>(可选):使用指定的模板目录来初始化仓库,模板目录包含了初始化仓库时所需的默认文件和配置。

示例

初始化本地仓库

shell
git init ./init_example

命令执行完成后即可看到init_example目录下有一个.git目录

image-20240313152626225

克隆远程仓库(clone)

将远程服务器的仓库复制到本地的操作被称为克隆,克隆操作通常是一次性的,一旦开发人员获得了远程仓库的工作副本,之后所有版本控制操作和协作都通过其本地仓库进行管理。

clone-example

命令

shell
git clone [--branch <tag>] [--depth=<number>] <repo_url> [<dir>]
  • --branch <tag>(可选):通过指定 <tag> 来克隆仓库的特定分支。如果不指定则将克隆仓库的所有分支。

  • --depth=<number>(可选):通过指定 <number> 来限制克隆的深度,即需要克隆的仓库的提交记录数量,这也被称为浅克隆。如果不指定则将克隆完整的提交记录。

    为何需要浅克隆?

    因为如果克隆的仓库存在大量的提交记录(例如千万条),克隆全部的提交记录则会导致克隆时间增加并且也会增加仓库占用的硬盘空间,而且较为久远的提交记录并无太大作用。

  • <repo_url>(必须):指定需要克隆的仓库地址。

  • <dir>(可选):指定将克隆的仓库存放在本地的位置,如果不指定则默认为命令执行的当前目录。

示例

克隆仓库

shell
git clone https://github.com/JunLiangWangX/mianshi.git

克隆完成则可以在命令执行的当前目录看到克隆的文件

image-20240313110705607

克隆仓库特定分支

shell
git clone --branch dev https://github.com/JunLiangWangX/mianshi.git

克隆完成后进入克隆的文件执行git branch命令则看到仅克隆了dev分支

image-20240313110730785

浅克隆

git clone --depth 1 https://github.com/JunLiangWangX/mianshi.git

克隆完成后进入克隆的文件执行git log命令则看到仅克隆1条提交记录

image-20240313111913575

分支相关

在Git仓库中一条分支就代表着一条独立的开发线,分支允许开发人员在不影响主线开发的情况下进行并行开发,实现新功能或修复错误。待完成任务后,又可以将分支合并回主线或其他分支。

git分支

上面的图表展示了一个具有两条独立开发线的仓库,一条用于一个小功能,另一条用于一个长期运行的功能。通过在分支中开发它们,不仅可以并行地处理两者,而且还可以保持main分支不受可疑代码的影响。

对于分支的查询/创建/删除/跟踪/切换主要使用了git branchgit checkout以及git push等命令,下面我们就开始详细介绍。

查看分支

我们可以通过git branch命令查看本地仓库的所有分支

shell
git branch

image-20240314172305383

通过加-a参数即可查看与本地仓库关联的远程仓库的所有分支

shell
git branch -a

image-20240314172327591

创建分支

我们可以通过以下命令为本地仓库创建分支。

shell
git branch <branch_name> [<remotes_branch_name>]
  • <branch_name>(必须):指定分支名称。
  • <remotes_branch_name>(可选):指定创建的分支需要关联(跟踪)的远程仓库的分支,不指定则不关联远程仓库分支。

image-20240314172408478

执行该命令使用当前本地分支创建远程分支,创建远程分支需要在已有的本地仓库且未与远程分支关联的分支下执行以下命令。

git push <remote_repo> <remote_branch_name>
  • <remote_repo>(必须):指定远程仓库,一般为origin。
  • <remotes_branch_name>(必须):指定创建的远程仓库分支的名称。

image-20240314173959320

切换分支

我们可以通过以下命令切换当前分支。

shell
git checkout <branch_name>
  • <branch_name>(必须):指定需要切换的分支名称。

image-20240315105855406

我们还可以使用该命令加-b参数,新建并切换到新建的分支。

shell
git checkout -b <branch_name> [<remotes_branch_name>]
  • <branch_name>(必须):指定需要新建并切换的分支名称。
  • <remotes_branch_name>(可选):指定创建的分支需要关联(跟踪)的远程仓库的分支,不指定则不关联远程仓库分支。

image-20240315110113192

删除分支

我们可以通过以下命令删除本地分支

shell
git branch -d <branch_name>
  • <branch_name>(必须):指定需要删除的本地分支名称。

image-20240315114427115

如果分支有未合并的更改,使用上述删除命令 git会阻止您删除该分支,们可以通过以下命令强制删除本地分支

shell
git branch -D <branch_name>
  • <branch_name>(必须):指定需要删除的本地分支名称。

重命名分支

我们可以通过以下命令重命名本地仓库分支的名称

shell
git branch <branch_name> -m <re_branch_name>
  • <branch_name>(必须):需要修改名称的分支的原始名称。
  • <re_branch_name>(必须):新分支名称。

image-20240315110904491

跟踪远程分支

跟踪远程分支是git中的术语,本地仓库分支关联远程仓库分支即称为跟踪,跟踪远程分支后可以与他人同步和协作开发。

我们可以通过以下命令查看当前本地分支跟踪的远程分支

shell
git branch -vv

image-20240315113037950

我们可以通过以下命令将本地分支关联到远程仓库分支,也可以使用该命令切换本地分支关联的远程分支。

shell
git branch <branch_name> --set-upstream-to=<remote_repo>/<remote_branch_name>
  • <branch_name>(必须):需要关联的本地分支的名称。
  • <remote_repo>(必须):指定远程仓库,一般为origin。
  • <remotes_branch_name>(必须):指定需要关联的远程分支的名称。

image-20240315113910375

标签相关

在Git中,标签(Tag)是用于标记特定提交的不可变引用,它们是版本控制中的一个重要概念,用于标识重要的里程碑、版本号或发布版本等

tag-example

与分支不同,标签是静态的,不会随着新的提交而移动。一旦创建了标签,它会始终指向特定的提交,不会自动更新

Git中有两种类型的标签:轻量标签(Lightweight Tag)附注标签(Annotated Tag)

  • 轻量标签(Lightweight Tag):轻量标签只是指向特定提交的引用。它们是最简单的标签形式,只是一个指针,没有额外的信息。创建轻量标签时,只需指定标签名称和目标提交即可。
  • 附注标签(Annotated Tag):附注标签是包含额外信息的对象,其中包括标签的作者、创建日期、标签消息等。创建附注标签时,会创建一个独立的Git对象,存储标签的信息,并将其与特定提交关联。

标签的创建和使用可以帮助您在版本历史中标记重要节点,例如软件发布、里程碑完成等。它们提供了一个易于引用的指针,可以方便地访问特定的提交,下面我们具体学习标签相关的命令吧!

查看本地仓库标签列表

我们可以通过以下命令查看本地仓库的标签列表

shell
git tag [-l "<search_rule>"]
  • -l "<search_rule>"(可选):用于列出匹配特定模式的标签。例如,git tag -l "v1.*"将列出所有以"v1."开头的标签。

image-20240407111031478

查看远程仓库标签列表

我们可以通过以下命令查看远程仓库的标签列表

shell
git ls-remote --tags <remote_repo>
  • <remote_repo>(必须):指定远程仓库,一般为origin。

image-20240407145712662

查看标签详情

我们可以通过以下命令查看标签详情内容,包括与标签关联的提交、作者、日期和标签消息等。

shell
git show <tag_name>
  • <tag_name>(必须):指定需要查看详情的标签名称。

image-20240407112005885

创建轻量级标签

我们可以通过以下命令创建轻量级标签

shell
git tag <tag_name> [<commit_hash>]
  • <tag_name>(必须):指定创建的标签名称。
  • <commit_hash>(可选):指定为某次提交创建标签,不指定则默认为最近一次提交。

image-20240407112602352

创建附注标签

我们可以通过以下命令创建附注标签

shell
git tag -a <tag_name> -m "<tag_message>" [<commit_hash>]
  • <tag_name>(必须):指定创建的标签名称。
  • "<tag_message>"(必须):指定附注标签的消息。
  • <commit_hash>(可选):指定为某次提交创建标签,不指定则默认为最近一次提交。

image-20240407144655271

创建远程仓库标签

在本地仓库创建好标签后,我们可以通过以下命令将添加的标签同步到远程仓库

shell
git push <remote_repo> <tag_name>
  • <remote_repo>(必须):指定远程仓库,一般为origin。
  • <tag_name>(必须):指定需要同步到远程仓库的标签名称。

image-20240407152919039

删除本地仓库标签

我们可以通过以下命令删除本地仓库标签

shell
git tag -d <tag_name>
  • <tag_name>(必须):指定需要删除的标签名称。

image-20240407153152435

删除远程仓库标签

我们可以通过以下命令删除远程仓库标签

shell
git push <remote_repo> --delete <tag_name>
  • <remote_repo>(必须):指定远程仓库,一般为origin。
  • <tag_name>(必须):指定需要删除的标签名称。

image-20240407154053395

重新标记/替换旧标签

如果您尝试创建与现有标签具有相同标识符的标签,Git 将抛出如下错误:

bash
fatal: tag 'v0.4' already exists

此外,如果您尝试使用现有标签标识符来标记较旧的提交,Git 将抛出相同的错误。

如果您必须更新现有标签,则-f FORCE必须使用该选项。

css
git tag -a -f v1.4 15027957951b64cf874c3557a0f3547bd83b3ff6

执行上述命令会将提交映射15027957951b64cf874c3557a0f3547bd83b3ff6v1.4标签标识符。它将覆盖v1.4标签的任何现有内容。

保存更改

在Git中保存文件更改与其他软件不太一样,这是因为Git在本地仓库与用户之间还存在一个暂存区,因此想要保存文件必须经过两个流程:保存更改至暂存区——>提交更改到本地仓库。并且当更改文件处于不同位置时,拥有不同的状态:

  • 已修改(Modified):文件已被修改,但尚未保存到暂存区。
  • 已暂存(Staged):修改的文件已经添加到暂存区,准备提交到版本控制系统。
  • 已提交(Committed):更改已经提交到本地仓库。

save-change-example

通过这两个步骤,您可以将文件的更改保存到Git的版本历史记录中,以便日后查看、回滚或与其他开发者共享。暂存区的存在使您能够选择性地将更改提交,而不是一次性提交所有更改,从而提供了更大的灵活性

查看文件状态

我们可以通过以下命令查看文件当前的状态

shell
git status [--short]
  • --short(可选):指定为简洁模式显示。

image-20240319110701305

暂存更改

我们可以通过以下命令暂存文件的更改

shell
git add <file|dir>
  • <file|dir>(必须):指定需要暂存的文件或是文件夹,可使用通配符。

image-20240319112702022

取消暂存更改

我们可以通过以下命令取消暂存文件的更改

shell
git restore --staged <file|dir>

image-20240319113112193

丢弃已修改但未暂存的文件

我们可以通过以下命令丢弃已修改但未暂存的文件

shell
git checkout --<file|dir>
  • <file|dir>(必须):指定需要丢弃的文件或是文件夹,可使用通配符。

image-20240409112837741

提交到本地仓库

我们可以通过以下命令将修改的文件提交到本地仓库

shell
git commit [-a] [-m "message"]
  • -a(可选):选择更改的文件提交,即便是未暂存的文件也可直接提交。
  • -m "message"(可选):指定提交的消息。

image-20240319174519696

查看提交记录

我们可以通过以下命令查看仓库的提交记录

shell
git log [--oneline] [--author="Author Name"] [--since="yyyy-mm-dd"] [--until="yyyy-mm-dd"] [--grep="keyword"]
  • --oneline(可选):以简洁的单行格式显示提交记录。
  • --author="Author Name"(可选):只显示指定作者的提交记录。
  • --since="yyyy-mm-dd"(可选):只显示指定日期之后的提交记录。
  • --until="yyyy-mm-dd"(可选):只显示指定日期之前的提交记录。
  • --grep="keyword"(可选):只显示包含指定关键字的提交记录。

image-20240319173824359

回退提交(清除提交记录)

我们可以通过以下命令回退提交,该命令会清除提交记录。

shell
git reset [--soft|--mixed|--hard] HEAD~<number>
  • --soft|--mixed|--hard(可选):回退后提交的文件状态。
    • --soft:提交的文件状态更改为已暂存。
    • --mixed:提交的文件状态更改为已修改。
    • --hard:提交的文件直接删除。
  • <number>(必须):指定回退到最近第几次提交记录。

image-reset-commit

回退提交(不清除提交记录)

我们可以通过以下命令回退提交,该命令不会清除提交记录。

shell
git revert <commit-SHA1>
  • <commit_hash>(必须):指定回退到某次提交。

image-20240409151427232

贮藏更改

Git 中的贮藏(stash)操作是一种非常有用的功能,它允许开发者临时保存工作目录中的修改,以便稍后再次恢复。在软件开发过程中,经常会遇到需要暂时保存但又不想提交的修改的情况,这时候贮藏操作就派上了用场。

贮藏操作可以将当前工作目录中的更改保存在一个临时位置,以便稍后再恢复。当您在进行一些修改但不想立即提交时,可以使用贮藏操作。这些修改可能是尚未完成的工作、临时性的调试代码或者与当前任务无关的更改。通过贮藏这些更改,您可以将工作目录还原到干净的状态,然后在需要时再重新应用这些更改。

stash-example

在 Git 中,使用贮藏操作非常简单,主要使用 git stash 命令,你可以执行一系列操作,包括查看、恢复、删除以及添加贮藏。接下来我们就详细学习下贮藏相关的命令吧!

贮藏更改

我们可以通过以下命令贮藏更改的文件,暂时保存工作目录中的修改,并将其存储在一个临时位置,以便稍后再次恢复。

shell
git stash [save "贮藏描述"] [-u]
  • save "贮藏描述"(可选):指定贮藏文件的描述。
  • -u(可选):指定贮藏包括未跟踪文件的更改。

image-20240402170702761

查看贮藏列表

我们可以通过以下命令查看贮藏列表,这个命令将显示所有贮藏的详细信息,包括每个贮藏的唯一标识符、贮藏时的提交信息以及可能提供的描述。。

shell
git stash list

image-20240402170932513

删除所有贮藏

我们可以通过以下命令删除所有贮藏,执行此命令将清除所有当前存储的贮藏,因此请确保您不再需要这些贮藏中的任何更改。

shell
git stash clear

image-20240402171449653

删除指定贮藏

我们可以通过以下命令删除指定的贮藏,通过提供<stash标识符>,您可以精确地指定要删除的贮藏,而不会影响其他贮藏的状态。

shell
 git stash drop <stash标识>
  • <stash标识符>(必须):指定需要删除的贮藏标识符。

image-20240402173151494

应用贮藏

我们可以通过以下命令应用贮藏,该命令可以帮助你恢复之前贮藏的更改,而不会删除贮藏记录。

shell
 git stash apply <stash标识>
  • <stash标识符>(可选):指定需要应用的贮藏标识符,如果不指定则应用最近一次贮藏。

image-20240403104142279

应用后删除贮藏

我们可以通过以下命令应用后删除贮藏,该命令可以帮助你恢复之前贮藏的更改,并在应用后立即删除贮藏记录。

shell
 git stash pop <stash标识>
  • <stash标识符>(可选):指定需要应用的贮藏标识符,如果不指定则应用最近一次贮藏。

image-20240403104712535

取消文件跟踪

默认情况下,Git管理代码版本时会对所有文件进行跟踪,但有些时候我们并不希望项目中的一些文件上传到远程仓库或公共仓库中,例如密钥,个人隐私文件等。因此Git提供了两种忽略跟踪文件的方式.gitignore文本文件与git rm命令!

.gitignore

.gitignore是一个位于仓库根目录的文本文件,它用于指定哪些文件或目录应该被Git忽略,不应该被纳入版本控制。你可以自由创建.gitignore文件并在其中列出要忽略的文件、目录或匹配模式。

例如,假设你希望忽略名为config.ini的文件和logs目录,你可以在.gitignore文件中添加以下内容:

powershell
config.ini
/logs/

添加该.gitignore文件后会有如下效果:

image-20240408155422108

.gitignore匹配规则

规则匹配文件示例解释
**/logslogs/debug.log
logs/monday/foo.bar
build/logs/debug.log
双星号(**)表示匹配任何层级的目录或文件。
*.logdebug.log
foo.log
.log
星号(*)表示匹配零个或多个字符。
debug?.logdebug0.log
debugg.log
问号(?)表示匹配一个字符。
debug[0-9].logdebug0.log
debug1.log
方括号([])表示匹配指定范围内的单个字符。
/loglog/a.txt
log/b.txt
斜杠(/)表示匹配的是目录。
!a.txtb.txt
c.txt
d.txt
感叹号(!)用于否定一个模式,即如果文件匹配了前面的模式,但同时也匹配了后面的否定模式,那么该文件将不会被忽略。

忽略已提交的文件

如果你想忽略之前已经提交到版本库的文件,具体步骤如下:

  1. 编辑.gitignore文件,添加要忽略的文件的规则。例如,将debug.log添加到.gitignore文件中。
  2. 运行git rm --cached debug.log命令将debug.log文件从仓库中删除。--cached选项会保留本地目录文件,如果你希望将文件从仓库和本地文件系统中都删除,可以省略--cached选项。
  3. 运行git commit"命令,提交对.gitignore文件的修改和文件删除的操作。

通过这些步骤,你可以忽略并停止跟踪之前已经提交的文件,如下所示:

image-20240408163408798

提交被忽略的文件

如果你想强制将一个被忽略的文件提交到仓库中,可以使用git add -f(或git add --force)选项,例如你想提交被忽略的debug.log文件,可使用以下命令:

shell
git add -f debug.log

然而,更好的做法应该在.gitignore文件中定义一个例外规则,以便明确指定要提交的特定文件,这样做更清晰、不容易引起不必要的麻烦,如下:

powershell
*.log
!debug.log

删除忽略的文件

如果你想从工作目录中删除未跟踪的文件和目录,以清理工作区,你可以使用以下命令:

shell
git clean [-n|f|d|x]
  • -n--dry-run(可选):试运行,将显示哪些文件将被删除,并不会实际删除。
  • -f--force(可选):强制执行删除操作。
  • -d(可选):指定删除未跟踪的目录。
  • -x(可选):指定删除.gitignore忽略规则中指定的文件和目录。

image-20240408171118305

协作相关

获取远程仓库的更新

我们可以使用 git fetch 或者 git pull 两个命令从远程仓库获取最新的提交和分支信息,两者区别如下:

  • git fetch:该命令将远程仓库的最新更改下载到本地,但不会自动合并到当前分支。你可以随后使用其他命令(如 git merge 或者 git rebase)来合并或应用这些更改。
  • git pull:该命令从远程仓库获取最新更改,并自动将其合并到当前分支。它实际上是 git fetchgit merge 的组合操作。

git fetch

shell
git fetch [<remote_repo>] [<branch>] [--all] [--prune] [--tags] [--prune] [--dry-run]
  • <remote_repo>(可选):指定要获取更新的远程仓库的名称,不指定则拉取当前仓库的更新。
  • <branch>(可选):指定要获取更新的远程仓库分支的名称,不指定则拉取当前分支的更新。
  • --all(可选):获取所有远程仓库的更新。
  • --prune(可选):在获取更新时,删除本地仓库中已经不存在于远程仓库的引用,以保持同步。
  • --tags(可选):同时获取远程仓库中的标签。
  • --dry-run(可选):模拟运行,显示将要获取的更新,但不会实际执行获取操作。
  • --depth=<number>(可选):通过指定 <number> 来限制获取的深度,即需要获取更新的仓库的提交记录数量,如果不指定则将获取完整的更改记录。

git pull

shell
git pull [<remote_repo>] [<branch>] [--rebase] [--no-rebase] [--ff-only] [--ffy] [--no-commit] [--squash] [--autostash]
  • <remote_repo>(可选):指定要获取更新的远程仓库的名称,不指定则拉取当前仓库的更新。
  • <branch>(可选):指定要获取更新的远程仓库分支的名称,不指定则拉取当前分支的更新。
  • --rebase(可选):使用变基(rebase)而不是合并(merge)来合并远程分支的更改。变基可以产生一个更整洁的提交历史,但也可能导致冲突更难以解决。使用git pull --rebase可以在拉取远程更改之前将本地提交变基到远程分支的顶部。
  • --no-rebase(可选):禁用变基选项,强制使用合并(merge)来合并远程分支的更改。这是git pull命令的默认行为。
  • --ff-only(可选):只允许快进合并(fast-forward merge)。如果远程分支的历史可以直接应用到本地分支而不需要创建新的合并提交,那么合并将会成功。如果不能进行快进合并,则会失败。
  • --ff(可选):尝试进行快进合并,如果无法进行快进合并,则不进行合并。
  • --no-commit(可选):拉取远程更改后不自动生成合并提交。这个选项可以让你在合并之前进行其他操作,例如检查更改或解决冲突,然后手动提交合并结果。
  • --squash(可选):将所有拉取的提交压缩成一个单独的提交。这个选项适用于你想要将远程更改合并为一个更高层次的提交的情况。
  • --autostash(可选):在拉取之前自动储藏(stash)当前分支上的未提交更改,并在合并后重新应用这些更改。这对于在拉取过程中避免冲突非常有用。

推送

当你把更改提交到本地仓库后,可以使用 git push 命令将这些更改推送到远程仓库,这样其他协作者就可以看到并获取你的更改。

下面是git push命令的一般用法:

git push <remote_repo> <branch> [-u] [-f] [--all] [--tags] [--dry-run]
  • <remote_repo>(可选):指定推送到远程仓库的名称,不指定则为当前仓库。
  • <branch>(可选):指定推送到远程仓库分支的名称,不指定则为当前分支。
  • -u--set-upstream:在推送的同时,将本地分支与远程分支进行关联。这样,下次你可以直接使用git push命令进行推送,而不需要显式指定远程仓库和分支。
  • -f--force:强制推送更改,即使这样可能会覆盖其他人的提交。这个选项应该谨慎使用,因为它可能会导致数据丢失或冲突。只在你确信需要覆盖远程分支的情况下才使用它。
  • --all:推送所有分支到远程仓库。默认情况下,git push只会推送当前分支。使用该选项可以将所有本地分支推送到远程仓库。
  • --tags:推送标签到远程仓库。标签是用于标记特定提交的引用。使用该选项可以将本地的标签推送到远程仓库。
  • --dry-run:模拟推送操作,而不进行实际的推送。这个选项可以让你在推送之前预览将要进行的操作,以确保没有意外的结果。

合并

合并(Merge)是将一个分支的更改合并到另一个分支的操作。在Git中,有几种合并策略可以使用,具体取决于你想要实现的合并结果。

快进合并

快进合并(Fast-forward merge)当一个分支的提交历史可以直接应用到另一个分支时,Git会执行快进合并。这种合并不会创建新的合并提交,而是简单地将目标分支指向源分支的最新提交。这种合并只适用于目标分支没有自己的新提交的情况。

fast-forward-before-merge

shell
# 切换到目标分支
git checkout main

# 执行快进合并
git merge Feature

fast-forward-after-merge

普通合并

普通合并(Regular merge)当两个分支都有新的提交时,Git会执行普通合并。这种合并会创建一个新的合并提交,它有两个父提交,代表了两个分支的更改。在合并过程中,Git会尝试自动解决冲突,但如果有冲突无法自动解决,你需要手动解决冲突后再进行提交。

regular-before-merge

shell
# 切换到目标分支
git checkout main

# 执行普通合并
git merge Feature

regular-after-merge

递归合并

递归合并(Recursive merge)是一种特殊的普通合并,它在多个分支之间存在合并关系时使用。当你在一个分支上合并另一个分支,而另一个分支又合并了其他分支时,就会发生递归合并。在这种情况下,Git会创建一个新的递归合并提交,它有多个父提交,代表了多个分支的更改。

recursion-before-merge

shell
# 切换到目标分支
git checkout Main

# 执行递归合并
git merge Fix_Bug Feature

recursion-after-merge

需要注意的是,合并可能会引起冲突, 特别是当两个分支在相同的文件的相同位置进行了不兼容的更改时。在这种情况下,Git会标记冲突,并将冲突的文件标记为未解决状态,你需要手动解决冲突,然后使用git add命令将解决后的文件标记为已解决,最后执行git commit提交合并结果。

变基

变基(rebase)操作是 Git 中的一种常见操作,它允许将一个分支的提交应用于另一个分支上,从而改变提交历史的结构,变基操作实际上是通过将一系列提交复制到另一个基准上来实现的

01-What-is-git-rebase

在变基操作中,你会选择一个基准分支,以及目标分支,然后将基准分支的提交复制到目标分支上。这样可以使目标分支的提交看起来好像是基于基准分支的最新状态进行开发的。

下面是变基操作的一般步骤:

  1. 确保你在基准分支上进行操作:首先,确保你位于要进行变基操作的基准分支上(假设你要将dev变基到main,那么你应该位于dev分支),可以使用 git branch 命令查看当前分支,并使用 git checkout 命令切换到基准分支。
  2. 执行变基操作:运行 git rebase 命令,指定要进行变基操作的目标分支。例如,你要将dev变基到main,那么你应该位于dev分支,并且运行 git rebase main
  3. 解决冲突(如果有):在变基过程中,如果存在冲突,Git 会暂停变基操作,并提示你解决这些冲突。你需要手动编辑文件,解决冲突后,使用 git add 命令将文件标记为已解决。
  4. 完成变基操作:当所有冲突都解决完毕后,使用 git rebase --continue 命令继续变基操作,或者使用 git rebase --abort 命令放弃变基操作。
  5. 合并分支:切换分支到目标分支,然后执行git merge命令,指定要合并的基准分支。例如你要将dev变基到main,这个步骤中,你应该位于main分支,并且运行 git merge dev

注意!谨慎使用变基操作

变基操作会改变提交历史的结构,因此在多人协作或公共分支上使用变基操作时,需要小心使用,以避免引起混乱。

交互式变基

通过 git rebase --interactive 命令,你可以打开一个文本编辑器进行交互式变基操作,文本编辑器将显示当前分支的提交历史,并允许你对每个提交进行操作,例如修改提交消息、合并、删除或重新排序提交等

命令的语法如下:

shell
git rebase --interactive <branch>
  • <branch>(可选):指定目标分支。

运行该命令后,Git 将打开一个文本编辑器,并显示一个类似于以下的界面:

shell
pick 3f4b03e Commit message 1
pick b2a5c1d Commit message 2
pick 8de1a2f Commit message 3

# ...

每个提交都以 pick 开头,后面是提交的哈希值和提交消息。在编辑器中,你可以对每个提交进行以下操作:

  • pick:保持提交不变。
  • reword:修改提交消息。
  • edit:编辑提交的内容。
  • squash:将该提交合并到前一个提交中,并将提交消息合并为一个。
  • fixup:将该提交合并到前一个提交中,但丢弃提交消息。
  • drop:移除该提交。

在编辑器中进行适当的修改后,保存并关闭编辑器,Git 将按照你的修改执行相应的操作,并重新应用提交历史。

注意!谨慎使用交互式变基操作

交互式变基操作修改了提交历史,因此在多人协作或公共分支上使用时必须小心谨慎,以避免造成不可挽回的损失。如果你已经将分支的提交推送到远程仓库,请谨慎执行交互式变基操作,因为它会改变提交历史,可能导致问题。

高级变基操作

假设我们有一个示例存储库,其分支如下:

css
o---o---o---o---o  main
     \
      o---o---o---o---o  featureA
           \
            o---o---o  featureB

featureB 基于 featureA,但是featureB 其实并不依赖于 featureA 的任何更改,我们想要把featureB从feature A分离出来,应用到main分支中。此时就需要使用--onto高级变基命令!

css
// 切换到featureB分支
git rebase --onto main featureA featureB
// 切换到main分支
git merge featureB

执行高级变基操作后,分支如下:

css
                  o---o---o  featureB
                 /
o---o---o---o---o  main
     \
      o---o---o---o---o  featureA

高级变基命令的语法如下:

shell
git rebase --onto <newbase> <oldbase> <branch>
  • <newbase>(可选):指定变基后的目标分支,所有变基操作的提交将被复制到该分支。如果不提供 <newbase> 参数,则默认为当前分支。
  • <oldbase>(可选):指定变基操作的起点。如果不提供 <oldbase> 参数,则默认为当前分支的上一个提交。
  • <branch>(可选):指定要进行变基操作的分支。如果不提供 <branch> 参数,则默认为当前分支。

请勿将本站文章用作商业用途 | 转载请标明来源