Git - 补充工作中常用的一些命令
- 1 一些场景
- 2 git cherry-pick \<commit-hash\> 和 git checkout branch \-\- file
- 3 git checkout commitID和git reset --hard commitID的区别
- 3.1 git checkout commitID
- 3.2 git reset --hard commitID
- 3.3 使用场景对比
- 4 git rebase -i
1 一些场景
如何将分支hotfix/bug-123的提交 abc,拿到 feature/bug-123分支?
假设你当前在feature分支
有三种方法:
- 使用 git cherry-pick
git checkout feature/bug-123
git cherry-pick abc
# 解决冲突(如果有)
git add <冲突文件>
git cherry-pick --continue
# 此时提交 abc 现在已经被应用到 feature/bug-123 分支
- 使用 git merge
如果 hotfix/bug-123 分支只有提交 abc 是你需要的,可以直接合并整个分支
git checkout feature/bug-123
git merge hotfix/bug-123
# 解决冲突(如果有)
git add <冲突文件>
git commit
# 此时hotfix/bug-123 分支的提交(包括 abc)现在已经被合并到 feature/bug-123 分支
- 使用 git rebase
如果 feature/bug-123 分支需要保持线性历史,可以使用 rebase
git checkout feature/bug-123
git rebase hotfix/bug-123
# 解决冲突(如果有)
git add <冲突文件>
git rebase --continue
# 此时feature/bug-123 分支现在包含了 hotfix/bug-123 分支的提交(包括 abc),并且提交历史是线性的
推荐方法:使用 git cherry-pick,因为它只提取指定提交,不会引入其他无关的更改
2 git cherry-pick <commit-hash> 和 git checkout branch -- file
- git cherry-pick
- 作用:将某个提交(commit)应用到当前分支
- 使用场景:当你需要将另一个分支的某个特定提交(包括其更改)应用到当前分支时使用
- 操作对象:提交(commit),而不是单个文件
- 命令格式:
git cherry-pick <commit-hash>
- 特点:
- 会将指定提交的更改应用到当前分支,并生成一个新的提交。
- 适用于跨分支复制某个提交的更改。
- 如果提交涉及多个文件,所有文件的更改都会被应用。
- git checkout branch – file
- 作用:将某个分支中的特定文件覆盖到当前工作目录。
- 使用场景:当你需要将另一个分支的某个文件的状态复制到当前分支时使用。
- 操作对象:单个文件,而不是提交。
- 特点:
- 只操作单个文件,不会影响其他文件。
- 不会生成新的提交,你需要手动 git add 和 git commit。
- 适用于从另一个分支恢复某个文件的状态。
总结:
- 如果你需要复制某个提交的所有更改,使用 git cherry-pick。
- 如果你只需要复制另一个分支的某个文件,使用 git checkout branch – file
3 git checkout commitID和git reset --hard commitID的区别
git checkout commitID
和 git reset --hard commitID
都可以将 Git 仓库的状态恢复到指定的提交,但是它们的工作方式和影响有所不同。具体区别如下:
3.1 git checkout commitID
- 作用:切换到指定的提交
commitID
,使工作目录和暂存区的文件恢复到该提交的状态 - 行为:
- 该命令会让你的工作目录变为与 commitID 对应的文件内容一致,但是不会修改当前分支的历史,你依然停留在当前分支上
- 它会进入 分离头指针(detached HEAD) 状态,也就是说,Git 不再指向任何分支,而是指向了一个特定的提交。如果在这种状态下进行新的提交,Git 会创建一个新的分支,除非你显式地创建一个新分支
- 不会改变暂存区(index)的状态,因此不会丢失任何暂存的更改
- 适用场景
- 你想查看某个特定提交的内容,或者临时检查某个历史版本
- 你只想查看一个特定的提交,而不想修改当前分支
3.2 git reset --hard commitID
- 作用:将当前分支的指针重置到指定的 commitID,同时会重置工作目录和暂存区,使它们与该提交一致
- 行为:
- 改变当前分支的历史:它会把当前分支的指针(例如 master 或 main)指向 commitID,从而“丢弃”该提交之后的所有更改和提交
- 更改工作目录和暂存区:它会将工作目录中的所有文件和暂存区的文件恢复到 commitID 所对应的状态,所有未提交的更改都会丢失
- 删除历史提交:所有在 commitID 之后的提交都会被删除,分支的历史会被重写
- 适用场景:
- 你想彻底丢弃一些提交并重置代码状态,或者将分支回滚到某个特定提交
- 要小心使用,因为会删除所有本地更改,并且无法恢复被丢弃的提交(除非你有备份)
3.3 使用场景对比
- 如果你只是想查看某个提交,不打算修改当前分支,可以使用 git checkout commitID
- 如果你想删除当前分支上的提交,并回到某个历史点,丢弃所有后续的更改,则使用 git reset --hard commitID
4 git rebase -i
启动交互式 rebase
- 命令形式:
git rebase -i <commit-hash>
或git rebase -i HEAD~n
- 编辑 rebase 的操作:
- 示例:
pick 1234567 Commit message 1
pick 2345678 Commit message 2
- 以下是一些常用的命令和作用:
- pick:保留该提交
- reword:保留提交,但修改提交信息
- edit:保留提交,但让你修改该提交的内容(例如,修改代码或文件)
- squash 或 s:将当前提交与前一个提交合并,并保留两者的提交信息
- fixup 或 f:将当前提交与前一个提交合并,并丢弃当前提交的提交信息(只保留前一个提交的信息)
- drop:删除当前提交
- exec:在该提交时执行一个命令
- 示例:
例如,你想将第 2 和第 3 个提交合并到第一个提交中,并修改它们的提交信息,可以将文件编辑为如下所示
pick 1234567 Commit message 1
squash 2345678 Commit message 2
squash 3456789 Commit message 3
编辑完成后,保存并关闭编辑器,Git 会继续执行 rebase 操作,应用你选择的操作。
- 如果有冲突,Git 会暂停 rebase,要求你解决冲突。你需要手动解决冲突,解决完冲突后,要add到暂存区,但不需要提交,然后使用
git rebase --continue
继续 rebase - 如果你不想继续 rebase,可以使用
git rebase --abort
来放弃 rebase 操作
编辑提交信息
如果你选择了 squash
或 reword
,Git 会打开一个新的编辑器,允许你编辑提交信息。你可以选择保留原始信息,或者将提交信息合并为新的内容