Git工做流程和rebase与合并问题 - Git workflow and rebase vs merge questions

问题:

I've been using Git now for a couple of months on a project with one other developer. 我和其余开发人员一块儿在一个项目上使用Git几个月了。 I have several years of experience with SVN , so I guess I bring a lot of baggage to the relationship. 我有几年的SVN经验,因此我想我给这段关系带来了不少包袱。 git

I have heard that Git is excellent for branching and merging, and so far, I just don't see it. 我据说Git很是适合分支和合并,到目前为止,我只是没有看到它。 Sure, branching is dead simple, but when I try to merge, everything goes all to hell. 固然,分支很简单,可是当我尝试合并时,一切都变得很糟糕。 Now, I'm used to that from SVN, but it seems to me that I just traded one sub-par versioning system for another. 如今,我已经习惯了SVN,但在我看来,我只是将一个低于标准的版本系统换成了另外一个。 编程

My partner tells me that my problems stem from my desire to merge willy-nilly, and that I should be using rebase instead of merge in many situations. 个人搭档告诉我,个人问题源于我不顾一切地合并,而且我应该在不少状况下使用rebase而不是合并。 For example, here's the workflow that he's laid down: 例如,这是他所规定的工做流程: 服务器

clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature
git checkout master
git merge my_new_feature

Essentially, create a feature branch, ALWAYS rebase from master to the branch, and merge from the branch back to master. 基本上,建立一个功能分支,始终从主分支到分支,并从分支合并回主分支。 Important to note is that the branch always stays local. 须要注意的重要一点是,分支始终保持在本地。 app

Here is the workflow that I started with 这是我开始的工做流程 ide

clone remote repository
create my_new_feature branch on remote repository
git checkout -b --track my_new_feature origin/my_new_feature
..work, commit, push to origin/my_new_feature
git merge master (to get some changes that my partner added)
..work, commit, push to origin/my_new_feature
git merge master
..finish my_new_feature, push to origin/my_new_feature
git checkout master
git merge my_new_feature
delete remote branch
delete local branch

There are two essential differences (I think): I use merge always instead of rebasing, and I push my feature branch (and my feature branch commits) to the remote repository. 有两个本质区别(我认为):我老是使用merge而不是rebase,我将个人功能分支(和个人功能分支提交)推送到远程存储库。 this

My reasoning for the remote branch is that I want my work backed up as I'm working. 我对远程分支的理由是,我但愿在我工做时备份个人工做。 Our repository is automatically backed up and can be restored if something goes wrong. 咱们的存储库会自动备份,若是出现问题能够恢复。 My laptop is not, or not as thoroughly. 个人笔记本电脑没有,或没有完全。 Therefore, I hate to have code on my laptop that's not mirrored somewhere else. 所以,我讨厌个人笔记本电脑上没有镜像的代码。 atom

My reasoning for the merge instead of rebase is that merge seems to be standard and rebase seems to be an advanced feature. 我合并而不是rebase的缘由是合并彷佛是标准的,而rebase彷佛是一个高级功能。 My gut feeling is that what I'm trying to do is not an advanced setup, so rebase should be unnecessary. 个人直觉是,我正在尝试作的不是高级设置,因此不该该使用rebase。 I've even perused the new Pragmatic Programming book on Git, and they cover merge extensively and barely mention rebase. 我甚至在Git上阅读了新的实用编程书,它们涵盖了普遍的合并,几乎没有提到rebase。 idea

Anyway, I was following my workflow on a recent branch, and when I tried to merge it back to master, it all went to hell. 不管如何,我在最近的一个分支上关注个人工做流程,当我试图将它合并回主人时,一切都进入了地狱。 There were tons of conflicts with things that should have not mattered. 对于应该不重要的事情存在大量冲突。 The conflicts just made no sense to me. 冲突对我来讲毫无心义。 It took me a day to sort everything out, and eventually culminated in a forced push to the remote master, since my local master has all conflicts resolved, but the remote one still wasn't happy. 我花了一天的时间来解决全部事情,并最终被强制推向远程主人,由于个人当地主人解决了全部冲突,可是远程主人仍然不高兴。 spa

What is the "correct" workflow for something like this? 这样的事情的“正确”工做流程是什么? Git is supposed to make branching and merging super-easy, and I'm just not seeing it. Git应该让分支和合并超级简单,我只是没有看到它。 .net

Update 2011-04-15 更新2011-04-15

This seems to be a very popular question, so I thought I'd update with my two years experience since I first asked. 这彷佛是一个很是受欢迎的问题,因此我认为自从我第一次提出问题以来,我会用本身两年的经验进行更新。

It turns out that the original workflow is correct, at least in our case. 事实证实,原始工做流程是正确的,至少在咱们的状况下。 In other words, this is what we do and it works: 换句话说,这就是咱们所作的,它的工做原理:

clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge my_new_feature

In fact, our workflow is a little different, as we tend to do squash merges instead of raw merges. 事实上,咱们的工做流程略有不一样,由于咱们倾向于进行压缩合并而不是原始合并。 ( Note: This is controversial, see below. ) This allows us to turn our entire feature branch into a single commit on master. 注意:这是有争议的,见下文。 )这容许咱们将整个功能分支转换为主服务器上的单个提交。 Then we delete our feature branch. 而后咱们删除咱们的功能分支。 This allows us to logically structure our commits on master, even if they're a little messy on our branches. 这容许咱们在master上逻辑地构造咱们的提交,即便它们在咱们的分支上有点乱。 So, this is what we do: 因此,这就是咱们所作的:

clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge --squash my_new_feature
git commit -m "added my_new_feature"
git branch -D my_new_feature

Squash Merge Controversy - As several commenters have pointed out, the squash merge will throw away all history on your feature branch. 壁球合并争议 - 正如几位评论者所指出的那样,壁球合并将抛弃你的特征分支上的全部历史。 As the name implies, it squashes all the commits down into a single one. 顾名思义,它将全部提交压缩成一个提交。 For small features, this makes sense as it condenses it down into a single package. 对于小功能,这有意义,由于它将其压缩到单个包中。 For larger features, it's probably not a great idea, especially if your individual commits are already atomic. 对于更大的功能,它可能不是一个好主意,特别是若是您的我的提交已是原子的。 It really comes down to personal preference. 这真的取决于我的喜爱。

Github and Bitbucket (others?) Pull Requests - In case you're wondering how merge/rebase relates to Pull Requests, I recommend following all the above steps up until you're ready to merge back to master. Github和Bitbucket(其余人?)Pull Requests - 若是您想知道merge / rebase如何与Pull Requests相关,我建议您按照上述全部步骤进行操做,直到您准备好合并回master。 Instead of manually merging with git, you just accept the PR. 您只需接受PR,而不是手动与git合并。 Note that this will not do a squash merge (at least not by default), but non-squash, non-fast-forward is the accepted merge convention in the Pull Request community (as far as I know). 请注意,这不会进行压缩合并(至少不会默认),但非压缩,非快进是Pull Request社区中可接受的合并约定(据我所知)。 Specifically, it works like this: 具体来讲,它的工做原理以下:

clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git push # May need to force push
...submit PR, wait for a review, make any changes requested for the PR
git rebase master
git push # Will probably need to force push (-f), due to previous rebases from master
...accept the PR, most likely also deleting the feature branch in the process
git checkout master
git branch -d my_new_feature
git remote prune origin

I've come to love Git and never want to go back to SVN. 我来爱Git,从不想回到SVN。 If you're struggling, just stick with it and eventually you'll see the light at the end of the tunnel. 若是你正在努力,只要坚持下去,最终你会看到隧道尽头的光线。


解决方案:

参考一: https://stackoom.com/question/1v7v/Git工做流程和rebase与合并问题
参考二: https://oldbug.net/q/1v7v/Git-workflow-and-rebase-vs-merge-questions
相关文章
相关标签/搜索