我知道有些人默认使用git pull -rebase,而另一些人坚持从不使用它。我相信我理解合并和重基之间的区别,但我试图把它放在git pull的上下文中。只是不想看到大量的合并提交消息,还是还有其他问题?
当前回答
我想提供一个不同的角度来解释git pull -rebase的实际含义,因为它似乎有时会丢失。
如果您曾经使用过Subversion(或CVS),那么您可能已经习惯了svn update的行为。如果要提交更改,并且由于上游已经进行了更改而导致提交失败,则svn update。Subversion通过将上游更改与您的更改合并进行,这可能会导致冲突。
Subversion刚刚做的,本质上是git pull -rebase。将您的局部更改重新定义为相对于新版本的行为是“重基”的一部分。如果您在失败的提交尝试之前执行了svn diff,并将结果diff与之后的svn diff输出进行比较,那么这两个diff之间的差异就是重基操作所做的。
在这种情况下,Git和Subversion之间的主要区别是,在Subversion中,“您的”更改仅作为未提交的更改存在于您的工作副本中,而在Git中,您有实际的本地提交。换句话说,在Git中,你已经分叉了历史;你们的历史和上游的历史有分歧,但你们有共同的祖先。
In my opinion, in the normal case of having your local branch simply reflecting the upstream branch and doing continuous development on it, the right thing to do is always --rebase, because that is what you are semantically actually doing. You and others are hacking away at the intended linear history of a branch. The fact that someone else happened to push slightly prior to your attempted push is irrelevant, and it seems counter-productive for each such accident of timing to result in merges in the history.
在我看来,如果出于某种原因,您确实觉得有必要将某些东西作为一个分支,那就另当别论了。但是,除非您有一个特定的和积极的愿望,以合并的形式表示您的更改,在我看来,默认的行为应该是git pull -rebase。
请考虑其他需要观察和理解项目历史的人。您是希望历史上到处都是数百个合并,还是希望只选择代表有意的不同开发工作的真正合并的少数合并?
其他回答
如何使用git拉
git pull: Update your local working branch with commits from the remote, and update all remote tracking branches. git pull --rebase: Update your local working branch with commits from the remote, but rewrite history so any local commits occur after all new commits coming from the remote, avoiding a merge commit. git pull --force: This option allows you to force a fetch of a specific remote tracking branch when using the option that would otherwise not be fetched due to conflicts. To force Git to overwrite your current branch to match the remote tracking branch, read below about using git reset. git pull --all: Fetch all remotes - this is handy if you are working on a fork or in another use case with multiple remotes.
我认为这可以归结为个人喜好。
您想要在推动更改之前隐藏您的愚蠢错误吗?如果是这样,git拉-rebase是完美的。它允许您稍后将提交压缩为几个(或一个)提交。如果你在你的(未推送的)历史中有合并,那么以后做git rebase就不那么容易了。
我个人并不介意公布我所有的愚蠢错误,所以我倾向于合并而不是重新建立数据库。
我想提供一个不同的角度来解释git pull -rebase的实际含义,因为它似乎有时会丢失。
如果您曾经使用过Subversion(或CVS),那么您可能已经习惯了svn update的行为。如果要提交更改,并且由于上游已经进行了更改而导致提交失败,则svn update。Subversion通过将上游更改与您的更改合并进行,这可能会导致冲突。
Subversion刚刚做的,本质上是git pull -rebase。将您的局部更改重新定义为相对于新版本的行为是“重基”的一部分。如果您在失败的提交尝试之前执行了svn diff,并将结果diff与之后的svn diff输出进行比较,那么这两个diff之间的差异就是重基操作所做的。
在这种情况下,Git和Subversion之间的主要区别是,在Subversion中,“您的”更改仅作为未提交的更改存在于您的工作副本中,而在Git中,您有实际的本地提交。换句话说,在Git中,你已经分叉了历史;你们的历史和上游的历史有分歧,但你们有共同的祖先。
In my opinion, in the normal case of having your local branch simply reflecting the upstream branch and doing continuous development on it, the right thing to do is always --rebase, because that is what you are semantically actually doing. You and others are hacking away at the intended linear history of a branch. The fact that someone else happened to push slightly prior to your attempted push is irrelevant, and it seems counter-productive for each such accident of timing to result in merges in the history.
在我看来,如果出于某种原因,您确实觉得有必要将某些东西作为一个分支,那就另当别论了。但是,除非您有一个特定的和积极的愿望,以合并的形式表示您的更改,在我看来,默认的行为应该是git pull -rebase。
请考虑其他需要观察和理解项目历史的人。您是希望历史上到处都是数百个合并,还是希望只选择代表有意的不同开发工作的真正合并的少数合并?
我认为你应该使用git pull -rebase与他人在同一分支上合作。你处于你的工作→提交→工作→提交循环中,当你决定推送你的工作时,你的推送被拒绝了,因为在同一个分支上有并行的工作。在这一点上,我总是做一个拉-rebase。我不使用squash(扁平提交),但我使用rebase来避免额外的合并提交。
随着Git知识的增长,你会发现自己比使用过的其他版本控制系统更多地关注历史。如果您有大量的小型合并提交,很容易失去对历史中正在发生的大局的关注。
这实际上是我唯一一次执行rebase(*),其余的工作流程都是基于合并的。但只要你最频繁的提交者这样做,历史最终看起来会更好。
(*) 在教授Git课程时,我有一个学生因为这个问题逮捕了我,因为我也主张在某些情况下重新定义功能分支。他读到了这个答案;)这种调整基数也是可能的,但它总是必须根据预先安排/商定的制度,因此不应该“总是”适用。在那个时候,我通常也不做拉-rebase,这就是问题所在;)
一个实践案例是当你与Bitbucket PR合作时。 让我们用下面的例子来理解它:
这里有公共关系部门。
然后你决定通过BitBucket GUI用最新的Master分支重新构建PR远程分支。这个操作将改变你的PR的提交id。
因为您已经使用GUI重新创建了远程分支。首先,你必须同步你电脑上的本地分支和远程分支。
在这种情况下,git pull -rebase就像魔法一样有效。
在git pull -rebase之后,你的本地分支和远程分支具有相同的历史和相同的提交id。
那么现在,如果您向PR分支添加一个新的提交/更改。
你可以很好地推送一个新的提交,而不需要使用强制或任何东西到远程分支/BitBucket PR。
推荐文章
- 为什么我需要显式地推一个新分支?
- 如何撤消最后的git添加?
- Rubymine:如何让Git忽略Rubymine创建的.idea文件
- Gitignore二进制文件,没有扩展名
- Git隐藏错误:Git隐藏弹出并最终与合并冲突
- 了解Git和GitHub的基础知识
- 没有。Git目录的Git克隆
- Git与Mercurial仓库的互操作性
- 忽略git中修改(但未提交)的文件?
- “git restore”命令是什么?“git restore”和“git reset”之间有什么区别?
- Git合并与强制覆盖
- Git拉另一个分支
- 在Bash命令提示符上添加git分支
- 如何更改Git日志日期格式
- git pull -rebase和git pull -ff-only之间的区别