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
相關文章
相關標籤/搜索