重学Git(一)
一、最最最基础操作
# 初始化仓库
git init
# 添加文件到暂存区
git add readme.md
# 提交
git commit -m 'wrote a readme file'
二、简单的时空穿梭
1. 文件修改后,查看状态
修改 readme.md 文件,查看状态
git status
命令告知,已经对文件修改但仍未提交暂存区,下一步运用 git diff readme.md
对文件状态进行比较,比较结果显示新的文件比旧的文件新增两行
git add readme.md
后,提示文件已提交暂存区,下一步需要 commit
提交后再次查看 status
2. 查看过去
再次修改并提交,用 git log
命令查看版本
对于 git log
命令,可以添加参数从而更加清晰展示
如 git log --oneline --graph
此外也可以在 git gui 中更加清晰查看版本变动
3. 回到过去
git 中,运用 Head 代表当前版本,用 Head^ 代表上一个版本,用 Head^^ 代表上上个版本,如果回退过多,如要回退上一百个版本,则可使用 Head-100
回退版本后查看,发现只剩下了两个版本
此时发现已找不到第三个版本的 commit id,如果此时恰好也没有其他历史记录获取 commit id,可以通过命令 git reflog
获取完整的记录
找到 commit id 后再次回到第三个版本
三、工作区、暂存区与版本库
1. git diff
差异比较
# 1. 比较工作区与暂存区
# 当工作区有改动,暂存区为空,比较工作区与最后一次commit的共同文件
# 当工作区有改动,暂存区不为空,比较工作区与暂存区的共同文件
git diff
# 2. 比较工作区与HEAD
git diff HEAD --filename
# 3. 比较暂存区与HEAD
# 比较的是所有不同文件的增删改
git diff --cached
git diff --staged
# 4. 比较两个不同版本
git diff 211ba2 2948ac2 --filename
2. 撤销工作区的修改
如果需要撤销工作区的修改,将工作区文件还原成暂存区的状态,运用 git checkout -- file
命令,可以还原修改文件到与暂存区相同的状态。
如果不但修改了工作区,并且已进行 add 到暂存区的操作,则可运用 git reset HEAD <file>
将暂存区修改撤销掉
还原后则撤销了该文件的 add,此时可再用 git checkout -- file
命令,还原工作区该文件的更改。
3. 删除文件
# 删除工作区的文件
rm filename
# 删除工作区与暂存区的文件,可以运用-r进行递归删除
git rm filename
# 只将文件存暂存区删除
git rm --cached filename
三、git 分支管理
通过创建新分支,可以在团队开发中在自己的分支中进行开发,而不影响其他的分支,在开发完成后可以将自己的分支一次性合并到原有的分支上,不会影响团队其他人的工作。
1. 分支创建
# 创建并切换分支到“dev”
git checkout -b dev
# 相当于如下两条命令的合并
git branch dev # 创建分支
git checkout dev # 切换分支
# 查看目前所处分支
git branch
# switch命令也可以创建新的分支
git switch -c dev
操作创建 dev 分支,并切换;在 dev 分支对 readme 文件进行操作,新增一行并提交;重新切换回 master 分支,发现 readme 文件并无刚刚更新的内容
运用 git merge 命令,将刚刚在 dev 的更改合并到 master
再次查看 readme 文件,发现更新已合并。
2. 冲突
如果同时对 master 分支和 dev 分支新增一行并提交,在合并时会产生冲突,无法 automerge:
解决冲突详见“5. 冲突处理”
3. 删除分支
在完成某一部分的开发后,如果此分支之后不会再使用,则可对该分支进行删除。此时,如果已完成 merge 操作的分支可以直接删除,如果分支没有完成 merge 操作,则会进行提示:
4. 切换分支的正确姿势
切换分支可以使用 git checkout <branch>
,而 git checkout
这一命令同样也可用于恢复工作树。
git checkout 的用法****总结
检出指定文件
从暂存区检出某一文件;如果暂存区为空,这该文件回滚到最近一次提交状态,该命令常用于对某一文件修改的撤销(上文提到);如果添加 commit id 则回从某一次特定提交中检出某一文件。git checkout [commit id] [--] <paths>
创建并切换分支
如上文提到用法,如果-b 更改为-B,则会强制创建并覆盖分区git checkout -b <new_branch_name>
新建一个无 log 历史的分区
如果当前分支经多次提交,log 历史过长,则可创建一个无 log 历史的新分支,但分支内容齐全git checkout --orphan <new_branch_name>
切换分支时将修改内容打包合并
在切换分支时可以利用该命令,将修改内容打包合并,同步到切换的分支git checkout --merge <branch_name>
- 容易造成冲突
- 造成修改内容丢失
分支差异比较
比较两个分支之间的差异,并提供交互界面进行操作git checkout -p <branch_name>
因此,更加推荐使用 git switch
命令切换分支,避免命令混淆。
5. 冲突处理
如果分支某一个文件内容存在冲突,在合并分支时无法直接合并,这时可以用编辑器打开合并冲突产生的文件,根据提示增删需要的内容,再次 add-commit 提交,处理冲突
运用 git log 命令查看分支合并情况
6. 强制禁用 Fast Forward
禁用 Fast Forward 模式进行分支合并,会在合并时新增一个 commit
7. 紧急任务下 stash 当前工作区
如果在开发过程中,需要处理紧急任务,当前分支只进行了一半,还没有办法提交,此时可以运用 git stash
命令,将当前工作区暂存。当完成紧急任务后,运用 git stash pop
命令就可还原到之前进行了一半的工作区
在实际运用中,可以如同 commit 命令一样,给 stash 添加 message,便于区分
如果想多次运用 stash,而不删除,则可用 apply 命令代替 pop
8. Bug 修复后直接运用
如果 master 分支上存在的一个 Bug 得到了修复,而 dev 分支是由 master 分支 Bug 修复前的版本创建的,为了避免重复操作,我们可以通过 git cherry-pick
命令,将一个特定的提交复制到当前分支。
如修复 Bug 的提交版本为 e2d9109,则在 testbranch 分支上运用上述命令,则复制了 Bug 修改的提交到 testbranch 分支
9. Feature 分支
在开发中,会有不断的新功能增加,这其中不乏有很多是实验性质的,为了不与主分支混淆,最好每新增一个新功能,就添加一个 feature 分支;在开发完毕后,与主分支进行合并,并删除该 feature 分支。
如果该实验功能废弃,则可使用 git branch -D <feature_branch_name>
强制删除该 feature 分支。
四、标签管理
为了更加清晰地区分每一次 commit,通常会对 commit 打标签。
默认情况下,使用 git tag <tagname>
是对头指针对应的分支打标,也可指定某个 commit id 进行打标。
使用 git tag 查看所有打过的标签:
曾经对 commit 打过的标签也会显示在 git log 中
也可使用 git tag -a <tagname> -m <tagcommit> [<commit id>]
的形式,对某一个 tag 新增说明,使用 git show <tagname>
则可看到对某一个 tag 增加的说明文字:
如果标签打错,可以进行删除操作