问题:
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经验,所以我想我给这段关系带来了很多包袱。
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. 需要注意的重要一点是,分支始终保持在本地。
Here is the workflow that I started with 这是我开始的工作流程
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,我将我的功能分支(和我的功能分支提交)推送到远程存储库。
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. 因此,我讨厌我的笔记本电脑上没有镜像的代码。
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。
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. 我花了一天的时间来解决所有事情,并最终被强制推向远程主人,因为我的当地主人解决了所有冲突,但是远程主人仍然不高兴。
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应该让分支和合并超级简单,我只是没有看到它。
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
来源:oschina
链接:https://my.oschina.net/u/4428122/blog/4317426