Git merge strategy

We have a project hosted on Github with a main development branch called “Master”.
Some developers tend to merge project branches into Master. And others tend to merge Master into project branches.

Seems to me that the former adheres standard protocol. The later just doesn’t make sense. Am I just being paranoid, or does it really make a difference?

  • Colon in a git file name. Windows developers alarm?
  • Is there any way to git checkout previous branch?
  • How to setup SSH keys for buildbot user
  • Git status upstream and downstream
  • git archive “The input line is too long. ” error in batch file
  • RStudio project and git repository in subdirectory
  • To compound things, the project branches are then being pushed back to github with the merged Master branch

    For those that merge Master into project, the argument is that they need to an up-to-date copy of Master. My answer; what does a merge have to do with it? Maybe to pick up changes that have been introduced by others and merged into master?

    Shouldn’t the process be:
    1) checkout master,
    2) git fetch or git pull

  • 2 errors produced by git push -u origin master
  • How do you delete files that are already uploaded into a repository?
  • Run git gc on multiple repositories
  • How do Git merges handle simultaneous commits?
  • rbt setup-repo returns with error
  • Find Git branch name in post-update hook
  • 4 Solutions collect form web for “Git merge strategy”

    It makes total sense for the developers to merge the master branch into their project branch every now and then to make sure that they are not doing things that will not work once merged. This usually happens in their local repository.

    Then, when they are done with the new feature, they merge it into master, and push, which will add that feature to the master branch of the public repository. Or they just push what’s in their feature branch to the master branch of the public repository.

    A git fetch is just a way to fetch a repository from some remote. It will never do a merge at all. A git pull will do the same thing, but also includes a merge.

    So the process that you are suggesting will at best only merge changes to the public master branch with the local master branch. The developer will then still need to merge their local (now up-to-date) master branch with their feature branch or they will not be able to perform the sanity checks mentioned above.

    In contrast to @richardolsson, I wouldn’t recommend that they merge master into their topic branches, if by merge we mean git merge master.

    It is definitely a good idea for them to take updates that have happened on master and update their topic branches to reflect those changes, so as to avoid everything breaking terribly, but git provides a bit of a better tool for this particular use case, git rebase.

    Conceptually, they are very similar and the outcome in terms of the codebase is often identical, however using rebase can make the history of the project much clearer to someone looking at the logs, and help keep from having a gigantic history graph to look through, even though those can look pretty sweet.

    When you merge, git takes the status of the two (or more) branches being merged, attempts to piece them together appropriately, and makes a commit reflecting that a merge has happened, unless the HEAD of the target branch is a direct descendant of the branch being merged in, in which case it doesn’t need to do any diff/patch stuff and just plays the commits on top of each other (git calls this fast-forwarding).

    When you rebase, git (conceptually) takes the target branch, goes back to the last commit that it has in common with the branch it’s being rebased on, makes the commits from that branch, and then makes the commits from the target branch. An example may be in order:

    You have two branches, master, with commits A, B, C and D and topic, which was branched at B and has the commits A, B, E, and F. If you are on topic and git merge master, you can end up with a commit history that will look like A B E F G where G is the commit made by merging. If you rebase, git first takes topic and makes it’s commit history the same as master, and then makes the commits in topic, so you get a commit history that looks like A B C D E F.

    One major advantage of doing this, other than the clarity in log history, is that as long as there haven’t been changes in master since you rebased, git checkout master && git merge topic or similar will always be a fast-forward, since all of master‘s history is contained in topic. The big caveat here is to not rebase branches that are meant to be publicly shared, because the SHA-1s of the commits have to be rewritten, which basically means a bunch of meaningless conflicts.

    It took me a while for the benefit of this to take hold in my head. I’ve since found that (for me at least, and so far…), the “best” workflow is to:

    • rebase topic branches
    • merge tracking branches

    Something like:

    git checkout topic
    git rebase master
    # fix any conflicts, run tests, etc
    git checkout master
    git merge topic

    This gives a very clear history, and pretty much ensures that if breakage happens, it happens on the topic branch. It also makes some of the tools like git bisect a bit easier to use when you need to use them.

    Anyhow, hope you found this way-too-long answer useful.

    The better workflow would be, that the developers rebase their feature/project branches on the master branch, to avoid cluttering the history.

    The first thing to realize is that branch names are technically only local to any given repository. The central version-2.0 might be my master and your testing. That being said, in practice, people usually use the same names as the repository they most often push to, so merging project into master then pushing master is the standard way.

    Merging master into project will produce this tree:

    master  A____B
    project  \__C_\_D

    Merging project into master will produce this tree:

    master  A____B___D
    project  \__C__/

    Note that both are essentially identical except for the branch names at D are reversed, along with the order of its parents. As long as you specify git push origin project:master if you do it the first way, then update master to point to D somehow before making another branch, you won’t notice a difference in practice. However, that’s creating extra mental effort for yourself, and you can screw things up if you don’t do it right every time. Merging project into master allows you to set up defaults for push that make it easy.

    Git Baby is a git and github fan, let's start git clone.