关于 Git 二三事
工具往往需要反复检验
关于目录
- 关于描述问题
- 关于经典场景 && 解决方案
- 关于一点点小技巧
- 关于小结
- 关于常用指令合集
关于描述问题
一图胜千言
例子: 选择正确的撤销方法
想要… | 备注 | 解决方案 |
---|---|---|
舍弃工作目录中对一个文件的修改 | 修改的文件未被暂存或提交 | checkout –[file_name] |
舍弃工作目录中所有未保存的变更 | 文件已暂存,但未被提交 | reset –hard |
合并与某个特定提交(但不含)之间的多个提交 | – | reset [commit] |
移除所有未保存的变更,包含未跟踪的文件 | 修改的文件未被提交 | clean -fd |
移除所有已暂存的变更和在某个提交之前提交的工作,但不移除工作目录中的新文件 | — | reset –hard [commit] |
移除之前的工作,但完整保留提交历史记录( “前进式回滚” ) | 分支已经被发布,工作目录是干净的 | revert [commit] |
从分支历史记录中移除一个单独的提交 | 修改的文件已经被提交,工作目录是干净的,分支尚未进行发布 | rebase –interactive [commit] |
保留之前的工作,但与另一提交合并 | 选择 squash(压缩)选项 | rebase –interactive [commit] |
通过清晰区分自己当前所要的场景并频繁使用 git status
查看当前状态,来明辨的场景
关于经典场景 && 解决方案
Q:文件删除造成的变基冲突
First, rewinding head to replay your work on top of it...
Applying: CH10: Stub file added with notes copied from video recording lessons.
Using index info to reconstruct a base tree...
A ch10.asciidoc
Falling back to patching base and 3-way merge...
CONFLICT (modify/delete): ch10.asciidoc deleted in HEAD and modified in CH10: Stub file added with notes copied from video recording lessons.. Version CH10: Stub file added with notes copied from video recording lessons. of ch10.asciidoc left in tree.
Failed to merge in the changes.
Patch failed at 0001 CH10: Stub file added with notes copied from video recording lessons.
The copy of the patch that failed is found in:
/Users/emmajane/Git/1234000002182/.git/rebase-apply/patch
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
关键消息
When you have resolved this problem, run “git rebase –continue”.
此信息告诉我需要按以下步骤操作
- 解决合并冲突
vim [file_name]
- 当合并冲突已经被解决,运行命令
git rebase --continue
- 查看当前状态
git status
- 根据消息
git reset HEAD [file_name]
- 查看状态
git status
- 添加存储
git add [file_name]
- 添加提交
git commit -m [message]
- 根据消息
Q:单个文件合并并冲突造成的变基冲突
Applying: CH10: Stub file added with notes copied from video recording lessons.
Applying: TOC: Adding Chapter 10 to the book build.
Using index info to reconstruct a base tree...
M book.asciidoc
Falling back to patching base and 3-way merge...
Auto-merging book.asciidoc
CONFLICT (content): Merge conflict in book.asciidoc
Recorded preimage for 'book.asciidoc'
Failed to merge in the changes.
Patch failed at 0002 TOC: Adding Chapter 10 to the book build.
The copy of the patch that failed is found in:
/Users/emmajane/Git/1234000002182/.git/rebase-apply/patch
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
解决思路
- 查看 git 状态消息
git status
- 通过 vscode 解决冲突
- 查看 git 状态消息
git status
Q:定位丢失的工作
临时修改
# 查看 log 与 relog 的区别
# 查看压缩过的项目历史
git log --oneline
# 查看本地操作记录
git relog
# 签出特定提交,这时候会处于分离状态
git checkout [commit]
# 遵循 git 提示
git checkout -b [restoring_old_commit]
# 修改完相关工作后, 合并回分支
git checkout [working_branch]
git merge [restoring_old_commit]
# 删除临时分支
git branch --delete [restoring_old_commit]
# 如果已经发布,需要删除远程分支
git push --delete [restoring_old_commit]
复制提交 cherry-pick
# 查看图形化日志
git log --online --graph
# 复制另一个分支的提交 在提交信息的末尾追加一行(cherry picked from commit ...),方便以后查到这个提交是如何产生的。
git cherry-pick -x [commit]
# 复制一段提交,不包含 start_commit
git cherry-pick [start_commit]..[end_commit]
# 复制一段提交,包含 start_commit
git cherry-pick [start_commit]^..[end_commit]
Q:误删除文件
# 通过 HEAD 的快捷方式
git reset HEAD [file_name]
# 通过 checkout 恢复被删除文件
git checout -- [file_name]
# 合并指令
git reset --hard HEAD -- [file_name]
# 批量操作
git reset --hard HEAD
Q:撤销分支合并
理想情况下,合并分支后,立马意识到这是个错误合并。Git 在执行合并时候会保存一个指向最新提交的指针 ORIG_HEADs
,这时候直接通过 reset 取消合并即可
git reset --merge ORIG_HEAD
若没有意识到这是个错误合并,已经继续提交了,那么可以开始头脑风暴了
# 稳健的创建一个分支
git checkout -b [pre_branch]
# 截取希望保存的 commit
git cherry-pick commit_to_restore
# 回到错误分支
git checkout [error_branch]
# 回退
git reset [last_correct_commit]
# 再次合并
git merge [good_commits]
关于一点点小技巧
# stash 进行保存, 该命令只会保存已知的文件进度
git stash save
# 为加入未跟踪文件,可添加 --include-untracked
git stash save --include-untracked
# 亦可以丢弃它们
git stash save
git clean -D
# 查看保存的 stash
git stash list
# 查看 stash 中的内容
git show stash@{0}
# 可以通过添加内容来区分 stash
git stash save --include-untracked "msg"
# 可以继续工作
git stash list
git stash apply stash@{0}
# 删除 stash
git stash drop stash@{0}
# 应用后删除 stash
git stash pop stash@{0}
关于小结
本文是关于《Git 团队协作》的阅读笔记,该书已经过于久远,很多指令也已经更新,例如 git checkout [branch]
已经可以使用 git switch [branch]
来替代了,阅读之后还是能比较清晰的
关于常用指令合集
命令 | 用途 |
---|---|
git clone [url] | 下载远程仓库 |
git init | 初始化仓库 |
git status | 获取 git 状态 |
git add –all OR git add . | 将所有修改过的文件和新文件添加至仓库的暂存区 |
git commit -m ‘[message]’ | 将所有暂存的文件提交至仓库 |
git log | 查看项目历史 |
git log –oneline | 查看压缩过的项目历史 |
git branch –list | 列出所有本地分支 |
git branch –all | 列出本地和远程分支 |
git branch –remotes | 列出所有远程分支 |
git checkout –track [branch_name] | 创建远程分支的副本,在本地使用 |
git checkout [branch_name] | 切换到另一个本地分支 |
git checkout -b [branch_name] [branch_name_parent] | 从指定分支创建一个新分支 |
git add [file_name] | 仅暂存并准备提交指定文件 |
git add –patch [file_name] | 仅暂存并准备提交部分文件 |
git add HEAD [file_name] | 从暂存区移除提出的文件修改 |
git commit –amend | 使用当前暂存的修改更新之前的提交,并提供一个新的提交消息 |
git show commit | 输出某个提交的详细信息 |
git tag tag commit | 为某个提交对象打上标签 |
git tag | 列出所有标签 |
git show tag | 输出所有带标签提交的详细信息 |
git remote add [remote_name] [url] | 创建一个指向远程仓库的引用 |
git push | 将当前分支上的修改上传至远程仓库 |
git remote –verbose | 列出所有可用远程连接中 fetch 和 push 命令使用的 URL |
git push –set-upstream [remote_name] [branch_local] [branch_remote] | 将本地分支的副本推送至远程服务器 |
git merge [branch] | 将当前存储在另一分支的提交并入当前分支 |
git push –delete [remote_name] [branch_remote] | 在远程服务器中移除指定名称的分支 |
git checkout -b [branch_name] | 创建一个名为 branch 的分支 |
git add [file_name] | 暂存文件,准备提交至仓库 |
git commit | 将暂存的变更保存至仓库 |
git checkout [branch] | 切换到指定分支 |
git merge [branch] | 将 branch 中的提交并入当前分支 |
git branch –delete | 移除本地分支 |
git branch -D | 移除不包含并入其他分支的提交的本地分支 |
git clone [URL] | 下载一份远程仓库的副本 |
git log | 查看项目历史记录 |
git reflog | 查看分支的详细历史记录 |
git checkout [commit] | 切换到另一个本地分支 |
git cherry-pick [commit] | 将提交从一个分支复制到另一个分支 |
git reset –merge ORIG_HEAD | 移除当前分支中所有在最近一次合并中引入的提交 |
git checkout HEAD [file_name] | 还原已变更但尚未提交的文件 |
git reset HEAD [file_name] | 从暂存区移除提出的文件修改 |
git reset –hard HEAD | 将所有已变更的文件还原到之前保存的状态 |
git reset [commit] | 取消暂存在这个提交之前的所有提交中的变更 |
git rebase –interactive [commit] | 编辑,或压缩提交后的所有提交 |
git rebase –continue | 在解决合并冲突后,继续变基过程 |
git revert [commit] | 取消应用指定提交中的变更,创建一个共享友好的历史记录还原 |
git log –oneline –graph | 显示分支的图形化历史记录 |
git revert –mainline 1 [commit] | 反转一个合并提交 |
git branch –contains [commit] | 列出所有包含指定提交对象的分支 |
git revert –no-commit [last_commit_to_keep..newest_commit_to_reject] | 使用一个提交反转一组提交,而不是为每个撤销的提交都创建一个对象 |
git filter-branch | 从仓库中永久移除文件 |
git reflog expire | 忽略详细历史记录,仅使用存储的提交消息 |
git gc –prune=now | 运行垃圾回收器并确保所有未提交的变更从本地内存中移除 |