Git workflow and rebase vs merge questions

后端 未结 11 2224
春和景丽
春和景丽 2020-11-22 03:09

I\'ve been using Git now for a couple of months on a project with one other developer. I have several years of experience with SVN, so I guess I bring a lot of baggage to th

相关标签:
11条回答
  • 2020-11-22 03:47

    With Git there is no “correct” workflow. Use whatever floats your boat. However, if you constantly get conflicts when merging branches maybe you should coordinate your efforts better with your fellow developer(s)? Sounds like the two of you keep editing the same files. Also, watch out for whitespace and subversion keywords (i.e., “$Id$” and others).

    0 讨论(0)
  • 2020-11-22 03:50

    From what I have observed, git merge tends to keep the branches separate even after merging, whereas rebase then merge combines it into one single branch. The latter comes out much cleaner, whereas in the former, it would be easier to find out which commits belong to which branch even after merging.

    0 讨论(0)
  • 2020-11-22 03:53

    "Conflicts" mean "parallel evolutions of a same content". So if it goes "all to hell" during a merge, it means you have massive evolutions on the same set of files.

    The reason why a rebase is then better than a merge is that:

    • you rewrite your local commit history with the one of the master (and then reapply your work, resolving any conflict then)
    • the final merge will certainly be a "fast forward" one, because it will have all the commit history of the master, plus only your changes to reapply.

    I confirm that the correct workflow in that case (evolutions on common set of files) is rebase first, then merge.

    However, that means that, if you push your local branch (for backup reason), that branch should not be pulled (or at least used) by anyone else (since the commit history will be rewritten by the successive rebase).


    On that topic (rebase then merge workflow), barraponto mentions in the comments two interesting posts, both from randyfay.com:

    • A Rebase Workflow for Git: reminds us to fetch first, rebase:

    Using this technique, your work always goes on top of the public branch like a patch that is up-to-date with current HEAD.

    (a similar technique exists for bazaar)

    • Avoiding Git Disasters: A Gory Story: about the dangers of git push --force (instead of a git pull --rebase for instance)
    0 讨论(0)
  • 2020-11-22 03:55

    I only use rebase workflow, because it is visually clearer(not only in GitKraken, but also in Intellij and in gitk, but I recommend the first one most): you have a branch, it originates from the master, and it goes back to master. When the diagram is clean and beautiful, you will know that nothing goes to hell, ever.

    My workflow is almost the same from yours, but with only one small difference: I squash commits into one in my local branch before rebase my branch onto the latest changes on master, because:

    rebase works on basis of each commit

    which means, if you have 15 commits changing the same line as master does, you have to check 15 times if you don't squash, but what matters is the final result, right?

    So, the whole workflow is:

    1. Checkout to master and pull to ensure that you have the latest version

    2. From there, create a new branch

    3. Do your work there, you can freely commit several times, and push to remote, no worries, because it is your branch.

    4. If someone tells you, "hey, my PR/MR is approved, now it is merged to master", you can fetch them/pull them. You can do it anytime, or in step 6.

    5. After doing all your work, commit them, and if you have several commits, squash them(they are all your work, and how many times you change a line of code does not matter; the only important thing is the final version). Push it or not, it doesn't matter.

    6. Checkout to master, pull again to ensure you have the latest master in local. Your diagram should be similar to this:

    As you can see, you are on your local branch, which originates from an outdated status on master, while master(both local and remote) has moved forward with changes of your colleague.

    1. Checkout back to your branch, and rebase to master. You will now have one commit only, so you solve the conflicts only once.(And in GitKraken, you only have to drag your branch on to master and choose "Rebase"; another reason why I like it.) After that, you will be like:

    1. So now, you have all the changes on the latest master, combined with changes on your branch. You can now push to your remote, and, if you have pushed before, you will have to force push; Git will tell you that you cannot simply fast forward. That's normal, because of the rebase, you have changed the start point of your branch. But you should not fear: wisely use the force, but without fear. In the end, the remote is also your branch so you do not affect master even if you do something wrong.

    2. Create PR/MR and wait until it is approved, so master will have your contribution. Congrats! So you can now checkout to master, pull your changes, and delete your local branch in order to clean up the diagram. The remote branch should be deleted too, if this is not done when you merge it into master.

    The final diagram is clean and clear again:

    0 讨论(0)
  • 2020-11-22 03:56

    In my workflow, I rebase as much as possible (and I try to do it often. Not letting the discrepancies accumulate drastically reduces the amount and the severity of collisions between branches).

    However, even in a mostly rebase-based workflow, there is a place for merges.

    Recall that merge actually creates a node that has two parents. Now consider the following situation: I have two independent feature brances A and B, and now want to develop stuff on feature branch C which depends on both A and B, while A and B are getting reviewed.

    What I do then, is the following:

    1. Create (and checkout) branch C on top of A.
    2. Merge it with B

    Now branch C includes changes from both A and B, and I can continue developing on it. If I do any change to A, then I reconstruct the graph of branches in the following way:

    1. create branch T on the new top of A
    2. merge T with B
    3. rebase C onto T
    4. delete branch T

    This way I can actually maintain arbitrary graphs of branches, but doing something more complex than the situation described above is already too complex, given that there is no automatic tool to do the rebasing when the parent changes.

    0 讨论(0)
  • 2020-11-22 03:59

    I have one question after reading your explanation: Could it be that you never did a

    git checkout master
    git pull origin
    git checkout my_new_feature
    

    before doing the 'git rebase/merge master' in your feature branch?

    Because your master branch won't update automatically from your friend's repository. You have to do that with the git pull origin. I.e. maybe you would always rebase from a never-changing local master branch? And then come push time, you are pushing in a repository which has (local) commits you never saw and thus the push fails.

    0 讨论(0)
提交回复
热议问题