likes
comments
collection
share

记这些场景下Git该如何操作

作者站长头像
站长
· 阅读数 3

1. 前话

对于代码版本管理工具Git大家肯定已经玩的十分熟透了,但🌶️🐔我相信大多数同学们的日常使用流程用到的Git操作命令并不多,对于一些特殊场景无从下手,本篇就记一下特殊场景下Git该如何操作。

2. 入门

虽然大佬们Git玩的很熟透了,为了照顾下初学读者,就先简单过一下日常使用流程🌚。

2.1 初始化仓库

> git init #初始化仓库
> git add README.md #新增变更
> git commit -m "first commit" #提交变更,自动生成一条主分支

2.2 创建分支

有两种方式创建分支👇

  1. 先创建新分支,再切换到新分支:
> git branch test #创建新分支
> git checkout test #切换到新分支
  1. 直接创建并切换到新分支:
> git checkout -b test #创建并切换到新分支

2.3 变更与暂存区

变更在被提交前需存入暂存区。

> git add README.md #将README.md存入暂存区

若不希望被提交,则需要取出暂存区。

> git restore --staged README.md #将README.md取出暂存区

若希望还原变更,执行下面命令即可。

> git restore README.md #还原README.md变更

2.4 提交变更

> git commit -m "update" 

2.5 同步分支

同步分支有两种方式,分别是「合并」和「变基」👇

  1. 合并同步分支操作如下:
> git merge master #合并maser分支

若出现冲突,解决冲突后提交变更即可,演示如下:

> git merge master
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

> git add .  
> git commit -m "merge"
  1. 变基同步分支操作如下:
> git rebase master #变基maser分支

若出现冲突,按提示解决冲突即可,演示如下:

> git rebase master    
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

> git add .
> git rebase --continue

2.6 查看分支记录

> git log #查看分支记录

3. 正文

如前话所言,下面用场景讲解Git操作。

3.1 如何修改提交信息?

再🐂🍺的大佬们也会写bug,同时在PM的一再催促下提交代码写的提交信息难免会比较「无效」,例如:

> git commit -m "update"

「提交信息」的「格式准确性」与「内容丰富度」能够方便在多人协作场景下快速找到「问题提交」,也有效的给Code Review提效。

如果跟大佬一样提交了「无效信息」咋办?补救方法就是「修改它」。修改前要区分这两种情况,是「本次提交」还是「历史提交」。

3.1.1 修改本次提交

修改本次提交比较简单,直接一句话👇

> git commit --amend

敲入回车键后进入了vi编辑器,修改后「:wq」保存退出即可。

3.1.2 修改历史提交

  1. 首先需要找到需修改提交信息的提交记录的上一个提交记录Hash:
> git log #查看提交记录

commit 6cf0b908bcb43b212ad99de424c11ada6ea4bf38 (HEAD -> test)
Date:   Tue Jul 5 17:14:10 2022 +0800

    feat: do xxx

commit 5c6b202acc6b270cc07ebc8f45f3e75205812950
Date:   Tue Jul 5 17:03:31 2022 +0800

    update

commit fe850e5cfbde0b1e40a77f4db40112c3d864a778
Date:   Tue Jul 5 17:13:29 2022 +0800

    first commit
...

上一次的提交信息为“update”明显不符合规范,要修改该提交信息,那么拿到该提交的上一个提交的Hash值为fe850e5cfbde0b1e40a77f4db40112c3d864a778

  1. 用「交互式变基」的操作进行修改提交信息,演示如下:
> git rebase -i fe850e5cfbde0b1e40a77f4db40112c3d864a778 #交互式变基

敲入回车键后进入vi编辑器,内容如下:

pick 5c6b202 update
pick 6cf0b90 feat: do xxx

# Rebase fe850e5..6cf0b90 onto fe850e5 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.

交互式变基给了很多指令(Commands),根据上面的命令描述,我们选择使用「reword」指令去修改提交信息:

reword 5c6b202 update #使用「reword」进行修改提交信息
pick 6cf0b90 feat: do xxx

...

保存退出后自动进入vi编辑器编辑提交信息,再次保存退出即可。

3.2 如何合并多个提交?

还是场景一的大佬,TA又被PM催着提交代码,因为急躁,所以TA在第一次提交代码的时候漏提交了变更,所以进行了第二次提交把遗漏的变更补上了。

这两个提交都是是为了干一件事情,因为不可抗因素弄成了两次提交,显然这是冗余的,除了让提交记录多一条让老板感觉产出多一些。那该咋办?要怎么「合并」它们?

Git当然有方式去做「合并」,方法也是多样的:

  1. 直接合并两个提交
  2. 删除前一个提交

3.2.1 直接合并两个提交

跟场景一类似,先找到这两次提交的前一个提交的Hash👇

> git log #查看提交记录

commit 31857746a70d939a05a07311b7e48616536a5add (HEAD -> test)
Date:   Tue Jul 5 20:34:52 2022 +0800

    feat: add xxx

commit 17f9961b200eb1bec39dc0073485de9efaa4353c
Date:   Tue Jul 5 20:34:46 2022 +0800

    feat: add xxx

commit a2c6788c6cd87e9f27afa765bf6ca09b64299e6b (master)
Date:   Tue Jul 5 15:04:19 2022 +0800

    first commit

然后直接祭上「交互式变基」这个大杀器👇

> git rebase -i a2c6788c6cd87e9f27afa765bf6ca09b64299e6b

控制台进入vi编辑器👇

pick 17f9961 feat: add xxx
pick 3185774 feat: add xxx

# Rebase a2c6788..3185774 onto a2c6788 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.

通过交互命令描述可知,我们可以使用「squash」命令进行合并提交,修改后内容如下👇

pick 17f9961 feat: add xxx
squash 3185774 feat: add xxx #使用「squash」进行与前一个提交合并

保存退出后控制台再次进入vi编辑器,提示修改提交信息👇

# This is a combination of 2 commits.
# This is the 1st commit message:

feat: add xxx

# This is the commit message #2:

feat: add xxx

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Tue Jul 5 20:34:46 2022 +0800
#
# interactive rebase in progress; onto a2c6788
# Last commands done (2 commands done):
#    pick 17f9961 feat: add xxx
#    squash 3185774 feat: add xxx
# No commands remaining.
# You are currently rebasing branch 'test' on 'a2c6788'.
#
# Changes to be committed:
#       modified:   README.md
#

修改后再次保存退出便完成合并提交操作。

3.2.2 删除前一个提交

删除前一个提交步骤跟直接合并两个提交类似,只是在「交互式变基」的vi编辑器中选择的命令存在区别👇

drop 17f9961 feat: add xxx #使用「drop」删除该提交
pick 3185774 feat: add xxx

保存退出后需要进行冲突处理,我们手动保存前一个提交的内容后执行git add .,然后继续执行git rebase --continue,最后填写完提交信息保存退出即可完成删除提交操作。

3.3 如何使用其他分支的某次提交的变更?

多人协作中存在这么一个场景,A和B分别使用各自的分支开发新功能,在开发过程中A提交了一个无关业务的新增通用组件的变更,B也需要用这个通用组件,该如何做?

B无论使用merge(合并)还是rebase(变基)显然都会导致合并了A的未完成开发的业务代码,能不能只选取某个提交进行合并?

Git提供的Cherry Pick命令就派上用场了。这里简单演示一下:

> git checkout a #切换到a分支
Switched to branch 'a'

> git log #查看a分支提交记录
commit 4ad11274260cbbb22fda0992f60508e6c434f422 (HEAD -> a)
Date:   Tue Jul 5 21:02:00 2022 +0800

    feat: add a2

commit 57f2a730faa8efcfcfcb38015e9b7bb3e4693ce4
Date:   Tue Jul 5 21:01:53 2022 +0800

    feat: add a1
...
    
> git checkout b #切换到b分支
Switched to branch 'b'

> git cherry-pick 57f2a730faa8efcfcfcb38015e9b7bb3e4693ce4 #使用cherry-pick合并a分支选定的一个提交
[b e50820d] feat: add a1
 Date: Tue Jul 5 21:01:53 2022 +0800
 1 file changed, 0 insertions(+), 0 deletions(-)

4. 最后

划水摸鱼了两个月,都不高产了😂,计划后面写「React源码通读系列」哈~ 大佬们觉得本篇有用的话,期待给个小心心❤️