5. Git 进阶高频操作

简介: stash 储藏当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug--include-untracked 参数可以额外储藏新的未被追踪的文件。--all 选项将收集所有未跟踪的文件以及在 .gitignore 和 排除文件中明确忽略的文件。

stash 储藏



当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug

--include-untracked 参数可以额外储藏新的未被追踪的文件。


--all 选项将收集所有未跟踪的文件以及在 .gitignore 和 排除文件中明确忽略的文件。

# 更推荐对 stash 加一些注释
`git stash save 'message'` 
`git stash save --include-untracked 'message'` 
`git stash save --all -untracked 'message'`


Git 把 stash内容存在某个地方了(包含了工作区 和 暂存区的内容),但是需要恢复一下,有两个办法:


  • git stash apply恢复,但是恢复后,stash内容并不删除,你需要用 git stash drop来删除;


  • 另一种方式是 git stash pop,恢复的同时把 stash 内容 pop 出去.

按保存时间由近及远的顺序列举出储藏栈。


git stash list


恢复指定的stash, 只需要指定序号, stash@{0}代表最新的stash。依次是次新的数据,按照时间新到旧排序。

$ git stash apply stash@{0}


此时, 变更内容都还原到了工作区.


清空所有 stash 信息

$ git stash clear


要用其他更基础的 Git 命令来达到相同的效果,需要手动创建一个新分支,在新分

支上提交所有修改,之后回到之前的分支继续工作,最后把你保存的分支状态恢复到新的工作目录。如果还不清楚,下面将展示这样的过程。


有时,储藏你的变更会导致你的分支上出现一个全新的开发序列,并且在最终还原你的储藏状态到所有变更之前时可能没有直接意义。此外,合并冲突可能会导致弹出操作难以进行。然而,你可能仍需要恢复你储藏的内容。在这种情况下, git 提供了git stash branch 命令来帮助你。这条命令基于储藏条目生成时的提交,会将保存的储藏内容转换到一个新分支。


因此我们重置一些状态,采用一些不同的方法,创建一个名为 mod 的新分支来包含那些储藏的变更。

$ git stash branch mod
# 操作 mod 分支
...
# 切回 master 分支,并进行合并
 $ git checkout master
 Switched to branch 'master
 $ git merge mod


以下展示在没有 stash 命令之前怎么保存临时提交

# 常规开发试程中断
# 创建一个新分支来保存状态
 git checkout -b saved_state
 git commit -a -m "Saved state"
#回到之前的分支进行更新
 $ git checkout master
# 编辑紧急修复
 git commit -a-m "Fix something."
# 恢复保存的状态到工作目录
git checkout saved state
git reset -soft HEAD
#..继续之前我们离开时的工作


cherry-pick



git cherry-pick提交命令会在当前分支上应用给定提交引入的变更。这将引入一个新的独特的提交。严格来说,使用git cherry-pick并不改变版本库中的现有历史记录,而是添加历史记录。


跟其他通过应用 diff 来引入变更的Git操作一样,你可能需要解决冲突来完全应用给定提交的变更。


git cherry-pick 命令通常用于把版本库中一个分支的特定提交引入一个不同的分支中。


git cherry-pick <提交号1> <提交号2> <提交号3>


挑选多个提交合并, 提交之间用空格相隔


挑选区间, 左开右闭.其中,<start-commit>在时间上必须早于<end-commit>


git cherry-pick <start-commit>..<end-commit>

git cherry-pick <subcommand>
    --quit                end revert or cherry-pick sequence 结束pick操作,但是不会影响冲突之前多个提交中已经成功的
    --continue            resume revert or cherry-pick sequence  //继续下个操作
    --abort               cancel revert or cherry-pick sequence 直接打回原形
    -n, --no-commit       don't automatically commit 不自动提交
    -e, --edit            edit the commit message 编辑提交信息
    -s, --signoff         add Signed-off-by:
    -m, --mainline <parent-number>
                          select mainline parent
    --rerere-autoupdate   update the index with reused conflict resolution if possible
    --strategy <strategy>
                          merge strategy
    -X, --strategy-option <option>
                          option for merge strategy
    -S, --gpg-sign[=<key-id>]
                          GPG sign commit
    -x                    append commit name
    --ff                  allow fast-forward
    --allow-empty         preserve initially empty commits
    --allow-empty-message
                          allow commits with empty messages
    --keep-redundant-commits
                          keep redundant, empty commits


如果在git cherry-pick 后加一个分支名,则表示将该分支顶端提交进cherry-pick,如:git cherry-pick <branch name>


rebase 交互式



git rebase -i


如果你在命令后增加了这个选项, Git 会打开一个 UI 界面并列出将要被复制到目标分支的备选提交记录,它还会显示每个提交记录的哈希值和提交说明,提交说明有助于你理解这个提交进行了哪些更改。


此模式下你可以重新排序、编辑、删除,把多个提交合并成一个,把一个提交分离成多个, 然后把它们放回原来的分支或者不同的分支。


git rebase -i HEAD^ 区间范围为 [HEAD, HEAD]


git rebase -i HEAD~2 区间范围为 (HEAD~2, HEAD] ,为左开右闭区间。


git rebase -i HEAD~3 区间范围为 (HEAD~3, HEAD]

git rebase -i HEAD~3
pick ba16ab5 1
pick 4e71e75 aiya
pick cc4b570 someMessage
# Rebase c277d53..cc4b570 onto c277d53 (3 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


其中 s, squash 将会所在行所在的提交合并到前一个提交中


一般为方便确认 rebase 的返回,通常和 git show-branch --more=nums [branchName] 搭配使用。


分支开发策略



在实际开发中,我们应该按照几个基本原则进行分支管理:


首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;


那在哪干活呢?干活都在 dev 分支上,也就是说,dev 分支是不稳定的,到某个时候,比如 1.0 版本发布时,再把 dev 分支合并到 master上,在 master 分支发布1.0版本;

你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往 dev 分支上合并就可以了。


image.png


选择分支的衍合 or 合并


衍合的风险


呃,奇妙的衍合也并非完美无缺,要用它得遵守一条准则:


一旦分支中的提交对象发布到公共仓库,就千万不要对该分支进行衍合操作。


如果把衍合当成一种在推送之前清理提交历史的手段,而且仅仅衍合那些尚未公开的提交对象,就没问题。如果衍合那些已经公开的提交对象,并且已经有人基于这些提交对象开展了后续开发工作的话,就会出现叫人沮丧的麻烦。




目录
相关文章
|
5月前
|
开发工具 git
记IDEA Git版本回退并push到远程操作
记IDEA Git版本回退并push到远程操作
121 1
记IDEA Git版本回退并push到远程操作
|
5月前
|
人工智能 数据可视化 开发工具
Git log 进阶用法(含格式化、以及数据过滤)
Git log 进阶用法(含格式化、以及数据过滤)
|
5月前
|
开发工具 git 开发者
|
5月前
|
开发工具 git
web后端-IDEA的Git操作
web后端-IDEA的Git操作
|
5月前
|
Linux 网络安全 开发工具
Git拉取代码的完整示例操作
Git拉取代码的完整示例操作
184 0
|
3月前
|
Ubuntu 开发工具 git
git 超实用教程【人人必会!】(含大厂的 git 操作规范)
git 超实用教程【人人必会!】(含大厂的 git 操作规范)
50 0
|
4月前
|
开发工具 git
idea的git reset current branch to here操作详解
idea的git reset current branch to here操作详解
296 1
|
5月前
|
开发工具 git 开发者
【专栏】探讨了 Git 中的 `git rebase` 操作,它用于重新应用提交到另一分支,改变历史顺序
【4月更文挑战第29天】本文探讨了 Git 中的 `git rebase` 操作,它用于重新应用提交到另一分支,改变历史顺序。与 `git merge` 不同,rebase 重写提交历史,提供简洁线性的历史记录。文章介绍了 rebase 的基本操作、应用场景,如整理提交历史、解决冲突和整合分支,并强调了使用注意事项,如避免在公共分支上操作。尽管 rebase 可以带来整洁的历史和冲突解决便利,但其潜在的风险和可能导致的历史混乱需谨慎对待。理解并恰当使用 `git rebase` 可以提升开发效率和代码质量。
173 1
|
5月前
|
开发工具 git 开发者
掌握常见Git操作:技巧与实践
掌握常见Git操作:技巧与实践