Git rebase详细解析




merge 和rebase什么关系

git rebase 和git merge 做的事其实是一样的。它们都被设计来将一个分支的更改并入另一个分支,只不过方式有些不同。

merge

命令示例

git checkout feature
git merge master

这样feature 分支中新的合并提交(merge commit)将两个分支的历史连在了一起

Merge 好在它是一个安全的操作。现有的分支不会被更改

每次合并上游更改时 feature 分支都会引入一个外来的合并提交。如果上游分支 非常活跃的话,这或多或少会污染你的分支历史

Rebase

命令示例

git checkout feature
git rebase master

它会把整个 feature 分支移动到 master 分支的后面,有效地把所有 master 分支上新的提交并入过来

但是,rebase 为原分支上每一个提交创建一个新的提交,重写了项目历史,并且不会带来合并提交。

rebase的优点和缺点

优点
- rebase最大的好处是你的项目历史会非常整洁
- rebase 导致最后的项目历史呈现出完美的线性——你可以从项目终点到起点浏览而不需要任何的 fork。这让你更容易使用 git log、git bisect 和 gitk 来查看项目历史

缺点
- 安全性,如果你违反了 rebase 黄金法则,重写项目历史可能会给你的协作工作流带来灾难性的影响
- 可跟踪性,rebase 不会有合并提交中附带的信息——你看不到 feature 分支中并入了上游的哪些更改

交互式的rebase

交互式的 rebase 允许你更改并入新分支的提交。这比自动的 rebase 更加强大,因为它提供了对分支上提交历史完整的控制

一般来说,这被用于将 feature 分支并入 master 分支之前,清理混乱的历史。

命令示例:

git checkout feature
git rebase -i master

它会打开一个文本编辑器,显示所有将被移动的提交:

pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3

在这里可以编辑提交的记录,具体可以怎么编辑先不详说,见下文

保存后关闭文件,Git 会根据你的指令来执行 rebase

忽略不重要的提交会让你的 feature 分支的历史更清晰易读。这是 git merge 做不到的

【声明:转载请注明出处
独立:http://wangnan.tech
简书:http://www.jianshu.com/u/244399b1d776
CSDN:http://blog.csdn.net/wangnan9279

rebase黄金法则

法则:

绝不要在公共的分支上使用它!

在你运行 git rebase 之前,一定要问问你自己「有没有别人正在这个分支上工作?」。如果答案是肯定的,那就不能rebase

强制推送

如果你想把 rebase 之后的 master 分支推送到远程仓库,Git 会阻止你这么做,因为两个分支包含冲突。但你可以传入 –force 标记来强行推送

git push --force

rebase在开发中的使用场景

rebase 可以或多或少应用在你们团队的 Git 工作流中

本地清理
隔一段时间执行一次交互式 rebase,你可以保证你 feature 分支中的每一个提交都是专注和有意义的。你在写代码时不用担心造成孤立的提交——因为你后面一定能修复

下面的命令对最新的 3 次提交进行了交互式 rebase:

git checkout feature
git rebase -i HEAD~3

你实际上没有移动分支——你只是将之后的 3 次提交合并了

交互式 rebase 是在你工作流中引入 git rebase 的的好办法,因为它只影响本地分支。其他开发者只能看到你已经完成的结果,那就是一个非常整洁、易于追踪的分支历史。

但同样的,这只能用在私有分支上。如果你在同一个 feature 分支和其他开发者合作的话,这个分支是公开的,你不能重写这个历史。

如何选择使用merge还是rebase

你使用 rebase 之前需要知道的知识点都在这了。如果你想要一个干净的、线性的提交历史,没有不必要的合并提交,你应该使用 git rebase 而不是 git merge 来并入其他分支上的更改。

另一方面,如果你想要保存项目完整的历史,并且避免重写公共分支上的 commit, 你可以使用 git merge。两种选项都很好用,但至少你现在多了 git rebase 这个选择。

具体说说交互式rebase的操作

例如开启交互式rebase合并最近三次提交

git checkout feature
git rebase -i HEAD~3

这是一个交互式rebase界面:

pick 07c5abd Introduce OpenPGP and teach basic usage
pick de9b1eb Fix PostChecker::Post#urls
pick 3e7ee36 Hey kids, stop all the highlighting
pick fa20af3 git interactive rebase, squash, amend

# Rebase 8db7e8b..fa20af3 onto 8db7e8b
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# 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.
#
# Note that empty commits are commented out

上面的互动界面,先列出当前分支最新的4个commit(越下面越新)。每个commit前面有一个操作命令,默认是pick,表示该行commit被选中,要进行rebase操作。4个commit的下面是一大堆注释,列出可以使用的命令。

* pick:正常选中
* reword:选中,并且修改提交信息;
* edit:选中,rebase时会暂停,允许你修改这个commit(参考这里)
* squash:选中,会将当前commit与上一个commit合并
* fixup:与squash相同,但不会保存当前commit的提交信息
* exec:执行其他shell命令

上面这6个命令当中,squash和fixup可以用来合并commit。先把需要合并的commit前面的动词,改成squash(或者s)

pick 07c5abd Introduce OpenPGP and teach basic usage
s de9b1eb Fix PostChecker::Post#urls
s 3e7ee36 Hey kids, stop all the highlighting
pick fa20af3 git interactive rebase, squash, amend

这样一改,执行后,当前分支只会剩下两个commit。第二行和第三行的commit,都会合并到第一行的commit。提交信息会同时包含,这三个commit的提交信息。

# This is a combination of 3 commits.
# The first commit's message is:
Introduce OpenPGP and teach basic usage

# This is the 2nd commit message:
Fix PostChecker::Post#urls
# This is the 3rd commit message:
Hey kids, stop all the highlighting

如果将第三行的squash命令改成fixup命令。

pick 07c5abd Introduce OpenPGP and teach basic usage
s de9b1eb Fix PostChecker::Post#urls
f 3e7ee36 Hey kids, stop all the highlighting
pick fa20af3 git interactive rebase, squash, amend

运行结果相同,还是会生成两个commit,第二行和第三行的commit,都合并到第一行的commit。但是,新的提交信息里面,第三行commit的提交信息,会被注释掉

# This is a combination of 3 commits.
# The first commit's message is:
Introduce OpenPGP and teach basic usage

# This is the 2nd commit message:
Fix PostChecker::Post#urls
# This is the 3rd commit message:
# Hey kids, stop all the highlighting

Pony Foo提出另外一种合并commit的简便方法,就是先撤销过去5个commit,然后再建一个新的。

$ git reset HEAD~5
$ git add .
$ git commit -am "Here's the bug fix that closes #28"
$ git push --force

squash和fixup命令,还可以当作命令行参数使用,自动合并commit。

$ git commit --fixup
$ git rebase -i --autosquash

推送到远程仓库
合并commit后,就可以推送当前分支到远程仓库了

$ git push --force origin myfeature

git push命令要加上force参数,因为rebase以后,分支历史改变了,跟远程分支不一定兼容,有可能要强行推送

提交到远程仓库以后,就可以发出 Pull Request 到master分支,然后请求别人进行代码review,确认可以合并到master。

(本文完)

整理自:
- https://github.com/geeeeeeeeek/git-recipes/wiki/5.1-%E4%BB%A3%E7%A0%81%E5%90%88%E5%B9%B6%EF%BC%9AMerge%E3%80%81Rebase-%E7%9A%84%E9%80%89%E6%8B%A9
- http://www.ruanyifeng.com/blog/2015/08/git-use-process.html
- http://fle.github.io/git-tip-keep-your-branch-clean-with-fixup-and-autosquash.html
- http://willi.am/blog/2014/08/12/the-dark-side-of-the-force-push/

### 回答1: Active Directory域服务是一种由微软公司开发的网络服务,它提供了一种集中管理和控制网络资源的方式。它可以在一个域中集中管理用户、计算机、应用程序和其他网络资源,从而提高了网络的安全性和可管理性。Active Directory域服务还提供了一些高级功能,如单点登录、组策略管理和域名系统(DNS)集成等,使得网络管理员可以更加轻松地管理和维护网络。 ### 回答2: Active Directory域服务(Active Directory Domain Services,简称AD DS)是微软公司的一项用于管理和组织网络资源的目录服务。它是一种基于LDAP(轻量级目录访问协议)的目录服务,可以让用户和管理员方便地管理和访问网络中的资源。 AD DS的主要功能包括用户身份认证、访问控制、组管理和资源管理等。通过AD DS,管理员可以集中管理和配置用户和计算机的访问权限,确保系统安全。同时,AD DS还提供了域的集中管理功能,管理员可以通过域控制器管理域中的所有对象,并在域中实施策略。 AD DS还支持单点登录功能,用户只需在登录到域之后,即可自动访问到所属域中的资源,而无需再次输入用户名和密码。这大大提高了用户的工作效率。 此外,AD DS还支持多域架构,可以通过建立信任关系实现跨域资源的访问和管理。管理员可以维护多个域之间的信任关系,实现用户和资源的统一管理。 总而言之,AD DS是一种强大的目录服务,可以实现用户和资源的集中管理和访问控制,提高网络系统的稳定性和安全性。它是企业网络管理的重要组成部分,为企业提供了高效的身份认证和资源管理功能,增强了企业的生产力和安全性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值